Merge branch 'develop' of https://github.com/friendica/friendica into develop
This commit is contained in:
commit
7886de5c39
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -42,3 +42,9 @@ nbproject
|
|||
|
||||
#ignore local folder
|
||||
/local/
|
||||
|
||||
#ignore config files from Visual Studio
|
||||
/.vs/
|
||||
/php_friendica.phpproj
|
||||
/php_friendica.sln
|
||||
/php_friendica.phpproj.user
|
||||
|
|
|
@ -4,7 +4,14 @@ AddType audio/ogg .oga
|
|||
#AddHandler php53-cgi .php
|
||||
|
||||
<FilesMatch "\.(out|log)$">
|
||||
<IfModule authz_host_module>
|
||||
#Apache 2.4
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !authz_host_module>
|
||||
#Apache 2.2
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
|
|
60
CHANGELOG
60
CHANGELOG
|
@ -1,3 +1,63 @@
|
|||
Version 3.5
|
||||
Friendica Core:
|
||||
NEW Optional local directory with possible federated contacts [heluecht]
|
||||
NEW Autocompletion for @-mentions and BBCode tags [rabuzarus]
|
||||
NEW Added a composer derived autoloader which allows composer autoloaders in addons/libraries [fabrixxm]
|
||||
NEW theme: frio [rabuzarus, heluecht, fabrixxm]
|
||||
Enhance .htaccess file (nerdoc, dissolve)
|
||||
Updates to the translations (DE, ES, IS, IT, RU) [translation teams]
|
||||
Updates to the documentation [tobiasd, heluecht, mexcon, silke, rabuzarus, fabrixxm, Olivier Mehani, gerhard6380, ben utzer]
|
||||
Extended the BBCode by [abstract] tag used for bridged postings to networks with limited character length [heluecht]
|
||||
Code cleanup [heluecht, QuixOr]
|
||||
Improvements to the API and Friendica specific extensions [heluecht, fabrixxm, gerhard6380]
|
||||
Improvements to the RSS/Atom feed import [mexcon]
|
||||
Improvements to the communication with federated networks (Diaspora, Hubzilla, OStatus) [heluecht]
|
||||
Improvements on the themes (quattro, vier, frost) [rabuzarus, fabrixxm, stieben, heluecht, Quix0r, tobiasd]
|
||||
Improvements to the ACL dialog [fabrixxm, rabuzarus]
|
||||
Improvements to the database structure and optimization of queries [heluecht]
|
||||
Improvements to the UI (contacts, hotkeys, remember me, ARIA, code hightlighting) [rabuzarus, heluecht, tobiasd]
|
||||
Improvements to the background process (poller, worker) [heluecht]
|
||||
Improvements to the admin panel [tobiasd, heluecht, fabrixxm]
|
||||
Improvements to the performance [heluecht]
|
||||
Improvements to the installation wizzard (language selection, RINO version, check required PHP modules, default theme is now vier) [tobiasd]
|
||||
Improvements to the relocation of nodes and accounts [heluecht]
|
||||
Improvements to the DDoS detection [heluecht]
|
||||
Improvements to the calendar/events module [heluecht, rabuzarus]
|
||||
Improvements to OpenID login [strk]
|
||||
Improvements to the ShaShape font [andi]
|
||||
Reworked the implementation of the DFRN, Diaspora protocols [heluecht]
|
||||
Reworked the notifications code [fabrixxm, rabuzarus, heluecht]
|
||||
Reworked the p/config code [fabrixxm, rabuzarus]
|
||||
Reworked XML generation [heluecht]
|
||||
Removed now unused simplepie from library [heluecht]
|
||||
|
||||
Friendica Addons
|
||||
Updated to the translations (DE, ES, IS, NL, PT BR), [translation teams]
|
||||
Piwik [tobiasd]
|
||||
Twitter Connector [heluecht]
|
||||
Pumpio Connector [heluecht]
|
||||
Rendertime [heluecht]
|
||||
wppost [heluecht]
|
||||
showmore [rabuzarus]
|
||||
fromgplus [heluecht]
|
||||
app.net Connector [heluecht]
|
||||
GNU Social Connector [heluecht]
|
||||
LDAP [Olivier Mehani]
|
||||
smileybutton [rabuzarus]
|
||||
retriver [mexon]
|
||||
mailstream [mexon]
|
||||
forumdirectory [tobiasd]
|
||||
NEW notifyall (port from Hubzilla) [rabuzarus, tobiasd]
|
||||
DEPRECATED cal (now in core), FB Connector, FB Post Connector, FB Sync
|
||||
|
||||
Closed Issues
|
||||
683, 786, 796, 922, 1261, 1576, 1701, 1769, 1970, 1145, 1494,
|
||||
1728, 1877, 2063, 2059, 2078, 2079, 2133, 2165, 2194, 2229, 2230,
|
||||
2241, 2254, 2242, 2270, 2277, 2339, 2320, 2345, 2352, 2358, 2367,
|
||||
2373, 2376, 2378, 2385, 2395, 2402, 2406, 2433, 2472, 2485, 2492,
|
||||
2506, 2512, 2516, 2539, 2540, 2893, 2597, 2611, 2617, 2629, 2645,
|
||||
2687, 2716, 2757, 2764
|
||||
|
||||
Version 3.4.3
|
||||
What's new for the users:
|
||||
Updates to the documentation (silke, tobiasd, annando, rebeka-catalina)
|
||||
|
|
|
@ -32,8 +32,7 @@ link if your cert is self-signed).
|
|||
- Apache with mod-rewrite enabled and "Options All" so you can use a
|
||||
local .htaccess file
|
||||
|
||||
- PHP 5.2+. The later the better. PHP 5.3 is required for communications
|
||||
with the Diaspora network and improved security.
|
||||
- PHP 5.4+.
|
||||
|
||||
- PHP *command line* access with register_argc_argv set to true in the
|
||||
php.ini file [or see 'poormancron' in section 8]
|
||||
|
@ -42,7 +41,7 @@ php.ini file [or see 'poormancron' in section 8]
|
|||
|
||||
- some form of email server or email gateway such that PHP mail() works
|
||||
|
||||
- Mysql 5.x
|
||||
- Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
|
||||
|
||||
- ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks
|
||||
(Windows) [Note: other options are presented in Section 8 of this document]
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,5 +1,5 @@
|
|||
Friendica Communications Server
|
||||
Copyright (c) 2010-2013 the Friendica Project
|
||||
Copyright (c) 2010-2016 the Friendica Project
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
|
|
|
@ -24,12 +24,12 @@ If you want to get your work into the source tree yourself, feel free to do so a
|
|||
The process is simple and friendica ships with all the tools necessary.
|
||||
|
||||
The location of the translated files in the source tree is
|
||||
/view/LNG-CODE/
|
||||
/view/lang/LNG-CODE/
|
||||
where LNG-CODE is the language code used, e.g. de for German or fr for French.
|
||||
The translated strings come as a "message.po" file from transifex which needs to be translated into the PHP file friendica uses.
|
||||
To do so, place the file in the directory mentioned above and use the "po2php" utility from the util directory of your friendica installation.
|
||||
|
||||
Assuming you want to convert the German localization which is placed in view/de/message.po you would do the following.
|
||||
Assuming you want to convert the German localization which is placed in view/lang/de/message.po you would do the following.
|
||||
|
||||
1. Navigate at the command prompt to the base directory of your
|
||||
friendica installation
|
||||
|
@ -37,9 +37,9 @@ Assuming you want to convert the German localization which is placed in view/de/
|
|||
2. Execute the po2php script, which will place the translation
|
||||
in the strings.php file that is used by friendica.
|
||||
|
||||
$> php util/po2php.php view/de/messages.po
|
||||
$> php util/po2php.php view/lang/de/messages.po
|
||||
|
||||
The output of the script will be placed at view/de/strings.php where
|
||||
The output of the script will be placed at view/lang/de/strings.php where
|
||||
friendica is expecting it, so you can test your translation immediately.
|
||||
|
||||
3. Visit your friendica page to check if it still works in the language you
|
||||
|
@ -50,7 +50,7 @@ Assuming you want to convert the German localization which is placed in view/de/
|
|||
not give any output if the file is ok but might give a hint for
|
||||
searching the bug in the file.
|
||||
|
||||
$> php view/de/strings.php
|
||||
$> php view/lang/de/strings.php
|
||||
|
||||
4. commit the two files with a meaningful commit message to your git
|
||||
repository, push it to your fork of the friendica repository at github and
|
||||
|
|
364
boot.php
364
boot.php
|
@ -36,9 +36,9 @@ require_once('include/dbstructure.php');
|
|||
|
||||
define ( 'FRIENDICA_PLATFORM', 'Friendica');
|
||||
define ( 'FRIENDICA_CODENAME', 'Asparagus');
|
||||
define ( 'FRIENDICA_VERSION', '3.5-dev' );
|
||||
define ( 'FRIENDICA_VERSION', '3.5.1-dev' );
|
||||
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
|
||||
define ( 'DB_UPDATE_VERSION', 1196 );
|
||||
define ( 'DB_UPDATE_VERSION', 1208 );
|
||||
|
||||
/**
|
||||
* @brief Constant with a HTML line break.
|
||||
|
@ -127,6 +127,10 @@ define ( 'CACHE_MONTH', 0 );
|
|||
define ( 'CACHE_WEEK', 1 );
|
||||
define ( 'CACHE_DAY', 2 );
|
||||
define ( 'CACHE_HOUR', 3 );
|
||||
define ( 'CACHE_HALF_HOUR', 4 );
|
||||
define ( 'CACHE_QUARTER_HOUR', 5 );
|
||||
define ( 'CACHE_FIVE_MINUTES', 6 );
|
||||
define ( 'CACHE_MINUTE', 7 );
|
||||
/* @}*/
|
||||
|
||||
/**
|
||||
|
@ -181,6 +185,28 @@ define ( 'PAGE_BLOG', 4 );
|
|||
define ( 'PAGE_PRVGROUP', 5 );
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* @name account types
|
||||
*
|
||||
* ACCOUNT_TYPE_PERSON - the account belongs to a person
|
||||
* Associated page types: PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE
|
||||
*
|
||||
* ACCOUNT_TYPE_ORGANISATION - the account belongs to an organisation
|
||||
* Associated page type: PAGE_SOAPBOX
|
||||
*
|
||||
* ACCOUNT_TYPE_NEWS - the account is a news reflector
|
||||
* Associated page type: PAGE_SOAPBOX
|
||||
*
|
||||
* ACCOUNT_TYPE_COMMUNITY - the account is community forum
|
||||
* Associated page types: PAGE_COMMUNITY, PAGE_PRVGROUP
|
||||
* @{
|
||||
*/
|
||||
define ( 'ACCOUNT_TYPE_PERSON', 0 );
|
||||
define ( 'ACCOUNT_TYPE_ORGANISATION',1 );
|
||||
define ( 'ACCOUNT_TYPE_NEWS', 2 );
|
||||
define ( 'ACCOUNT_TYPE_COMMUNITY', 3 );
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* @name CP
|
||||
*
|
||||
|
@ -386,6 +412,20 @@ define ( 'GRAVITY_LIKE', 3);
|
|||
define ( 'GRAVITY_COMMENT', 6);
|
||||
/* @}*/
|
||||
|
||||
/**
|
||||
* @name Priority
|
||||
*
|
||||
* Process priority for the worker
|
||||
* @{
|
||||
*/
|
||||
define('PRIORITY_UNDEFINED', 0);
|
||||
define('PRIORITY_CRITICAL', 10);
|
||||
define('PRIORITY_HIGH', 20);
|
||||
define('PRIORITY_MEDIUM', 30);
|
||||
define('PRIORITY_LOW', 40);
|
||||
define('PRIORITY_NEGLIGIBLE',50);
|
||||
/* @}*/
|
||||
|
||||
|
||||
// Normally this constant is defined - but not if "pcntl" isn't installed
|
||||
if (!defined("SIGTERM"))
|
||||
|
@ -475,6 +515,7 @@ class App {
|
|||
public $performance = array();
|
||||
public $callstack = array();
|
||||
public $theme_info = array();
|
||||
public $backend = true;
|
||||
|
||||
public $nav_sel;
|
||||
|
||||
|
@ -516,6 +557,8 @@ class App {
|
|||
*/
|
||||
public $template_engine_instance = array();
|
||||
|
||||
public $process_id;
|
||||
|
||||
private $ldelim = array(
|
||||
'internal' => '',
|
||||
'smarty3' => '{{'
|
||||
|
@ -557,6 +600,7 @@ class App {
|
|||
|
||||
$this->performance["start"] = microtime(true);
|
||||
$this->performance["database"] = 0;
|
||||
$this->performance["database_write"] = 0;
|
||||
$this->performance["network"] = 0;
|
||||
$this->performance["file"] = 0;
|
||||
$this->performance["rendering"] = 0;
|
||||
|
@ -576,6 +620,8 @@ class App {
|
|||
|
||||
$this->query_string = '';
|
||||
|
||||
$this->process_id = uniqid("log", true);
|
||||
|
||||
startup();
|
||||
|
||||
set_include_path(
|
||||
|
@ -739,60 +785,100 @@ class App {
|
|||
return($this->scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the Friendica instance base URL
|
||||
*
|
||||
* This function assembles the base URL from multiple parts:
|
||||
* - Protocol is determined either by the request or a combination of
|
||||
* system.ssl_policy and the $ssl parameter.
|
||||
* - Host name is determined either by system.hostname or inferred from request
|
||||
* - Path is inferred from SCRIPT_NAME
|
||||
*
|
||||
* Caches the result (depending on $ssl value) for performance.
|
||||
*
|
||||
* Note: $ssl parameter value doesn't directly correlate with the resulting protocol
|
||||
*
|
||||
* @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN
|
||||
* @return string Friendica server base URL
|
||||
*/
|
||||
function get_baseurl($ssl = false) {
|
||||
|
||||
// Is the function called statically?
|
||||
if (!is_object($this))
|
||||
return(self::$a->get_baseurl($ssl));
|
||||
if (!is_object($this)) {
|
||||
return self::$a->get_baseurl($ssl);
|
||||
}
|
||||
|
||||
// Arbitrary values, the resulting url protocol can be different
|
||||
$cache_index = $ssl ? 'https' : 'http';
|
||||
|
||||
// Cached value found, nothing to process
|
||||
if (isset($this->baseurl[$cache_index])) {
|
||||
return $this->baseurl[$cache_index];
|
||||
}
|
||||
|
||||
$scheme = $this->scheme;
|
||||
|
||||
if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) {
|
||||
if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL))
|
||||
if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) {
|
||||
$scheme = 'https';
|
||||
}
|
||||
|
||||
// Basically, we have $ssl = true on any links which can only be seen by a logged in user
|
||||
// (and also the login link). Anything seen by an outsider will have it turned off.
|
||||
|
||||
if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
|
||||
if($ssl)
|
||||
if ($ssl) {
|
||||
$scheme = 'https';
|
||||
else
|
||||
} else {
|
||||
$scheme = 'http';
|
||||
}
|
||||
}
|
||||
|
||||
if (get_config('config','hostname') != "")
|
||||
$this->hostname = get_config('config','hostname');
|
||||
|
||||
$this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
|
||||
return $this->baseurl;
|
||||
}
|
||||
|
||||
if (get_config('config', 'hostname') != '') {
|
||||
$this->hostname = get_config('config', 'hostname');
|
||||
}
|
||||
|
||||
$this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
|
||||
|
||||
return $this->baseurl[$cache_index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the baseurl components
|
||||
*
|
||||
* Clears the baseurl cache to prevent inconstistencies
|
||||
*
|
||||
* @param string $url
|
||||
*/
|
||||
function set_baseurl($url) {
|
||||
$parsed = @parse_url($url);
|
||||
|
||||
$this->baseurl = $url;
|
||||
$this->baseurl = [];
|
||||
|
||||
if($parsed) {
|
||||
$this->scheme = $parsed['scheme'];
|
||||
|
||||
$hostname = $parsed['host'];
|
||||
if(x($parsed,'port'))
|
||||
if (x($parsed, 'port')) {
|
||||
$hostname .= ':' . $parsed['port'];
|
||||
if(x($parsed,'path'))
|
||||
}
|
||||
if (x($parsed, 'path')) {
|
||||
$this->path = trim($parsed['path'], '\\/');
|
||||
|
||||
if (file_exists(".htpreconfig.php"))
|
||||
@include(".htpreconfig.php");
|
||||
|
||||
if (get_config('config','hostname') != "")
|
||||
$this->hostname = get_config('config','hostname');
|
||||
|
||||
if (!isset($this->hostname) OR ($this->hostname == ""))
|
||||
$this->hostname = $hostname;
|
||||
}
|
||||
|
||||
if (file_exists(".htpreconfig.php")) {
|
||||
@include(".htpreconfig.php");
|
||||
}
|
||||
|
||||
if (get_config('config', 'hostname') != '') {
|
||||
$this->hostname = get_config('config', 'hostname');
|
||||
}
|
||||
|
||||
if (!isset($this->hostname) OR ($this->hostname == '')) {
|
||||
$this->hostname = $hostname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get_hostname() {
|
||||
|
@ -940,7 +1026,7 @@ class App {
|
|||
} else {
|
||||
$r = q("SELECT `contact`.`avatar-date` AS picdate FROM `contact` WHERE `contact`.`thumb` like '%%/%s'",
|
||||
$common_filename);
|
||||
if(! count($r)){
|
||||
if(! dbm::is_result($r)){
|
||||
$this->cached_profile_image[$avatar_image] = $avatar_image;
|
||||
} else {
|
||||
$this->cached_profile_picdate[$common_filename] = "?rev=".urlencode($r[0]['picdate']);
|
||||
|
@ -1058,6 +1144,9 @@ class App {
|
|||
}
|
||||
|
||||
function save_timestamp($stamp, $value) {
|
||||
if (!isset($this->config['system']['profiler']) || !$this->config['system']['profiler'])
|
||||
return;
|
||||
|
||||
$duration = (float)(microtime(true)-$stamp);
|
||||
|
||||
if (!isset($this->performance[$value])) {
|
||||
|
@ -1079,6 +1168,52 @@ class App {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Log active processes into the "process" table
|
||||
*/
|
||||
function start_process() {
|
||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
|
||||
|
||||
$command = basename($trace[0]["file"]);
|
||||
|
||||
$this->remove_inactive_processes();
|
||||
|
||||
q("START TRANSACTION");
|
||||
|
||||
$r = q("SELECT `pid` FROM `process` WHERE `pid` = %d", intval(getmypid()));
|
||||
if(!dbm::is_result($r)) {
|
||||
q("INSERT INTO `process` (`pid`,`command`,`created`) VALUES (%d, '%s', '%s')",
|
||||
intval(getmypid()),
|
||||
dbesc($command),
|
||||
dbesc(datetime_convert()));
|
||||
}
|
||||
q("COMMIT");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove inactive processes
|
||||
*/
|
||||
function remove_inactive_processes() {
|
||||
q("START TRANSACTION");
|
||||
|
||||
$r = q("SELECT `pid` FROM `process`");
|
||||
if(dbm::is_result($r)) {
|
||||
foreach ($r AS $process) {
|
||||
if (!posix_kill($process["pid"], 0)) {
|
||||
q("DELETE FROM `process` WHERE `pid` = %d", intval($process["pid"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
q("COMMIT");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove the active process from the "process" table
|
||||
*/
|
||||
function end_process() {
|
||||
q("DELETE FROM `process` WHERE `pid` = %d", intval(getmypid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string with a callstack. Can be used for logging.
|
||||
*
|
||||
|
@ -1098,11 +1233,6 @@ class App {
|
|||
return implode(", ", $callstack);
|
||||
}
|
||||
|
||||
function mark_timestamp($mark) {
|
||||
//$this->performance["markstart"] -= microtime(true) - $this->performance["marktime"];
|
||||
$this->performance["markstart"] = microtime(true) - $this->performance["markstart"] - $this->performance["marktime"];
|
||||
}
|
||||
|
||||
function get_useragent() {
|
||||
return(FRIENDICA_PLATFORM." '".FRIENDICA_CODENAME."' ".FRIENDICA_VERSION."-".DB_UPDATE_VERSION."; ".$this->get_baseurl());
|
||||
}
|
||||
|
@ -1111,6 +1241,77 @@ class App {
|
|||
return($this->is_friendica_app);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the site is called via a backend process
|
||||
*
|
||||
* This isn't a perfect solution. But we need this check very early.
|
||||
* So we cannot wait until the modules are loaded.
|
||||
*
|
||||
* @return bool Is it a known backend?
|
||||
*/
|
||||
function is_backend() {
|
||||
$backend = array();
|
||||
$backend[] = "_well_known";
|
||||
$backend[] = "api";
|
||||
$backend[] = "dfrn_notify";
|
||||
$backend[] = "fetch";
|
||||
$backend[] = "hcard";
|
||||
$backend[] = "hostxrd";
|
||||
$backend[] = "nodeinfo";
|
||||
$backend[] = "noscrape";
|
||||
$backend[] = "p";
|
||||
$backend[] = "poco";
|
||||
$backend[] = "post";
|
||||
$backend[] = "proxy";
|
||||
$backend[] = "pubsub";
|
||||
$backend[] = "pubsubhubbub";
|
||||
$backend[] = "receive";
|
||||
$backend[] = "rsd_xml";
|
||||
$backend[] = "salmon";
|
||||
$backend[] = "statistics_json";
|
||||
$backend[] = "xrd";
|
||||
|
||||
if (in_array($this->module, $backend))
|
||||
return(true);
|
||||
else
|
||||
return($this->backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the maximum number of database processes is reached
|
||||
*
|
||||
* @return bool Is the limit reached?
|
||||
*/
|
||||
function max_processes_reached() {
|
||||
|
||||
// Is the function called statically?
|
||||
if (!is_object($this))
|
||||
return(self::$a->max_processes_reached());
|
||||
|
||||
if ($this->is_backend()) {
|
||||
$process = "backend";
|
||||
$max_processes = get_config('system', 'max_processes_backend');
|
||||
if (intval($max_processes) == 0)
|
||||
$max_processes = 5;
|
||||
} else {
|
||||
$process = "frontend";
|
||||
$max_processes = get_config('system', 'max_processes_frontend');
|
||||
if (intval($max_processes) == 0)
|
||||
$max_processes = 20;
|
||||
}
|
||||
|
||||
$processlist = dbm::processlist();
|
||||
if ($processlist["list"] != "") {
|
||||
logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
|
||||
|
||||
if ($processlist["amount"] > $max_processes) {
|
||||
logger("Processcheck: Maximum number of processes for ".$process." tasks (".$max_processes.") reached.", LOGGER_DEBUG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the maximum load is reached
|
||||
*
|
||||
|
@ -1118,14 +1319,26 @@ class App {
|
|||
*/
|
||||
function maxload_reached() {
|
||||
|
||||
// Is the function called statically?
|
||||
if (!is_object($this))
|
||||
return(self::$a->maxload_reached());
|
||||
|
||||
if ($this->is_backend()) {
|
||||
$process = "backend";
|
||||
$maxsysload = intval(get_config('system', 'maxloadavg'));
|
||||
if ($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
} else {
|
||||
$process = "frontend";
|
||||
$maxsysload = intval(get_config('system','maxloadavg_frontend'));
|
||||
if ($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
}
|
||||
|
||||
$load = current_load();
|
||||
if ($load) {
|
||||
if (intval($load) > $maxsysload) {
|
||||
logger('system: load '.$load.' too high.');
|
||||
logger('system: load '.$load.' for '.$process.' tasks ('.$maxsysload.') too high.');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1153,13 +1366,46 @@ class App {
|
|||
logger("killed stale process");
|
||||
// Calling a new instance
|
||||
if ($task != "")
|
||||
proc_run('php', $task);
|
||||
proc_run(PRIORITY_MEDIUM, $task);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function proc_run($args) {
|
||||
|
||||
// Add the php path if it is a php call
|
||||
if (count($args) && ($args[0] === 'php' OR is_int($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")) {
|
||||
if ((time() - get_config("system", "proc_run_started")) < 10)
|
||||
return;
|
||||
|
||||
// Set the timestamp of the last proc_run
|
||||
set_config("system", "proc_run_started", time());
|
||||
}
|
||||
|
||||
$args[0] = ((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();
|
||||
|
||||
for($x = 0; $x < count($args); $x ++)
|
||||
$args[$x] = escapeshellarg($args[$x]);
|
||||
|
||||
$cmdline = implode($args," ");
|
||||
|
||||
if(get_config('system','proc_windows'))
|
||||
proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__)));
|
||||
else
|
||||
proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1275,7 +1521,7 @@ function check_db() {
|
|||
$build = DB_UPDATE_VERSION;
|
||||
}
|
||||
if($build != DB_UPDATE_VERSION)
|
||||
proc_run('php', 'include/dbupdate.php');
|
||||
proc_run(PRIORITY_CRITICAL, 'include/dbupdate.php');
|
||||
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1671,7 @@ function run_update_function($x) {
|
|||
function check_plugins(&$a) {
|
||||
|
||||
$r = q("SELECT * FROM `addon` WHERE `installed` = 1");
|
||||
if(count($r))
|
||||
if(dbm::is_result($r))
|
||||
$installed = $r;
|
||||
else
|
||||
$installed = array();
|
||||
|
@ -1563,7 +1809,10 @@ function login($register = false, $hiddens=false) {
|
|||
* @brief Used to end the current process, after saving session state.
|
||||
*/
|
||||
function killme() {
|
||||
|
||||
if (!get_app()->is_backend())
|
||||
session_write_close();
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -1648,10 +1897,11 @@ 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 $cmd program to run
|
||||
* @param (string|integer) $cmd program to run or priority
|
||||
*
|
||||
* 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);
|
||||
*
|
||||
* @note $cmd and string args are surrounded with ""
|
||||
*
|
||||
|
@ -1675,8 +1925,7 @@ function proc_run($cmd){
|
|||
foreach($arg as $n) {
|
||||
$newargs[] = $n;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
$newargs[] = $arg;
|
||||
}
|
||||
|
||||
|
@ -1685,12 +1934,20 @@ function proc_run($cmd){
|
|||
$arr = array('args' => $args, 'run_cmd' => true);
|
||||
|
||||
call_hooks("proc_run", $arr);
|
||||
if(! $arr['run_cmd'])
|
||||
if (!$arr['run_cmd'] OR !count($args))
|
||||
return;
|
||||
|
||||
if(count($args) && $args[0] === 'php') {
|
||||
if (!get_config("system", "worker") OR
|
||||
(($args[0] != 'php') AND !is_int($args[0]))) {
|
||||
$a->proc_run($args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_int($args[0]))
|
||||
$priority = $args[0];
|
||||
else
|
||||
$priority = PRIORITY_MEDIUM;
|
||||
|
||||
if (get_config("system", "worker")) {
|
||||
$argv = $args;
|
||||
array_shift($argv);
|
||||
|
||||
|
@ -1703,7 +1960,7 @@ function proc_run($cmd){
|
|||
VALUES ('%s', '%s', %d)",
|
||||
dbesc($parameters),
|
||||
dbesc(datetime_convert()),
|
||||
intval(0));
|
||||
intval($priority));
|
||||
|
||||
// Should we quit and wait for the poller to be called as a cronjob?
|
||||
if (get_config("system", "worker_dont_fork"))
|
||||
|
@ -1724,23 +1981,8 @@ function proc_run($cmd){
|
|||
|
||||
// Now call the poller to execute the jobs that we just added to the queue
|
||||
$args = array("php", "include/poller.php", "no_cron");
|
||||
}
|
||||
|
||||
$args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
|
||||
}
|
||||
|
||||
// add baseurl to args. cli scripts can't construct it
|
||||
$args[] = $a->get_baseurl();
|
||||
|
||||
for($x = 0; $x < count($args); $x ++)
|
||||
$args[$x] = escapeshellarg($args[$x]);
|
||||
|
||||
$cmdline = implode($args," ");
|
||||
|
||||
if(get_config('system','proc_windows'))
|
||||
proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__)));
|
||||
else
|
||||
proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__)));
|
||||
$a->proc_run($args);
|
||||
}
|
||||
|
||||
function current_theme(){
|
||||
|
@ -1756,7 +1998,7 @@ function current_theme(){
|
|||
$r = q("select theme from user where uid = %d limit 1",
|
||||
intval($a->profile_uid)
|
||||
);
|
||||
if($r)
|
||||
if(dbm::is_result($r))
|
||||
$page_theme = $r[0]['theme'];
|
||||
}
|
||||
|
||||
|
@ -1869,7 +2111,7 @@ function feed_birthday($uid,$tz) {
|
|||
intval($uid)
|
||||
);
|
||||
|
||||
if($p && count($p)) {
|
||||
if(dbm::is_result($p)) {
|
||||
$tmp_dob = substr($p[0]['dob'],5);
|
||||
if(intval($tmp_dob)) {
|
||||
$y = datetime_convert($tz,$tz,'now','Y');
|
||||
|
@ -2165,7 +2407,7 @@ function current_load() {
|
|||
if (!is_array($load_arr))
|
||||
return false;
|
||||
|
||||
return max($load_arr);
|
||||
return max($load_arr[0], $load_arr[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
352
database.sql
352
database.sql
|
@ -1,6 +1,6 @@
|
|||
-- ------------------------------------------
|
||||
-- Friendica 3.5-dev (Asparagus)
|
||||
-- DB_UPDATE_VERSION 1196
|
||||
-- Friendica 3.5.1-dev (Asparagus)
|
||||
-- DB_UPDATE_VERSION 1205
|
||||
-- ------------------------------------------
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS `addon` (
|
|||
`timestamp` bigint(20) NOT NULL DEFAULT 0,
|
||||
`plugin_admin` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE attach
|
||||
|
@ -31,12 +31,12 @@ CREATE TABLE IF NOT EXISTS `attach` (
|
|||
`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',
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
`deny_gid` mediumtext NOT NULL,
|
||||
`allow_cid` mediumtext,
|
||||
`allow_gid` mediumtext,
|
||||
`deny_cid` mediumtext,
|
||||
`deny_gid` mediumtext,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE auth_codes
|
||||
|
@ -48,19 +48,19 @@ CREATE TABLE IF NOT EXISTS `auth_codes` (
|
|||
`expires` int(11) NOT NULL DEFAULT 0,
|
||||
`scope` varchar(250) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE cache
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `cache` (
|
||||
`k` varchar(255) NOT NULL,
|
||||
`v` text NOT NULL,
|
||||
`v` text,
|
||||
`expire_mode` int(11) NOT NULL DEFAULT 0,
|
||||
`updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`k`),
|
||||
PRIMARY KEY(`k`(191)),
|
||||
INDEX `updated` (`updated`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE challenge
|
||||
|
@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS `challenge` (
|
|||
`type` varchar(255) NOT NULL DEFAULT '',
|
||||
`last_update` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE clients
|
||||
|
@ -86,7 +86,7 @@ CREATE TABLE IF NOT EXISTS `clients` (
|
|||
`icon` text,
|
||||
`uid` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`client_id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE config
|
||||
|
@ -95,10 +95,10 @@ CREATE TABLE IF NOT EXISTS `config` (
|
|||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`cat` varchar(255) NOT NULL DEFAULT '',
|
||||
`k` varchar(255) NOT NULL DEFAULT '',
|
||||
`v` text NOT NULL,
|
||||
`v` text,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `cat_k` (`cat`(30),`k`(30))
|
||||
) DEFAULT CHARSET=utf8;
|
||||
UNIQUE INDEX `cat_k` (`cat`(30),`k`(30))
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE contact
|
||||
|
@ -115,29 +115,30 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
|||
`name` varchar(255) NOT NULL DEFAULT '',
|
||||
`nick` varchar(255) NOT NULL DEFAULT '',
|
||||
`location` varchar(255) NOT NULL DEFAULT '',
|
||||
`about` text NOT NULL,
|
||||
`keywords` text NOT NULL,
|
||||
`about` text,
|
||||
`keywords` text,
|
||||
`gender` varchar(32) NOT NULL DEFAULT '',
|
||||
`xmpp` varchar(255) NOT NULL DEFAULT '',
|
||||
`attag` varchar(255) NOT NULL DEFAULT '',
|
||||
`avatar` varchar(255) NOT NULL DEFAULT '',
|
||||
`photo` text NOT NULL,
|
||||
`thumb` text NOT NULL,
|
||||
`micro` text NOT NULL,
|
||||
`site-pubkey` text NOT NULL,
|
||||
`photo` text,
|
||||
`thumb` text,
|
||||
`micro` text,
|
||||
`site-pubkey` text,
|
||||
`issued-id` varchar(255) NOT NULL DEFAULT '',
|
||||
`dfrn-id` varchar(255) NOT NULL DEFAULT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '',
|
||||
`nurl` varchar(255) NOT NULL DEFAULT '',
|
||||
`addr` varchar(255) NOT NULL DEFAULT '',
|
||||
`alias` varchar(255) NOT NULL DEFAULT '',
|
||||
`pubkey` text NOT NULL,
|
||||
`prvkey` text NOT NULL,
|
||||
`pubkey` text,
|
||||
`prvkey` text,
|
||||
`batch` varchar(255) NOT NULL DEFAULT '',
|
||||
`request` text NOT NULL,
|
||||
`notify` text NOT NULL,
|
||||
`poll` text NOT NULL,
|
||||
`confirm` text NOT NULL,
|
||||
`poco` text NOT NULL,
|
||||
`request` text,
|
||||
`notify` text,
|
||||
`poll` text,
|
||||
`confirm` text,
|
||||
`poco` text,
|
||||
`aes_allow` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`ret-aes` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`usehub` tinyint(1) NOT NULL DEFAULT 0,
|
||||
|
@ -157,23 +158,24 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
|||
`writable` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`forum` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`prv` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`contact-type` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`hidden` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`archive` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`pending` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`rating` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`reason` text NOT NULL,
|
||||
`reason` text,
|
||||
`closeness` tinyint(2) NOT NULL DEFAULT 99,
|
||||
`info` mediumtext NOT NULL,
|
||||
`info` mediumtext,
|
||||
`profile-id` int(11) NOT NULL DEFAULT 0,
|
||||
`bdyear` varchar(4) NOT NULL DEFAULT '',
|
||||
`bd` date NOT NULL DEFAULT '0000-00-00',
|
||||
`notify_new_posts` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`fetch_further_information` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`ffi_keyword_blacklist` mediumtext NOT NULL,
|
||||
`ffi_keyword_blacklist` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `nurl` (`nurl`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE conv
|
||||
|
@ -181,15 +183,15 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
|||
CREATE TABLE IF NOT EXISTS `conv` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`guid` varchar(64) NOT NULL DEFAULT '',
|
||||
`recips` mediumtext NOT NULL,
|
||||
`recips` mediumtext,
|
||||
`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',
|
||||
`subject` mediumtext NOT NULL,
|
||||
`subject` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE deliverq
|
||||
|
@ -200,7 +202,7 @@ CREATE TABLE IF NOT EXISTS `deliverq` (
|
|||
`item` int(11) NOT NULL DEFAULT 0,
|
||||
`contact` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE event
|
||||
|
@ -214,26 +216,27 @@ CREATE TABLE IF NOT EXISTS `event` (
|
|||
`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',
|
||||
`summary` text NOT NULL,
|
||||
`desc` text NOT NULL,
|
||||
`location` text NOT NULL,
|
||||
`summary` text,
|
||||
`desc` text,
|
||||
`location` text,
|
||||
`type` varchar(255) NOT NULL DEFAULT '',
|
||||
`nofinish` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`adjust` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`ignore` tinyint(1) unsigned NOT NULL DEFAULT 0,
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
`deny_gid` mediumtext NOT NULL,
|
||||
`allow_cid` mediumtext,
|
||||
`allow_gid` mediumtext,
|
||||
`deny_cid` mediumtext,
|
||||
`deny_gid` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE fcontact
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `fcontact` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`guid` varchar(255) NOT NULL DEFAULT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '',
|
||||
`name` varchar(255) NOT NULL DEFAULT '',
|
||||
`photo` varchar(255) NOT NULL DEFAULT '',
|
||||
|
@ -247,11 +250,11 @@ CREATE TABLE IF NOT EXISTS `fcontact` (
|
|||
`priority` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`network` varchar(32) NOT NULL DEFAULT '',
|
||||
`alias` varchar(255) NOT NULL DEFAULT '',
|
||||
`pubkey` text NOT NULL,
|
||||
`pubkey` text,
|
||||
`updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `addr` (`addr`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE ffinder
|
||||
|
@ -262,7 +265,7 @@ CREATE TABLE IF NOT EXISTS `ffinder` (
|
|||
`cid` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`fid` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE fserver
|
||||
|
@ -271,10 +274,10 @@ CREATE TABLE IF NOT EXISTS `fserver` (
|
|||
`id` int(11) NOT NULL auto_increment,
|
||||
`server` varchar(255) NOT NULL DEFAULT '',
|
||||
`posturl` varchar(255) NOT NULL DEFAULT '',
|
||||
`key` text NOT NULL,
|
||||
`key` text,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `server` (`server`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE fsuggest
|
||||
|
@ -287,10 +290,10 @@ CREATE TABLE IF NOT EXISTS `fsuggest` (
|
|||
`url` varchar(255) NOT NULL DEFAULT '',
|
||||
`request` varchar(255) NOT NULL DEFAULT '',
|
||||
`photo` varchar(255) NOT NULL DEFAULT '',
|
||||
`note` text NOT NULL,
|
||||
`note` text,
|
||||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE gcign
|
||||
|
@ -302,7 +305,7 @@ CREATE TABLE IF NOT EXISTS `gcign` (
|
|||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `gcid` (`gcid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE gcontact
|
||||
|
@ -320,16 +323,17 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
|
|||
`last_contact` datetime DEFAULT '0000-00-00 00:00:00',
|
||||
`last_failure` datetime DEFAULT '0000-00-00 00:00:00',
|
||||
`location` varchar(255) NOT NULL DEFAULT '',
|
||||
`about` text NOT NULL,
|
||||
`keywords` text NOT NULL,
|
||||
`about` text,
|
||||
`keywords` text,
|
||||
`gender` varchar(32) NOT NULL DEFAULT '',
|
||||
`birthday` varchar(32) NOT NULL DEFAULT '0000-00-00',
|
||||
`community` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`contact-type` tinyint(1) NOT NULL DEFAULT -1,
|
||||
`hide` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`nsfw` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`network` varchar(255) NOT NULL DEFAULT '',
|
||||
`addr` varchar(255) NOT NULL DEFAULT '',
|
||||
`notify` text NOT NULL,
|
||||
`notify` text,
|
||||
`alias` varchar(255) NOT NULL DEFAULT '',
|
||||
`generation` tinyint(3) NOT NULL DEFAULT 0,
|
||||
`server_url` varchar(255) NOT NULL DEFAULT '',
|
||||
|
@ -339,7 +343,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
|
|||
INDEX `nick` (`nick`),
|
||||
INDEX `addr` (`addr`),
|
||||
INDEX `updated` (`updated`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE glink
|
||||
|
@ -355,7 +359,7 @@ CREATE TABLE IF NOT EXISTS `glink` (
|
|||
INDEX `cid_uid_gcid_zcid` (`cid`,`uid`,`gcid`,`zcid`),
|
||||
INDEX `gcid` (`gcid`),
|
||||
INDEX `zcid` (`zcid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE group
|
||||
|
@ -368,7 +372,7 @@ CREATE TABLE IF NOT EXISTS `group` (
|
|||
`name` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE group_member
|
||||
|
@ -380,7 +384,7 @@ CREATE TABLE IF NOT EXISTS `group_member` (
|
|||
`contact-id` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_gid_contactid` (`uid`,`gid`,`contact-id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE gserver
|
||||
|
@ -391,7 +395,7 @@ CREATE TABLE IF NOT EXISTS `gserver` (
|
|||
`nurl` varchar(255) NOT NULL DEFAULT '',
|
||||
`version` varchar(255) NOT NULL DEFAULT '',
|
||||
`site_name` varchar(255) NOT NULL DEFAULT '',
|
||||
`info` text NOT NULL,
|
||||
`info` text,
|
||||
`register_policy` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`poco` varchar(255) NOT NULL DEFAULT '',
|
||||
`noscrape` varchar(255) NOT NULL DEFAULT '',
|
||||
|
@ -403,7 +407,7 @@ CREATE TABLE IF NOT EXISTS `gserver` (
|
|||
`last_failure` datetime DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `nurl` (`nurl`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE hook
|
||||
|
@ -416,7 +420,7 @@ CREATE TABLE IF NOT EXISTS `hook` (
|
|||
`priority` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `hook_file_function` (`hook`(30),`file`(60),`function`(30))
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE intro
|
||||
|
@ -428,13 +432,13 @@ CREATE TABLE IF NOT EXISTS `intro` (
|
|||
`contact-id` int(11) NOT NULL DEFAULT 0,
|
||||
`knowyou` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`duplex` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`note` text NOT NULL,
|
||||
`note` text,
|
||||
`hash` varchar(255) NOT NULL DEFAULT '',
|
||||
`datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`blocked` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`ignore` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE item
|
||||
|
@ -458,34 +462,36 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`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',
|
||||
`owner-id` int(11) NOT NULL DEFAULT 0,
|
||||
`owner-name` varchar(255) NOT NULL DEFAULT '',
|
||||
`owner-link` varchar(255) NOT NULL DEFAULT '',
|
||||
`owner-avatar` varchar(255) NOT NULL DEFAULT '',
|
||||
`author-id` int(11) NOT NULL DEFAULT 0,
|
||||
`author-name` varchar(255) NOT NULL DEFAULT '',
|
||||
`author-link` varchar(255) NOT NULL DEFAULT '',
|
||||
`author-avatar` varchar(255) NOT NULL DEFAULT '',
|
||||
`title` varchar(255) NOT NULL DEFAULT '',
|
||||
`body` mediumtext NOT NULL,
|
||||
`body` mediumtext,
|
||||
`app` varchar(255) NOT NULL DEFAULT '',
|
||||
`verb` varchar(255) NOT NULL DEFAULT '',
|
||||
`object-type` varchar(255) NOT NULL DEFAULT '',
|
||||
`object` text NOT NULL,
|
||||
`object` text,
|
||||
`target-type` varchar(255) NOT NULL DEFAULT '',
|
||||
`target` text NOT NULL,
|
||||
`postopts` text NOT NULL,
|
||||
`target` text,
|
||||
`postopts` text,
|
||||
`plink` varchar(255) NOT NULL DEFAULT '',
|
||||
`resource-id` varchar(255) NOT NULL DEFAULT '',
|
||||
`event-id` int(11) NOT NULL DEFAULT 0,
|
||||
`tag` mediumtext NOT NULL,
|
||||
`attach` mediumtext NOT NULL,
|
||||
`inform` mediumtext NOT NULL,
|
||||
`file` mediumtext NOT NULL,
|
||||
`tag` mediumtext,
|
||||
`attach` mediumtext,
|
||||
`inform` mediumtext,
|
||||
`file` mediumtext,
|
||||
`location` varchar(255) NOT NULL DEFAULT '',
|
||||
`coord` varchar(255) NOT NULL DEFAULT '',
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
`deny_gid` mediumtext NOT NULL,
|
||||
`allow_cid` mediumtext,
|
||||
`allow_gid` mediumtext,
|
||||
`deny_cid` mediumtext,
|
||||
`deny_gid` mediumtext,
|
||||
`private` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`pubmail` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`moderated` tinyint(1) NOT NULL DEFAULT 0,
|
||||
|
@ -501,7 +507,7 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`mention` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`network` varchar(32) NOT NULL DEFAULT '',
|
||||
`rendered-hash` varchar(32) NOT NULL DEFAULT '',
|
||||
`rendered-html` mediumtext NOT NULL,
|
||||
`rendered-html` mediumtext,
|
||||
`global` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `guid` (`guid`),
|
||||
|
@ -519,15 +525,18 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
INDEX `uid_title` (`uid`,`title`),
|
||||
INDEX `uid_thrparent` (`uid`,`thr-parent`),
|
||||
INDEX `uid_parenturi` (`uid`,`parent-uri`),
|
||||
INDEX `uid_contactid_id` (`uid`,`contact-id`,`id`),
|
||||
INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`),
|
||||
INDEX `gcontactid_uid_created` (`gcontact-id`,`uid`,`created`),
|
||||
INDEX `authorid_created` (`author-id`,`created`),
|
||||
INDEX `ownerid_created` (`owner-id`,`created`),
|
||||
INDEX `wall_body` (`wall`,`body`(6)),
|
||||
INDEX `uid_visible_moderated_created` (`uid`,`visible`,`moderated`,`created`),
|
||||
INDEX `uid_uri` (`uid`,`uri`),
|
||||
INDEX `uid_wall_created` (`uid`,`wall`,`created`),
|
||||
INDEX `resource-id` (`resource-id`),
|
||||
INDEX `uid_type` (`uid`,`type`),
|
||||
INDEX `uid_starred` (`uid`,`starred`),
|
||||
INDEX `uid_starred_id` (`uid`,`starred`,`id`),
|
||||
INDEX `contactid_allowcid_allowpid_denycid_denygid` (`contact-id`,`allow_cid`(10),`allow_gid`(10),`deny_cid`(10),`deny_gid`(10)),
|
||||
INDEX `uid_wall_parent_created` (`uid`,`wall`,`parent`,`created`),
|
||||
INDEX `uid_type_changed` (`uid`,`type`,`changed`),
|
||||
|
@ -537,7 +546,7 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
INDEX `uid_eventid` (`uid`,`event-id`),
|
||||
INDEX `uid_authorlink` (`uid`,`author-link`),
|
||||
INDEX `uid_ownerlink` (`uid`,`owner-link`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE item_id
|
||||
|
@ -553,7 +562,7 @@ CREATE TABLE IF NOT EXISTS `item_id` (
|
|||
INDEX `sid` (`sid`),
|
||||
INDEX `service` (`service`),
|
||||
INDEX `iid` (`iid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE locks
|
||||
|
@ -564,7 +573,7 @@ CREATE TABLE IF NOT EXISTS `locks` (
|
|||
`locked` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`created` datetime DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE mail
|
||||
|
@ -579,7 +588,7 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
`contact-id` varchar(255) NOT NULL DEFAULT '',
|
||||
`convid` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`title` varchar(255) NOT NULL DEFAULT '',
|
||||
`body` mediumtext NOT NULL,
|
||||
`body` mediumtext,
|
||||
`seen` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`reply` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`replied` tinyint(1) NOT NULL DEFAULT 0,
|
||||
|
@ -594,7 +603,7 @@ CREATE TABLE IF NOT EXISTS `mail` (
|
|||
INDEX `reply` (`reply`),
|
||||
INDEX `uri` (`uri`),
|
||||
INDEX `parent-uri` (`parent-uri`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE mailacct
|
||||
|
@ -607,14 +616,14 @@ CREATE TABLE IF NOT EXISTS `mailacct` (
|
|||
`ssltype` varchar(16) NOT NULL DEFAULT '',
|
||||
`mailbox` varchar(255) NOT NULL DEFAULT '',
|
||||
`user` varchar(255) NOT NULL DEFAULT '',
|
||||
`pass` text NOT NULL,
|
||||
`pass` text,
|
||||
`reply_to` varchar(255) NOT NULL DEFAULT '',
|
||||
`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',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE manage
|
||||
|
@ -625,7 +634,7 @@ CREATE TABLE IF NOT EXISTS `manage` (
|
|||
`mid` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_mid` (`uid`,`mid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE notify
|
||||
|
@ -638,7 +647,7 @@ CREATE TABLE IF NOT EXISTS `notify` (
|
|||
`url` varchar(255) NOT NULL DEFAULT '',
|
||||
`photo` varchar(255) NOT NULL DEFAULT '',
|
||||
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`msg` mediumtext NOT NULL,
|
||||
`msg` mediumtext,
|
||||
`uid` int(11) NOT NULL DEFAULT 0,
|
||||
`link` varchar(255) NOT NULL DEFAULT '',
|
||||
`iid` int(11) NOT NULL DEFAULT 0,
|
||||
|
@ -646,9 +655,11 @@ CREATE TABLE IF NOT EXISTS `notify` (
|
|||
`seen` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`verb` varchar(255) NOT NULL DEFAULT '',
|
||||
`otype` varchar(16) NOT NULL DEFAULT '',
|
||||
`name_cache` tinytext,
|
||||
`msg_name` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE notify-threads
|
||||
|
@ -662,18 +673,18 @@ CREATE TABLE IF NOT EXISTS `notify-threads` (
|
|||
PRIMARY KEY(`id`),
|
||||
INDEX `master-parent-item` (`master-parent-item`),
|
||||
INDEX `receiver-uid` (`receiver-uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE oembed
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `oembed` (
|
||||
`url` varchar(255) NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`content` text,
|
||||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`url`),
|
||||
PRIMARY KEY(`url`(191)),
|
||||
INDEX `created` (`created`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE parsed_url
|
||||
|
@ -682,11 +693,11 @@ CREATE TABLE IF NOT EXISTS `parsed_url` (
|
|||
`url` varchar(255) NOT NULL,
|
||||
`guessing` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`oembed` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`content` text NOT NULL,
|
||||
`content` text,
|
||||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`url`,`guessing`,`oembed`),
|
||||
PRIMARY KEY(`url`(191),`guessing`,`oembed`),
|
||||
INDEX `created` (`created`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE pconfig
|
||||
|
@ -696,10 +707,10 @@ CREATE TABLE IF NOT EXISTS `pconfig` (
|
|||
`uid` int(11) NOT NULL DEFAULT 0,
|
||||
`cat` varchar(255) NOT NULL DEFAULT '',
|
||||
`k` varchar(255) NOT NULL DEFAULT '',
|
||||
`v` mediumtext NOT NULL,
|
||||
`v` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid_cat_k` (`uid`,`cat`(30),`k`(30))
|
||||
) DEFAULT CHARSET=utf8;
|
||||
UNIQUE INDEX `uid_cat_k` (`uid`,`cat`(30),`k`(30))
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE photo
|
||||
|
@ -713,7 +724,7 @@ CREATE TABLE IF NOT EXISTS `photo` (
|
|||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`title` varchar(255) NOT NULL DEFAULT '',
|
||||
`desc` text NOT NULL,
|
||||
`desc` text,
|
||||
`album` varchar(255) NOT NULL DEFAULT '',
|
||||
`filename` varchar(255) NOT NULL DEFAULT '',
|
||||
`type` varchar(128) NOT NULL DEFAULT 'image/jpeg',
|
||||
|
@ -723,15 +734,15 @@ CREATE TABLE IF NOT EXISTS `photo` (
|
|||
`data` mediumblob NOT NULL,
|
||||
`scale` tinyint(3) NOT NULL DEFAULT 0,
|
||||
`profile` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
`deny_gid` mediumtext NOT NULL,
|
||||
`allow_cid` mediumtext,
|
||||
`allow_gid` mediumtext,
|
||||
`deny_cid` mediumtext,
|
||||
`deny_gid` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `resource-id` (`resource-id`),
|
||||
INDEX `guid` (`guid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE poll
|
||||
|
@ -739,19 +750,19 @@ CREATE TABLE IF NOT EXISTS `photo` (
|
|||
CREATE TABLE IF NOT EXISTS `poll` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`uid` int(11) NOT NULL DEFAULT 0,
|
||||
`q0` mediumtext NOT NULL,
|
||||
`q1` mediumtext NOT NULL,
|
||||
`q2` mediumtext NOT NULL,
|
||||
`q3` mediumtext NOT NULL,
|
||||
`q4` mediumtext NOT NULL,
|
||||
`q5` mediumtext NOT NULL,
|
||||
`q6` mediumtext NOT NULL,
|
||||
`q7` mediumtext NOT NULL,
|
||||
`q8` mediumtext NOT NULL,
|
||||
`q9` mediumtext NOT NULL,
|
||||
`q0` mediumtext,
|
||||
`q1` mediumtext,
|
||||
`q2` mediumtext,
|
||||
`q3` mediumtext,
|
||||
`q4` mediumtext,
|
||||
`q5` mediumtext,
|
||||
`q6` mediumtext,
|
||||
`q7` mediumtext,
|
||||
`q8` mediumtext,
|
||||
`q9` mediumtext,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE poll_result
|
||||
|
@ -763,7 +774,18 @@ CREATE TABLE IF NOT EXISTS `poll_result` (
|
|||
PRIMARY KEY(`id`),
|
||||
INDEX `poll_id` (`poll_id`),
|
||||
INDEX `choice` (`choice`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE process
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `process` (
|
||||
`pid` int(10) unsigned NOT NULL,
|
||||
`command` varchar(32) NOT NULL DEFAULT '',
|
||||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`pid`),
|
||||
INDEX `command` (`command`)
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE profile
|
||||
|
@ -785,34 +807,35 @@ CREATE TABLE IF NOT EXISTS `profile` (
|
|||
`hometown` varchar(255) NOT NULL DEFAULT '',
|
||||
`gender` varchar(32) NOT NULL DEFAULT '',
|
||||
`marital` varchar(255) NOT NULL DEFAULT '',
|
||||
`with` text NOT NULL,
|
||||
`with` text,
|
||||
`howlong` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`sexual` varchar(255) NOT NULL DEFAULT '',
|
||||
`politic` varchar(255) NOT NULL DEFAULT '',
|
||||
`religion` varchar(255) NOT NULL DEFAULT '',
|
||||
`pub_keywords` text NOT NULL,
|
||||
`prv_keywords` text NOT NULL,
|
||||
`likes` text NOT NULL,
|
||||
`dislikes` text NOT NULL,
|
||||
`about` text NOT NULL,
|
||||
`pub_keywords` text,
|
||||
`prv_keywords` text,
|
||||
`likes` text,
|
||||
`dislikes` text,
|
||||
`about` text,
|
||||
`summary` varchar(255) NOT NULL DEFAULT '',
|
||||
`music` text NOT NULL,
|
||||
`book` text NOT NULL,
|
||||
`tv` text NOT NULL,
|
||||
`film` text NOT NULL,
|
||||
`interest` text NOT NULL,
|
||||
`romance` text NOT NULL,
|
||||
`work` text NOT NULL,
|
||||
`education` text NOT NULL,
|
||||
`contact` text NOT NULL,
|
||||
`music` text,
|
||||
`book` text,
|
||||
`tv` text,
|
||||
`film` text,
|
||||
`interest` text,
|
||||
`romance` text,
|
||||
`work` text,
|
||||
`education` text,
|
||||
`contact` text,
|
||||
`homepage` varchar(255) NOT NULL DEFAULT '',
|
||||
`xmpp` varchar(255) NOT NULL DEFAULT '',
|
||||
`photo` varchar(255) NOT NULL DEFAULT '',
|
||||
`thumb` varchar(255) NOT NULL DEFAULT '',
|
||||
`publish` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`net-publish` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `hometown` (`hometown`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE profile_check
|
||||
|
@ -825,7 +848,7 @@ CREATE TABLE IF NOT EXISTS `profile_check` (
|
|||
`sec` varchar(255) NOT NULL DEFAULT '',
|
||||
`expire` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE push_subscriber
|
||||
|
@ -840,7 +863,7 @@ CREATE TABLE IF NOT EXISTS `push_subscriber` (
|
|||
`last_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`secret` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE queue
|
||||
|
@ -851,7 +874,7 @@ CREATE TABLE IF NOT EXISTS `queue` (
|
|||
`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',
|
||||
`content` mediumtext NOT NULL,
|
||||
`content` mediumtext,
|
||||
`batch` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `cid` (`cid`),
|
||||
|
@ -859,7 +882,7 @@ CREATE TABLE IF NOT EXISTS `queue` (
|
|||
INDEX `last` (`last`),
|
||||
INDEX `network` (`network`),
|
||||
INDEX `batch` (`batch`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE register
|
||||
|
@ -872,7 +895,7 @@ CREATE TABLE IF NOT EXISTS `register` (
|
|||
`password` varchar(255) NOT NULL DEFAULT '',
|
||||
`language` varchar(16) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE search
|
||||
|
@ -884,7 +907,7 @@ CREATE TABLE IF NOT EXISTS `search` (
|
|||
PRIMARY KEY(`id`),
|
||||
INDEX `uid` (`uid`),
|
||||
INDEX `term` (`term`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE session
|
||||
|
@ -892,12 +915,12 @@ CREATE TABLE IF NOT EXISTS `search` (
|
|||
CREATE TABLE IF NOT EXISTS `session` (
|
||||
`id` bigint(20) unsigned NOT NULL auto_increment,
|
||||
`sid` varchar(255) NOT NULL DEFAULT '',
|
||||
`data` text NOT NULL,
|
||||
`data` text,
|
||||
`expire` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `sid` (`sid`),
|
||||
INDEX `expire` (`expire`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE sign
|
||||
|
@ -905,12 +928,12 @@ CREATE TABLE IF NOT EXISTS `session` (
|
|||
CREATE TABLE IF NOT EXISTS `sign` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`iid` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`signed_text` mediumtext NOT NULL,
|
||||
`signature` text NOT NULL,
|
||||
`signed_text` mediumtext,
|
||||
`signature` text,
|
||||
`signer` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `iid` (`iid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE spam
|
||||
|
@ -927,7 +950,7 @@ CREATE TABLE IF NOT EXISTS `spam` (
|
|||
INDEX `spam` (`spam`),
|
||||
INDEX `ham` (`ham`),
|
||||
INDEX `term` (`term`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE term
|
||||
|
@ -952,7 +975,7 @@ CREATE TABLE IF NOT EXISTS `term` (
|
|||
INDEX `uid_otype_type_term_global_created` (`uid`,`otype`,`type`,`term`,`global`,`created`),
|
||||
INDEX `otype_type_term_tid` (`otype`,`type`,`term`,`tid`),
|
||||
INDEX `guid` (`guid`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE thread
|
||||
|
@ -962,6 +985,8 @@ CREATE TABLE IF NOT EXISTS `thread` (
|
|||
`uid` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`contact-id` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`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',
|
||||
|
@ -994,20 +1019,20 @@ CREATE TABLE IF NOT EXISTS `thread` (
|
|||
INDEX `wall_private_received` (`wall`,`private`,`received`),
|
||||
INDEX `uid_created` (`uid`,`created`),
|
||||
INDEX `uid_commented` (`uid`,`commented`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE tokens
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `tokens` (
|
||||
`id` varchar(40) NOT NULL,
|
||||
`secret` text NOT NULL,
|
||||
`secret` text,
|
||||
`client_id` varchar(20) NOT NULL DEFAULT '',
|
||||
`expires` int(11) NOT NULL DEFAULT 0,
|
||||
`scope` varchar(200) NOT NULL DEFAULT '',
|
||||
`uid` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE user
|
||||
|
@ -1027,10 +1052,10 @@ CREATE TABLE IF NOT EXISTS `user` (
|
|||
`default-location` varchar(255) NOT NULL DEFAULT '',
|
||||
`allow_location` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`theme` varchar(255) NOT NULL DEFAULT '',
|
||||
`pubkey` text NOT NULL,
|
||||
`prvkey` text NOT NULL,
|
||||
`spubkey` text NOT NULL,
|
||||
`sprvkey` text NOT NULL,
|
||||
`pubkey` text,
|
||||
`prvkey` text,
|
||||
`spubkey` text,
|
||||
`sprvkey` text,
|
||||
`verified` tinyint(1) unsigned NOT NULL DEFAULT 0,
|
||||
`blocked` tinyint(1) unsigned NOT NULL DEFAULT 0,
|
||||
`blockwall` tinyint(1) unsigned NOT NULL DEFAULT 0,
|
||||
|
@ -1040,6 +1065,7 @@ CREATE TABLE IF NOT EXISTS `user` (
|
|||
`cntunkmail` int(11) NOT NULL DEFAULT 10,
|
||||
`notify-flags` int(11) unsigned NOT NULL DEFAULT 65535,
|
||||
`page-flags` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`account-type` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`prvnets` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`pwdreset` varchar(255) NOT NULL DEFAULT '',
|
||||
`maxreq` int(11) NOT NULL DEFAULT 10,
|
||||
|
@ -1050,14 +1076,14 @@ CREATE TABLE IF NOT EXISTS `user` (
|
|||
`expire_notification_sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`service_class` varchar(32) NOT NULL DEFAULT '',
|
||||
`def_gid` int(11) NOT NULL DEFAULT 0,
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
`deny_gid` mediumtext NOT NULL,
|
||||
`openidserver` text NOT NULL,
|
||||
`allow_cid` mediumtext,
|
||||
`allow_gid` mediumtext,
|
||||
`deny_cid` mediumtext,
|
||||
`deny_gid` mediumtext,
|
||||
`openidserver` text,
|
||||
PRIMARY KEY(`uid`),
|
||||
INDEX `nickname` (`nickname`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE userd
|
||||
|
@ -1067,19 +1093,19 @@ CREATE TABLE IF NOT EXISTS `userd` (
|
|||
`username` varchar(255) NOT NULL,
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `username` (`username`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- TABLE workerqueue
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `workerqueue` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`parameter` text NOT NULL,
|
||||
`parameter` text,
|
||||
`priority` tinyint(3) unsigned NOT NULL DEFAULT 0,
|
||||
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`pid` int(11) NOT NULL DEFAULT 0,
|
||||
`executed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY(`id`),
|
||||
INDEX `created` (`created`)
|
||||
) DEFAULT CHARSET=utf8;
|
||||
) DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
|
718
doc/BBCode.md
718
doc/BBCode.md
|
@ -1,181 +1,552 @@
|
|||
Friendica BBCode tags reference
|
||||
========================
|
||||
|
||||
* [Home](help)
|
||||
* [Creating posts](help/Text_editor)
|
||||
|
||||
Inline
|
||||
-----
|
||||
## Inline
|
||||
|
||||
<style>
|
||||
table.bbcodes {
|
||||
margin: 1em 0;
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #aaa;
|
||||
border-collapse: collapse;
|
||||
color: #000;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
<pre>[b]bold[/b]</pre> : <strong>bold</strong>
|
||||
table.bbcodes > tr > th,
|
||||
table.bbcodes > tr > td,
|
||||
table.bbcodes > * > tr > th,
|
||||
table.bbcodes > * > tr > td {
|
||||
border: 1px solid #aaa;
|
||||
padding: 0.2em 0.4em
|
||||
}
|
||||
|
||||
<pre>[i]italic[/i]</pre> : <em>italic</em>
|
||||
table.bbcodes > tr > th,
|
||||
table.bbcodes > * > tr > th {
|
||||
background-color: #f2f2f2;
|
||||
text-align: center;
|
||||
width: 50%
|
||||
}
|
||||
</style>
|
||||
|
||||
<pre>[u]underlined[/u]</pre> : <u>underlined</u>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[b]bold[/b]</td>
|
||||
<td><strong>bold</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[i]italic[/i]</td>
|
||||
<td><em>italic</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[u]underlined[/u]</td>
|
||||
<td><u>underlined</u></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[s]strike[/s]</td>
|
||||
<td><strike>strike</strike></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[o]overline[/o]</td>
|
||||
<td><span class="overline">overline</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[color=red]red[/color]</td>
|
||||
<td><span style="color: red;">red</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=http://www.friendica.com]Friendica[/url]</td>
|
||||
<td><a href="http://www.friendica.com" target="external-link">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</td>
|
||||
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=64x32]http://friendica.com/sites/default/files/friendika-32.png[/img]<br>
|
||||
<br>Note: provided height is simply discarded.</td>
|
||||
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" style="width: 64px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-small]small text[/size]</td>
|
||||
<td><span style="font-size: xx-small;">small text</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-large]big text[/size]</td>
|
||||
<td><span style="font-size: xx-large;">big text</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=20]exact size[/size] (size can be any number, in pixel)</td>
|
||||
<td><span style="font-size: 20px;">exact size</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[font=serif]Serif font[/font]</td>
|
||||
<td><span style="font-family: serif;">Serif font</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[s]strike[/s]</pre> : <strike>strike</strike>
|
||||
### Links
|
||||
|
||||
<pre>[color=red]red[/color]</pre> : <span style="color: red;">red</span>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url]http://friendica.com[/url]</td>
|
||||
<td><a href="http://friendica.com">http://friendica.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=http://friendica.com]Friendica[/url]</td>
|
||||
<td><a href="http://friendica.com">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[bookmark]http://friendica.com[/bookmark]<br><br>
|
||||
#^[url]http://friendica.com[/url]</td>
|
||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">http://friendica.com</a></h4></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[bookmark=http://friendica.com]Bookmark[/bookmark]<br><br>
|
||||
#^[url=http://friendica.com]Bookmark[/url]<br><br>
|
||||
#[url=http://friendica.com]^[/url][url=http://friendica.com]Bookmark[/url]</td>
|
||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">Bookmark</a></h4></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url]</td>
|
||||
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank">Diaspora post with GUID</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#Friendica</td>
|
||||
<td>#<a href="/search?tag=Friendica">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>@Mention</td>
|
||||
<td>@<a href="javascript:void(0)">Mention</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>acct:account@friendica.host.com (WebFinger)</td>
|
||||
<td><a href="/acctlink?addr=account@friendica.host.com" target="extlink">acct:account@friendica.host.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[mail]user@mail.example.com[/mail]</td>
|
||||
<td><a href="mailto:user@mail.example.com">user@mail.example.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[mail=user@mail.example.com]Send an email to User[/mail]</td>
|
||||
<td><a href="mailto:user@mail.example.com">Send an email to User</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[url=http://www.friendica.com]Friendica[/url]</pre> : <a href="http://www.friendica.com" target="external-link">Friendica</a>
|
||||
## Blocks
|
||||
|
||||
<pre>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</pre> : <img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto">
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[p]A paragraph of text[/p]</td>
|
||||
<td><p>A paragraph of text</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Inline [code]code[/code] in a paragraph</td>
|
||||
<td>Inline <key>code</key> in a paragraph</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[code]Multi<br>line<br>code[/code]</td>
|
||||
<td><code>Multi
|
||||
line
|
||||
code</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[code=php]function text_highlight($s,$lang)[/code]</td>
|
||||
<td><code><div class="hl-main"><ol class="hl-main"><li><span class="hl-code"> </span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">text_highlight</span><span class="hl-brackets">(</span><span class="hl-var">$s</span><span class="hl-code">,</span><span class="hl-var">$lang</span><span class="hl-brackets">)</span></li></ol></div></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[quote]quote[/quote]</td>
|
||||
<td><blockquote>quote</blockquote></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[quote=Author]Author? Me? No, no, no...[/quote]</td>
|
||||
<td><strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[center]Centered text[/center]</td>
|
||||
<td><div style="text-align:center;">Centered text</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]</td>
|
||||
<td>
|
||||
<div class="wall-item-container">
|
||||
You should not read any further if you want to be surprised.<br>
|
||||
<span id="spoiler-wrap-0716e642" class="spoiler-wrap fakelink" onclick="openClose('spoiler-0716e642');">Click to open/close</span>
|
||||
<blockquote class="spoiler" id="spoiler-0716e642" style="display: none;">There is a happy end.</blockquote>
|
||||
<div class="body-attach"><div class="clear"></div></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[spoiler=Author]Spoiler quote[/spoiler]</td>
|
||||
<td>
|
||||
<div class="wall-item-container">
|
||||
<strong class="spoiler">Author wrote:</strong><br>
|
||||
<span id="spoiler-wrap-a893765a" class="spoiler-wrap fakelink" onclick="openClose('spoiler-a893765a');">Click to open/close</span>
|
||||
<blockquote class="spoiler" id="spoiler-a893765a" style="display: none;">Spoiler quote</blockquote>
|
||||
<div class="body-attach"><div class="clear"></div></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[hr] (horizontal line)</td>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[size=xx-small]small text[/size]</pre> : <span style="font-size: xx-small;">small text</span>
|
||||
### Titles
|
||||
|
||||
<pre>[size=xx-large]big text[/size]</pre> : <span style="font-size: xx-large;">big text</span>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h1]Title 1[/h1]</td>
|
||||
<td><h1>Title 1</h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h2]Title 2[/h2]</td>
|
||||
<td><h2>Title 2</h2></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h3]Title 3[/h3]</td>
|
||||
<td><h3>Title 3</h3></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h4]Title 4[/h4]</td>
|
||||
<td><h4>Title 4</h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h5]Title 5[/h5]</td>
|
||||
<td><h5>Title 5</h5></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h6]Title 6[/h6]</td>
|
||||
<td><h6>Title 6</h6></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[size=20]exact size[/size] (size can be any number, in pixel)</pre> : <span style="font-size: 20px;">exact size</span>
|
||||
### Tables
|
||||
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table]<br>
|
||||
[tr]<br>
|
||||
[th]Header 1[/th]<br>
|
||||
[th]Header 2[/th]<br>
|
||||
[th]Header 2[/th]<br>
|
||||
[/tr]<br>
|
||||
[tr]<br>
|
||||
[td]Cell 1[/td]<br>
|
||||
[td]Cell 2[/td]<br>
|
||||
[td]Cell 3[/td]<br>
|
||||
[/tr]<br>
|
||||
[tr]<br>
|
||||
[td]Cell 4[/td]<br>
|
||||
[td]Cell 5[/td]<br>
|
||||
[td]Cell 6[/td]<br>
|
||||
[/tr]<br>
|
||||
[/table]</td>
|
||||
<td>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Header 1</th>
|
||||
<th>Header 2</th>
|
||||
<th>Header 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
<td>Cell 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 4</td>
|
||||
<td>Cell 5</td>
|
||||
<td>Cell 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table border=0]</td>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Header 1</th>
|
||||
<th>Header 2</th>
|
||||
<th>Header 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
<td>Cell 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 4</td>
|
||||
<td>Cell 5</td>
|
||||
<td>Cell 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table border=1]</td>
|
||||
<td>
|
||||
<table border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Header 1</th>
|
||||
<th>Header 2</th>
|
||||
<th>Header 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
<td>Cell 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 4</td>
|
||||
<td>Cell 5</td>
|
||||
<td>Cell 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Lists
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Block
|
||||
-----
|
||||
|
||||
<pre>[code]code[/code]</pre>
|
||||
|
||||
<code>code</code>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[quote]quote[/quote]</pre>
|
||||
|
||||
<blockquote>quote</blockquote>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[quote=Author]Author? Me? No, no, no...[/quote]</pre>
|
||||
|
||||
<strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[center]centered text[/center]</pre>
|
||||
|
||||
<div style="text-align:center;">centered text</div>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]</pre>
|
||||
|
||||
You should not read any further if you want to be surprised.<br />*click to open/close*
|
||||
|
||||
(The text between thhe opening and the closing of the spoiler tag will be visible once the link is clicked. So *"There is a happy end."* wont be visible until the spoiler is uncovered.)
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
**Table**
|
||||
<pre>[table border=1]
|
||||
[tr]
|
||||
[th]Tables now[/th]
|
||||
[/tr]
|
||||
[tr]
|
||||
[td]Have headers[/td]
|
||||
[/tr]
|
||||
[/table]</pre>
|
||||
|
||||
<table border="1"><tbody><tr><th>Tables now</th></tr><tr><td>Have headers</td></tr></tbody></table>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
**List**
|
||||
|
||||
<pre>[list]
|
||||
[*] First list element
|
||||
[*] Second list element
|
||||
[/list]</pre>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[ul]<br>
|
||||
[li] First list element<br>
|
||||
[li] Second list element<br>
|
||||
[/ul]<br>
|
||||
[list]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listbullet" style="list-style-type: circle;">
|
||||
<li> First list element<br>
|
||||
</li>
|
||||
<li>First list element</li>
|
||||
<li>Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[ol]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/ol]<br>
|
||||
[list=1]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listdecimal" style="list-style-type: decimal;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listnone" style="list-style-type: none;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=i]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listlowerroman" style="list-style-type: lower-roman;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=I]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listupperroman" style="list-style-type: upper-roman;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=a]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listloweralpha" style="list-style-type: lower-alpha;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=A]<br>
|
||||
[*] First list element<br>
|
||||
[*] Second list element<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listupperalpha" style="list-style-type: upper-alpha;">
|
||||
<li> First list element</li>
|
||||
<li> Second list element</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[list] is equivalent to [ul] (unordered list).
|
||||
|
||||
[ol] can be used instead of [list] to show an ordered list:
|
||||
|
||||
<pre>[ol]
|
||||
[*] First list element
|
||||
[*] Second list element
|
||||
[/ol]</pre>
|
||||
<ul class="listdecimal" style="list-style-type: decimal;"><li> First list element<br></li><li> Second list element</li></ul>
|
||||
|
||||
For more options on ordered lists, you can define the style of numeration on [list] argument:
|
||||
<pre>[list=1]</pre> : decimal
|
||||
|
||||
<pre>[list=i]</pre> : lover case roman
|
||||
|
||||
<pre>[list=I]</pre> : upper case roman
|
||||
|
||||
<pre>[list=a]</pre> : lover case alphabetic
|
||||
|
||||
<pre>[list=A] </pre> : upper case alphabetic
|
||||
|
||||
|
||||
|
||||
|
||||
Embed
|
||||
------
|
||||
## Embed
|
||||
|
||||
You can embed video, audio and more in a message.
|
||||
|
||||
<pre>[video]url[/video]</pre>
|
||||
<pre>[audio]url[/audio]</pre>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[video]url[/video]</td>
|
||||
<td>Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[video]Video file url[/video]
|
||||
[audio]Audio file url[/audio]</td>
|
||||
<td>Full URL to an ogg/ogv/oga/ogm/webm/mp4/mp3 file. An HTML5 player will be used to show it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[youtube]Youtube URL[/youtube]</td>
|
||||
<td>Youtube video OEmbed display. May not embed an actual player.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[youtube]Youtube video ID[/youtube]</td>
|
||||
<td>Youtube player iframe embed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[vimeo]Vimeo URL[/vimeo]</td>
|
||||
<td>Vimeo video OEmbed display. May not embed an actual player.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[vimeo]Vimeo video ID[/vimeo]</td>
|
||||
<td>Vimeo player iframe embed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[iframe]URL[/iframe]</td>
|
||||
<td>General embed, iframe size is limited by the theme size for video players.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url]*url*[/url]</td>
|
||||
<td>If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd).
|
||||
Page title with a link to *url* will be shown.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications.
|
||||
*url* can be also full url to an ogg file. HTML5 tag will be used to show it.
|
||||
## Map
|
||||
|
||||
<pre>[url]*url*[/url]</pre>
|
||||
This require "openstreetmap" or "Google Maps" addon version 1.3 or newer.
|
||||
If the addon isn't activated, the raw coordinates are shown instead.
|
||||
|
||||
If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd).
|
||||
Page title with a link to *url* will be shown.
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map]address[/map]</td>
|
||||
<td>Embeds a map centered on this address.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map=lat,long]</td>
|
||||
<td>Embeds a map centered on those coordinates.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map]</td>
|
||||
<td>Embeds a map centered on the post's location.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Map
|
||||
---
|
||||
## Abstract for longer posts
|
||||
|
||||
<pre>[map]address[/map]</pre>
|
||||
<pre>[map=lat,long]</pre>
|
||||
|
||||
You can embed maps from coordinates or addresses.
|
||||
This require "openstreetmap" addon version 1.3 or newer.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Abstract for longer posts
|
||||
-------------------------
|
||||
|
||||
If you want to spread your post to several third party networks you can have the problem that these networks have (for example) a length limitation.
|
||||
(Like on Twitter)
|
||||
If you want to spread your post to several third party networks you can have the problem that these networks have a length limitation like on Twitter.
|
||||
|
||||
Friendica is using a semi intelligent mechanism to generate a fitting abstract.
|
||||
But it can be interesting to define an own abstract that will only be displayed on the external network.
|
||||
But it can be interesting to define a custom abstract that will only be displayed on the external network.
|
||||
This is done with the [abstract]-element.
|
||||
Example:
|
||||
|
||||
<pre>[abstract]Totally interesting! A must-see! Please click the link![/abstract]
|
||||
I want to tell you a really boring story that you really never wanted
|
||||
to hear.</pre>
|
||||
|
||||
Twitter would display the text "Totally interesting! A must-see! Please click the link!".
|
||||
On Friendica you would only see the text after "I want to tell you a really ..."
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[abstract]Totally interesting! A must-see! Please click the link![/abstract]<br>
|
||||
I want to tell you a really boring story that you really never wanted to hear.</td>
|
||||
<td>Twitter would display the text <blockquote>Totally interesting! A must-see! Please click the link!</blockquote>
|
||||
On Friendica you would only see the text after <blockquote>I want to tell you a really ...</blockquote></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
It is even possible to define abstracts for separate networks:
|
||||
|
||||
<pre>
|
||||
[abstract]Hi friends Here are my newest pictures![abstract]
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[abstract]Hi friends Here are my newest pictures![/abstract]<br>
|
||||
[abstract=twit]Hi my dear Twitter followers. Do you want to see my new
|
||||
pictures?[abstract]
|
||||
pictures?[/abstract]<br>
|
||||
[abstract=apdn]Helly my dear followers on ADN. I made sone new pictures
|
||||
that I wanted to share with you.[abstract]
|
||||
Today I was in the woods and took some real cool pictures ...
|
||||
</pre>
|
||||
|
||||
For Twitter and App.net the system will use the defined abstracts.
|
||||
For other networks (e.g. when you are using the "statusnet" connector that is used to post to GNU Social) the general abstract element will be used.
|
||||
that I wanted to share with you.[/abstract]<br>
|
||||
Today I was in the woods and took some real cool pictures ...</td>
|
||||
<td>For Twitter and App.net the system will use the defined abstracts.<br>
|
||||
For other networks (e.g. when you are using the "statusnet" connector that is used to post to your GNU Social account) the general abstract element will be used.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you use (for example) the "buffer" connector to post to Facebook or Google+ you can use this element to define an abstract for a longer blogpost that you don't want to post completely to these networks.
|
||||
|
||||
|
@ -183,20 +554,59 @@ Networks like Facebook or Google+ aren't length limited.
|
|||
For this reason the [abstract] element isn't used.
|
||||
Instead you have to name the explicit network:
|
||||
|
||||
<pre>
|
||||
[abstract]These days I had a strange encounter ...[abstract]
|
||||
[abstract=goog]Helly my dear Google+ followers. You have to read my
|
||||
newest blog post![abstract]
|
||||
[abstract=face]Hello my Facebook friends. These days happened something
|
||||
really cool.[abstract]
|
||||
While taking pictures in the woods I had a really strange encounter ... </pre>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[abstract]These days I had a strange encounter...[/abstract]<br>
|
||||
[abstract=goog]Helly my dear Google+ followers. You have to read my newest blog post![/abstract]<br>
|
||||
[abstract=face]Hello my Facebook friends. These days happened something really cool.[/abstract]<br>
|
||||
While taking pictures in the woods I had a really strange encounter...</td>
|
||||
<td>Google and Facebook will show the respective abstracts while the other networks will show the default one.<br>
|
||||
<br>Meanwhile, Friendica won't show any of the abstracts.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The [abstract] element isn't working with the native OStatus connection or with connectors where we post the HTML.
|
||||
(Like Tumblr, Wordpress or Pump.io)
|
||||
The [abstract] element isn't working with connectors where we post the HTML like Tumblr, Wordpress or Pump.io.
|
||||
For the native connections--that is to e.g. Friendica, Hubzilla, Diaspora or GNU Social--the full posting is used and the contacts instance will display the posting as desired.
|
||||
|
||||
Special
|
||||
-------
|
||||
## Special
|
||||
|
||||
If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
|
||||
|
||||
<pre>[noparse][b]bold[/b][/noparse]</pre> : [b]bold[/b]
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
|
||||
<ul>
|
||||
<li>[noparse][b]bold[/b][/noparse]</li>
|
||||
<li>[nobb][b]bold[/b][/nobb]</li>
|
||||
<li>[pre][b]bold[/b][/pre]</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>[b]bold[/b]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[nosmile] is used to disable smilies on a post by post basis<br>
|
||||
<br>
|
||||
[nosmile] ;-) :-O
|
||||
</td>
|
||||
<td>;-) :-O</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Custom inline styles<br>
|
||||
<br>
|
||||
[style=text-shadow: 0 0 4px #CC0000;]You can change all the CSS properties of this block.[/style]</td>
|
||||
<td><span style="text-shadow: 0 0 4px #cc0000;;">You can change all the CSS properties of this block.</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Custom class block<br>
|
||||
<br>
|
||||
[class=custom]If the class exists, this block will have the custom class style applied.[/class]</td>
|
||||
<td><pre><span class="custom">If the class exists,<br> this block will have the custom class<br> style applied.</span></pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -16,7 +16,7 @@ Contact us
|
|||
|
||||
The discussion of Friendica development takes place in the following Friendica forums:
|
||||
|
||||
* The main [forum for Friendica development](https://friendika.openmindspace.org/profile/friendicadevelopers)
|
||||
* The main [forum for Friendica development](https://helpers.pyxis.uberspace.de/profile/developers)
|
||||
* The [forum for Friendica theme development](https://friendica.eu/profile/ftdevs)
|
||||
|
||||
Help other users
|
||||
|
@ -79,7 +79,7 @@ If you want to get involved here:
|
|||
* Look at the first steps that were made (e.g. the clean theme).
|
||||
Ask us to find out whom to talk to about their experiences.
|
||||
* Talk to design people if you know any.
|
||||
* Let us know about your plans [in the dev forum](https://friendika.openmindspace.org/profile/friendicadevelopers) and the [theme developer forum](https://friendica.eu/profile/ftdevs).
|
||||
* Let us know about your plans [in the dev forum](https://helpers.pyxis.uberspace.de/profile/developers) and the [theme developer forum](https://friendica.eu/profile/ftdevs).
|
||||
Do not worry about cross-posting.
|
||||
|
||||
###Client software
|
||||
|
|
|
@ -28,7 +28,7 @@ Friendica Documentation and Resources
|
|||
**Admin Manual**
|
||||
|
||||
* [Install](help/Install)
|
||||
* [Settings](help/Settings)
|
||||
* [Settings & Admin Panel](help/Settings)
|
||||
* [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors)
|
||||
* [Install an ejabberd server (XMPP chat) with synchronized credentials](help/install-ejabberd)
|
||||
* [Message Flow](help/Message-Flow)
|
||||
|
|
|
@ -10,7 +10,7 @@ Not every PHP/MySQL hosting provider will be able to support Friendica.
|
|||
Many will.
|
||||
But **please** review the requirements and confirm these with your hosting provider prior to installation.
|
||||
|
||||
Also if you encounter installation issues, please let us know via the [helper](http://helpers.pyxis.uberspace.de/profile/helpers) or the [developer](https://friendika.openmindspace.org/profile/friendicadevelopers) forum or [file an issue](https://github.com/friendica/friendica/issues).
|
||||
Also if you encounter installation issues, please let us know via the [helper](http://helpers.pyxis.uberspace.de/profile/helpers) or the [developer](https://helpers.pyxis.uberspace.de/profile/developers) forum or [file an issue](https://github.com/friendica/friendica/issues).
|
||||
Please be as clear as you can about your operating environment and provide as much detail as possible about any error messages you may see, so that we can prevent it from happening in the future.
|
||||
Due to the large variety of operating systems and PHP platforms in existence we may have only limited ability to debug your PHP installation or acquire any missing modules - but we will do our best to solve any general code issues.
|
||||
If you do not have a Friendica account yet, you can register a temporary one at [tryfriendica.de](https://tryfriendica.de) and join the forums mentioned above from there.
|
||||
|
@ -26,12 +26,12 @@ Requirements
|
|||
---
|
||||
|
||||
* Apache with mod-rewrite enabled and "Options All" so you can use a local .htaccess file
|
||||
* PHP 5.2+. The later the better. You'll need 5.3 for encryption of key exchange conversations. On a Windows environment, 5.2+ might not work as the function dns_get_record() is only available with version 5.3.
|
||||
* PHP 5.4+.
|
||||
* PHP *command line* access with register_argc_argv set to true in the php.ini file
|
||||
* curl, gd, mysql, hash and openssl extensions
|
||||
* some form of email server or email gateway such that PHP mail() works
|
||||
* mcrypt (optional; used for server-to-server message encryption)
|
||||
* Mysql 5.x or an equivalant alternative for MySQL (MariaDB etc.)
|
||||
* Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
|
||||
* the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.)
|
||||
* Installation into a top-level domain or sub-domain (without a directory/path component in the URL) is preferred. Directory paths will not be as convenient to use and have not been thoroughly tested.
|
||||
* If your hosting provider doesn't allow Unix shell access, you might have trouble getting everything to work.
|
||||
|
|
|
@ -9,7 +9,8 @@ This number should decrease quickly.
|
|||
The second is the messages which could for various reasons not being delivered.
|
||||
They will be resend later.
|
||||
You can have a quick glance into that second queus in the "Inspect Queue" section of the admin panel.
|
||||
If you have activated the background workers, there might be a third number representing the count of jobs queued for the workers.
|
||||
If you have activated the background workers, there is a third number representing the count of jobs queued for the workers.
|
||||
These worker tasks are prioritised and are done accordingly.
|
||||
|
||||
Then you get an overview of the accounts on your node, which can be moderated in the "Users" section of the panel.
|
||||
As well as an overview of the currently active addons
|
||||
|
|
96
doc/api.md
96
doc/api.md
|
@ -104,6 +104,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original
|
|||
* max_id: maximum id
|
||||
* getText: Defines the format of the status field. Can be "html" or "plain"
|
||||
* include_entities: "true" shows entities for pictures and links (Default: false)
|
||||
* friendica_verbose: "true" enables different error returns (default: "false")
|
||||
|
||||
#### Unsupported parameters
|
||||
* skip_status
|
||||
|
@ -116,6 +117,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original
|
|||
* since_id: minimal id
|
||||
* max_id: maximum id
|
||||
* getText: Defines the format of the status field. Can be "html" or "plain"
|
||||
* friendica_verbose: "true" enables different error returns (default: "false")
|
||||
|
||||
---
|
||||
### direct_messages/conversation (*; AUTH)
|
||||
|
@ -127,6 +129,18 @@ Shows all direct messages of a conversation
|
|||
* max_id: maximum id
|
||||
* getText: Defines the format of the status field. Can be "html" or "plain"
|
||||
* uri: URI of the conversation
|
||||
* friendica_verbose: "true" enables different error returns (default: "false")
|
||||
|
||||
---
|
||||
### direct_messages/sent (*; AUTH)
|
||||
#### Parameters
|
||||
* count: Items per page (default: 20)
|
||||
* page: page number
|
||||
* since_id: minimal id
|
||||
* max_id: maximum id
|
||||
* getText: Defines the format of the status field. Can be "html" or "plain"
|
||||
* include_entities: "true" shows entities for pictures and links (Default: false)
|
||||
* friendica_verbose: "true" enables different error returns (default: "false")
|
||||
|
||||
---
|
||||
### direct_messages/new (POST,PUT; AUTH)
|
||||
|
@ -138,14 +152,22 @@ Shows all direct messages of a conversation
|
|||
* title: Title of the direct message
|
||||
|
||||
---
|
||||
### direct_messages/sent (*; AUTH)
|
||||
### direct_messages/destroy (POST,DELETE; AUTH)
|
||||
#### Parameters
|
||||
* count: Items per page (default: 20)
|
||||
* page: page number
|
||||
* since_id: minimal id
|
||||
* max_id: maximum id
|
||||
* getText: Defines the format of the status field. Can be "html" or "plain"
|
||||
* include_entities: "true" shows entities for pictures and links (Default: false)
|
||||
* id: id of the message to be deleted
|
||||
* include_entities: optional, currently not yet implemented
|
||||
* friendica_parenturi: optional, can be used for increased safety to delete only intended messages
|
||||
* friendica_verbose: "true" enables different error returns (default: "false")
|
||||
|
||||
#### Return values
|
||||
|
||||
On success:
|
||||
* JSON return as defined for Twitter API not yet implemented
|
||||
* on friendica_verbose=true: JSON return {"result":"ok","message":"message deleted"}
|
||||
|
||||
On error:
|
||||
HTTP 400 BadRequest
|
||||
* on friendica_verbose=true: different JSON returns {"result":"error","message":"xyz"}
|
||||
|
||||
---
|
||||
### favorites (*; AUTH)
|
||||
|
@ -694,6 +716,65 @@ xml
|
|||
</photos>
|
||||
```
|
||||
|
||||
---
|
||||
### friendica/direct_messages_setseen (GET; AUTH)
|
||||
#### Parameters
|
||||
* id: id of the message to be updated as seen
|
||||
|
||||
#### Return values
|
||||
|
||||
On success:
|
||||
* JSON return {"result":"ok","message":"message set to seen"}
|
||||
|
||||
On error:
|
||||
* different JSON returns {"result":"error","message":"xyz"}
|
||||
|
||||
---
|
||||
### friendica/direct_messages_search (GET; AUTH)
|
||||
#### Parameters
|
||||
* searchstring: string for which the API call should search as '%searchstring%' in field 'body' of all messages of the authenticated user (caption ignored)
|
||||
|
||||
#### Return values
|
||||
Returns only tested with JSON, XML might work as well.
|
||||
|
||||
On success:
|
||||
* JSON return {"success":"true","search_results": array of found messages}
|
||||
* JSOn return {"success":"false","search_results":"nothing found"}
|
||||
|
||||
On error:
|
||||
* different JSON returns {"result":"error","message":"searchstring not specified"}
|
||||
|
||||
---
|
||||
### friendica/profile/show (GET; AUTH)
|
||||
show data of all profiles or a single profile of the authenticated user
|
||||
|
||||
#### Parameters
|
||||
* profile_id: id of the profile to be returned (optional, if omitted all profiles are returned by default)
|
||||
|
||||
#### Return values
|
||||
On success: Array of:
|
||||
|
||||
* multi_profiles: true if user has activated multi_profiles
|
||||
* global_dir: URL of the global directory set in server settings
|
||||
* friendica_owner: user data of the authenticated user
|
||||
* profiles: array of the profile data
|
||||
|
||||
On error:
|
||||
HTTP 403 Forbidden: when no authentication provided
|
||||
HTTP 400 Bad Request: if given profile_id is not in db or not assigned to authenticated user
|
||||
|
||||
General description of profile data in API returns:
|
||||
* profile_id
|
||||
* profile_name
|
||||
* is_default: true if this is the public profile
|
||||
* hide_friends: true if friends are hidden
|
||||
* profile_photo
|
||||
* profile_thumb
|
||||
* publish: true if published on the server's local directory
|
||||
* net_publish: true if published to global_dir
|
||||
* description ... homepage: different data fields from 'profile' table in database
|
||||
* users: array with the users allowed to view this profile (empty if is_default=true)
|
||||
|
||||
|
||||
---
|
||||
## Not Implemented API calls
|
||||
|
@ -718,7 +799,6 @@ The following API calls from the Twitter API aren't implemented neither in Frien
|
|||
* statuses/lookup
|
||||
* direct_messages/show
|
||||
* search/tweets
|
||||
* direct_messages/destroy
|
||||
* friendships/no_retweets/ids
|
||||
* friendships/incoming
|
||||
* friendships/outgoing
|
||||
|
|
|
@ -4,6 +4,7 @@ Table fcontact
|
|||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| -------- | ------------- | ---------------- | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
|
||||
| guid | unique id | varchar(64) | NO | | | |
|
||||
| url | | varchar(255) | NO | | | |
|
||||
| name | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
|
|
|
@ -24,9 +24,11 @@ Table item
|
|||
| owner-name | Name of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-link | Link to the profile page of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-avatar | Link to the avatar picture of the owner of this item | varchar(255) | NO | | | |
|
||||
| owner-id | Link to the contact table with uid=0 of the owner of this item | int(11) | NO | MUL | 0 | |
|
||||
| author-name | Name of the author of this item | varchar(255) | NO | | | |
|
||||
| author-link | Link to the profile page of the author of this item | varchar(255) | NO | | | |
|
||||
| author-avatar | Link to the avatar picture of the author of this item | varchar(255) | NO | | | |
|
||||
| author-id | Link to the contact table with uid=0 of the author of this item | int(11) | NO | MUL | 0 | |
|
||||
| title | item title | varchar(255) | NO | | | |
|
||||
| body | item body content | mediumtext | NO | | NULL | |
|
||||
| app | application which generated this item | varchar(255) | NO | | | |
|
||||
|
|
|
@ -2,7 +2,7 @@ Table notify
|
|||
============
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
| ------ | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- |
|
||||
| ---------- | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- |
|
||||
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
|
||||
| hash | | varchar(64) | NO | | | |
|
||||
| type | | int(11) | NO | | 0 | |
|
||||
|
@ -10,13 +10,15 @@ Table notify
|
|||
| url | | varchar(255) | NO | | | |
|
||||
| photo | | varchar(255) | NO | | | |
|
||||
| date | | datetime | NO | | 0000-00-00 00:00:00 | |
|
||||
| msg | | mediumtext | NO | | NULL | |
|
||||
| msg | | mediumtext | YES | | NULL | |
|
||||
| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
|
||||
| link | | varchar(255) | NO | | | |
|
||||
| iid | item.id | int(11) | NO | | 0 | |
|
||||
| parent | | int(11) | NO | | 0 | |
|
||||
| seen | | tinyint(1) | NO | | 0 | |
|
||||
| verb | | varchar(255) | NO | | | |
|
||||
| otype | | varchar(16) | NO | | | |
|
||||
| iid | item.id | int(11) | NO | | 0 | |
|
||||
| name_cache | Cached bbcode parsing of name | tinytext | YES | | NULL | |
|
||||
| msg_cache | Cached bbcode parsing of msg | mediumtext | YES | | NULL | |
|
||||
|
||||
Return to [database documentation](help/database)
|
||||
|
|
|
@ -7,6 +7,8 @@ Table thread
|
|||
| uid | | int(10) unsigned | NO | MUL | 0 | |
|
||||
| contact-id | | int(11) unsigned | NO | | 0 | |
|
||||
| gcontact-id | Global Contact | int(11) unsigned | NO | | 0 | |
|
||||
| owner-id | Item owner | int(11) unsigned | NO | MUL | 0 | |
|
||||
| author-id | Item author | int(11) unsigned | NO | MUL | 0 | |
|
||||
| created | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
|
||||
| edited | | datetime | NO | | 0000-00-00 00:00:00 | |
|
||||
| commented | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
|
||||
|
|
729
doc/de/BBCode.md
729
doc/de/BBCode.md
|
@ -3,195 +3,612 @@ Referenz der Friendica BBCode Tags
|
|||
|
||||
* [Zur Startseite der Hilfe](help)
|
||||
|
||||
Inline Tags
|
||||
-----
|
||||
## Inline
|
||||
|
||||
<style>
|
||||
table.bbcodes {
|
||||
margin: 1em 0;
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #aaa;
|
||||
border-collapse: collapse;
|
||||
color: #000;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
<pre>[b]fett[/b]</pre> : <strong>fett</strong>
|
||||
table.bbcodes > tr > th,
|
||||
table.bbcodes > tr > td,
|
||||
table.bbcodes > * > tr > th,
|
||||
table.bbcodes > * > tr > td {
|
||||
border: 1px solid #aaa;
|
||||
padding: 0.2em 0.4em
|
||||
}
|
||||
|
||||
<pre>[i]kursiv[/i]</pre> : <em>kursiv</em>
|
||||
table.bbcodes > tr > th,
|
||||
table.bbcodes > * > tr > th {
|
||||
background-color: #f2f2f2;
|
||||
text-align: center;
|
||||
width: 50%
|
||||
}
|
||||
</style>
|
||||
|
||||
<pre>[u]unterstrichen[/u]</pre> : <u>unterstrichen</u>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[b]fett[/b]</td>
|
||||
<td><strong>fett</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[i]kursiv[/i]</td>
|
||||
<td><em>kursiv</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[u]unterstrichen[/u]</td>
|
||||
<td><u>unterstrichen</u></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[s]durchgestrichen[/s]</td>
|
||||
<td><strike>durchgestrichen</strike></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[o]überstrichen[/o]</td>
|
||||
<td><span class="overline">überstrichen</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[color=red]rot[/color]</td>
|
||||
<td><span style="color: red;">rot</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=http://www.friendica.com]Friendica[/url]</td>
|
||||
<td><a href="http://www.friendica.com" target="external-link">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</td>
|
||||
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[img=64x32]http://friendica.com/sites/default/files/friendika-32.png[/img]<br>
|
||||
<br>Note: provided height is simply discarded.</td>
|
||||
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" style="width: 64px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-small]kleiner Text[/size]</td>
|
||||
<td><span style="font-size: xx-small;">kleiner Text</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=xx-large]großer Text[/size]</td>
|
||||
<td><span style="font-size: xx-large;">großer Text</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[size=20]exakte Größe[/size] (die Größe kann beliebig in Pixeln gewält werden)</td>
|
||||
<td><span style="font-size: 20px;">exakte Größe</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[font=serif]Serife Schriftart[/font]</td>
|
||||
<td><span style="font-family: serif;">Serife Schriftart</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[s]durchgestrichen[/s]</pre> : <strike>durchgestrichen</strike>
|
||||
### Links
|
||||
|
||||
<pre>[color=red]rot[/color]</pre> : <span style="color: red;">rot</span>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url]http://friendica.com[/url]</td>
|
||||
<td><a href="http://friendica.com">http://friendica.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=http://friendica.com]Friendica[/url]</td>
|
||||
<td><a href="http://friendica.com">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[bookmark]http://friendica.com[/bookmark]<br><br>
|
||||
#^[url]http://friendica.com[/url]</td>
|
||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">http://friendica.com</a></h4></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[bookmark=http://friendica.com]Lesezeichen[/bookmark]<br><br>
|
||||
#^[url=http://friendica.com]Lesezeichen[/url]<br><br>
|
||||
#[url=http://friendica.com]^[/url][url=http://friendica.com]Lesezeichen[/url]</td>
|
||||
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">Lesezeichen</a></h4></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora Beitrag mit GUID[/url]</td>
|
||||
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank">Diaspora Beitrag mit GUID</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#Friendica</td>
|
||||
<td>#<a href="/search?tag=Friendica">Friendica</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>@Erwähnung</td>
|
||||
<td>@<a href="javascript:void(0)">Erwähnung</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>acct:account@friendica.host.com (WebFinger)</td>
|
||||
<td><a href="/acctlink?addr=account@friendica.host.com" target="extlink">acct:account@friendica.host.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[mail]user@mail.example.com[/mail]</td>
|
||||
<td><a href="mailto:user@mail.example.com">user@mail.example.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[mail=user@mail.example.com]Eine E-Mail senden[/mail]</td>
|
||||
<td><a href="mailto:user@mail.example.com">Eine E-Mail senden</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[url=http://www.friendica.com]Friendica[/url]</pre> : <a href="http://www.friendica.com" target="external-link">Friendica</a>
|
||||
## Blocks
|
||||
|
||||
<pre>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</pre> : <img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto">
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[p]Ein Absatz mit Text[/p]</td>
|
||||
<td><p>Ein Absatz mit Text</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eingebetteter [code]Programmcode[/code] im Text</td>
|
||||
<td>Eingebetteter <key>Programmcode</key> im Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[code]Programmcode<br>über<br>mehrere<br>Zeilen[/code]</td>
|
||||
<td><code>Programmcode
|
||||
über
|
||||
mehrere
|
||||
Zeilen</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[code=php]function text_highlight($s,$lang)[/code]</td>
|
||||
<td><code><div class="hl-main"><ol class="hl-main"><li><span class="hl-code"> </span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">text_highlight</span><span class="hl-brackets">(</span><span class="hl-var">$s</span><span class="hl-code">,</span><span class="hl-var">$lang</span><span class="hl-brackets">)</span></li></ol></div></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[quote]Zitat[/quote]</td>
|
||||
<td><blockquote>Zitat</blockquote></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[quote=Autor]Autor? Ich? Nein, niemals...[/quote]</td>
|
||||
<td><strong class="Autor">Autor hat geschrieben:</strong><blockquote>Autor? Ich? Nein, niemals...</blockquote></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[center]zentrierter Text[/center]</td>
|
||||
<td><div style="text-align:center;">zentrierter Text</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Du solltest nicht weiter lesen, wenn du das Ende des Films nicht vorher erfahren willst. [spoiler]Es gibt ein Happy End.[/spoiler]</td>
|
||||
<td>
|
||||
<div class="wall-item-container">
|
||||
Du solltest nicht weiter lesen, wenn du das Ende des Films nicht vorher erfahren willst. <br>
|
||||
<span id="spoiler-wrap-0716e642" class="spoiler-wrap fakelink" onclick="openClose('spoiler-0716e642');">Zum öffnen/schließen klicken</span>
|
||||
<blockquote class="spoiler" id="spoiler-0716e642" style="display: none;">Es gibt ein Happy End.</blockquote>
|
||||
<div class="body-attach"><div class="clear"></div></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[spoiler=Autor]Spoiler Alarm[/spoiler]</td>
|
||||
<td>
|
||||
<div class="wall-item-container">
|
||||
<strong class="spoiler">Autor hat geschrieben</strong><br>
|
||||
<span id="spoiler-wrap-a893765a" class="spoiler-wrap fakelink" onclick="openClose('spoiler-a893765a');">Zum öffnen/schließen klicken</span>
|
||||
<blockquote class="spoiler" id="spoiler-a893765a" style="display: none;">Spoiler Alarm</blockquote>
|
||||
<div class="body-attach"><div class="clear"></div></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[hr] (horizontale Linie)</td>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[size=xx-small]kleiner Text[/size]</pre> : <span style="font-size: xx-small;">kleiner Text</span>
|
||||
### Überschriften
|
||||
|
||||
<pre>[size=xx-large]groß Text[/size]</pre> : <span style="font-size: xx-large;">großer Text</span>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h1]Titel 1[/h1]</td>
|
||||
<td><h1>Titel 1</h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h2]Titel 2[/h2]</td>
|
||||
<td><h2>Titel 2</h2></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h3]Titel 3[/h3]</td>
|
||||
<td><h3>Titel 3</h3></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h4]Titel 4[/h4]</td>
|
||||
<td><h4>Titel 4</h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h5]Titel 5[/h5]</td>
|
||||
<td><h5>Titel 5</h5></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[h6]Titel 6[/h6]</td>
|
||||
<td><h6>Titel 6</h6></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[size=20]exakte Textgröße[/size] (Textgröße kann jede Zahl sein, in Pixeln)</pre> : <span style="font-size: 20px;">exakte Größe</span>
|
||||
### Tabellen
|
||||
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table]<br>
|
||||
[tr]<br>
|
||||
[th]Kopfzeile 1[/th]<br>
|
||||
[th]Kopfzeile 2[/th]<br>
|
||||
[th]Kopfzeile 2[/th]<br>
|
||||
[/tr]<br>
|
||||
[tr]<br>
|
||||
[td]Zelle 1[/td]<br>
|
||||
[td]Zelle 2[/td]<br>
|
||||
[td]Zelle 3[/td]<br>
|
||||
[/tr]<br>
|
||||
[tr]<br>
|
||||
[td]Zelle 4[/td]<br>
|
||||
[td]Zelle 5[/td]<br>
|
||||
[td]Zelle 6[/td]<br>
|
||||
[/tr]<br>
|
||||
[/table]</td>
|
||||
<td>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Kopfzeile 1</th>
|
||||
<th>Kopfzeile 2</th>
|
||||
<th>Kopfzeile 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 1</td>
|
||||
<td>Zelle 2</td>
|
||||
<td>Zelle 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 4</td>
|
||||
<td>Zelle 5</td>
|
||||
<td>Zelle 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table border=0]</td>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Kopfzeile 1</th>
|
||||
<th>Kopfzeile 2</th>
|
||||
<th>Kopfzeile 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 1</td>
|
||||
<td>Zelle 2</td>
|
||||
<td>Zelle 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 4</td>
|
||||
<td>Zelle 5</td>
|
||||
<td>Zelle 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[table border=1]</td>
|
||||
<td>
|
||||
<table border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Kopfzeile 1</th>
|
||||
<th>Kopfzeile 2</th>
|
||||
<th>Kopfzeile 3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 1</td>
|
||||
<td>Zelle 2</td>
|
||||
<td>Zelle 3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zelle 4</td>
|
||||
<td>Zelle 5</td>
|
||||
<td>Zelle 6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Listen
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Block Tags
|
||||
-----
|
||||
|
||||
<pre>[code]Code[/code]</pre>
|
||||
|
||||
<code>Code</code>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[quote]Zitat[/quote]</pre>
|
||||
|
||||
<blockquote>Zitat</blockquote>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[quote=Autor]Der Autor? Ich? Nein, nein, nein...[/quote]</pre>
|
||||
|
||||
<strong class="author">Autor hat geschrieben:</strong><blockquote>Der Autor? Ich? Nein, nein, nein...</blockquote>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>[center]zentrierter Text[/center]</pre>
|
||||
|
||||
<div style="text-align:center;">zentrierter Text</div>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
<pre>Wer überrascht werden möchte sollte nicht weiter lesen.[spoiler]Es gibt ein Happy End.[/spoiler]</pre>
|
||||
|
||||
Wer überrascht werden möchte sollte nicht weiter lesen.<br />*klicken zum öffnen/schließen*
|
||||
|
||||
(Der Text zweischen dem öffnenden und dem schließenden Teil des spoiler Tags wird nicht angezeigt, bis der Link angeklickt wurde. In dem Fall wird *"Es gibt ein Happy End."* also erst angezeigt, wenn der Spoiler verraten wird.)
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
**Tabelle**
|
||||
<pre>[table border=1]
|
||||
[tr]
|
||||
[th]Tabellenzeile[/th]
|
||||
[/tr]
|
||||
[tr]
|
||||
[td]haben Überschriften[/td]
|
||||
[/tr]
|
||||
[/table]</pre>
|
||||
|
||||
<table border="1"><tbody><tr><th>Tabellenzeile</th></tr><tr><td>haben Überschriften</td></tr></tbody></table>
|
||||
|
||||
<p style="clear:both;"> </p>
|
||||
|
||||
**Listen**
|
||||
|
||||
<pre>[list]
|
||||
[*] Erstes Listenelement
|
||||
[*] Zweites Listenelement
|
||||
[/list]</pre>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[ul]<br>
|
||||
[li] Erstes Listenelement<br>
|
||||
[li] Zweites Listenelement<br>
|
||||
[/ul]<br>
|
||||
[list]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listbullet" style="list-style-type: circle;">
|
||||
<li> Erstes Listenelement<br>
|
||||
</li>
|
||||
<li>Erstes Listenelement</li>
|
||||
<li>Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[ol]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/ol]<br>
|
||||
[list=1]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listdecimal" style="list-style-type: decimal;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listnone" style="list-style-type: none;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=i]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listlowerroman" style="list-style-type: lower-roman;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=I]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listupperroman" style="list-style-type: upper-roman;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=a]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listloweralpha" style="list-style-type: lower-alpha;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[list=A]<br>
|
||||
[*] Erstes Listenelement<br>
|
||||
[*] Zweites Listenelement<br>
|
||||
[/list]</td>
|
||||
<td>
|
||||
<ul class="listupperalpha" style="list-style-type: upper-alpha;">
|
||||
<li> Erstes Listenelement</li>
|
||||
<li> Zweites Listenelement</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[list] ist Equivalent zu [ul] (unsortierte Liste).
|
||||
## Einbetten
|
||||
|
||||
[ol] kann anstelle von [list] verwendet werden um eine sortierte Liste zu erzeugen:
|
||||
Du kannst Videos, Musikdateien und weitere Dinge in Beiträgen einbinden.
|
||||
|
||||
<pre>[ol]
|
||||
[*] Erstes Listenelement
|
||||
[*] Zweites Listenelement
|
||||
[/ol]</pre>
|
||||
<ul class="listdecimal" style="list-style-type: decimal;"><li>Erstes Listenelement<br></li><li> Zweites Listenelement</li></ul>
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[video]url[/video]</td>
|
||||
<td>Wobei die *url* eine URL von youtube, vimeo, soundcloud oder einer anderen Plattform sein kann, die die opengraph Spezifikationen unterstützt.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[video]URL der Videodatei[/video]
|
||||
[audio]URL der Musikdatei[/audio]</td>
|
||||
<td>Die komplette URL einer ogg/ogv/oga/ogm/webm/mp4/mp3 Datei angeben, diese wird dann mit einem HTML5-Player angezeigt.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[youtube]Youtube URL[/youtube]</td>
|
||||
<td>Youtube Video mittels OEmbed anzeigen. Kann u.U, den Player nicht einbetten.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[youtube]Youtube video ID[/youtube]</td>
|
||||
<td>Youtube-Player im iframe einbinden.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[vimeo]Vimeo URL[/vimeo]</td>
|
||||
<td>Vimeo Video mittels OEmbed anzeigen. Kann u.U, den Player nicht einbetten.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[vimeo]Vimeo video ID[/vimeo]</td>
|
||||
<td>Vimeo-Player im iframe einbinden.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[iframe]URL[/iframe]</td>
|
||||
<td>General embed, iframe size is limited by the theme size for video players.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[url]*url*[/url]</td>
|
||||
<td>Wenn *url* die OEmbed- oder Opengraph-Spezifikationen unterstützt, wird das Objekt eingebettet (z.B. Dokumente von scribd).
|
||||
Ansonsten wird der Titel der Seite mit der URL verlinkt.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Für weitere Optionen von sortierten Listen kann man den Stil der Numerierung der Liste definieren:
|
||||
<pre>[list=1]</pre> : dezimal
|
||||
## Karten
|
||||
|
||||
<pre>[list=i]</pre> : römisch, Kleinbuchstaben
|
||||
Das Einbetten von Karten benötigt das "openstreetmap" oder das "Google Maps" Addon.
|
||||
Wenn keines der Addons aktiv ist, werden stattdeßen die Kordinaten angezeigt-
|
||||
|
||||
<pre>[list=I]</pre> : römisch, Großbuchstaben
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map]Adresse[/map]</td>
|
||||
<td>Bindet eine Karte ein, auf der die angegebene Adresse zentriert ist.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map=lat,long]</td>
|
||||
<td>Bindet eine Karte ein, die auf die angegebenen Koordinaten zentriert ist.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[map]</td>
|
||||
<td>Bindet eine Karte ein, die auf die Position des Beitrags zentriert ist.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[list=a]</pre> : alphabetisch, Kleinbuchstaben
|
||||
## Zusammenfassungen für lange Beiträge
|
||||
|
||||
<pre>[list=A] </pre> : alphabethisch, Großbuchstaben
|
||||
Wenn du deine Beiträge auf anderen Netzwerken von Drittanbietern verbreiten möchtest, z.B. Twitter, könntest du Probleme mit deren Zeichenbegrenzung haben.
|
||||
|
||||
Friendica verwendet einen semi-inelligenten Mechanismus um passende Zusammenfassungen zu erstellen.
|
||||
Du kannst allerdings auch selbst die Zusammenfassungen erstellen, die auf den unterschiedlichen Netzwerken angezeigt werden.
|
||||
Um dies zu tun, verwendest du den [abstract]-Tag.
|
||||
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[abstract]Unglaublich interessant! Muss man gesehen haben! Unbedingt dem Link folgen![/abstract]<br>
|
||||
Ich möchte euch eine unglaublich langweilige Geschichte erzählen, die ihr sicherlich niemals hören wolltet.</td>
|
||||
<td>Auf Twitter würde folgender Text verlffentlicht werden <blockquote>Unglaublich interessant! Muss man gesehen haben! Unbedingt dem Link folgen!</blockquote>
|
||||
Wohingegen auf Friendica folgendes stehen würde <blockquote>Ich möchte euch eine unglaublich langweilige Geschichte erzählen, die ihr sicherlich niemals hören wolltet.</blockquote></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Wenn du magst, kannst du auch unterschiedliche Zusammenfassungen für die unterschiedlichen Netzwerke verwenden.
|
||||
|
||||
Einbettung von Inhalten
|
||||
------
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[abstract]Hey Leute, hier sind meines neuesten Bilder![/abstract]<br>
|
||||
[abstract=twit]Hallo liebe Twitter Follower. Wollt ihr meine neuesten Bilder sehen?[/abstract]<br>
|
||||
[abstract=apdn]Moin liebe Follower auf ADN. Ich habe einige neue Bilder gemacht, die ich euch gerne zeigen will.[/abstract]<br>
|
||||
Heute war ich im Wald unterwegs und habe einige wirklich schöne Bilder gemacht...</td>
|
||||
<td>Für Twitter und App.net wird Friendica in diesem Fall die speziell definierten Zusammenfassungen Verwenden. Für andere Netzwerke (wie z.B. bei der Verwendung des GNU Social Konnektors zum Veröffentlichen auf deinen GNU Social Account) würde die allgemeine Zusammenfassung verwenden.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Man kann viele Dinge, z.B. Video und Audio Dateine, in Nachrichten einbetten.
|
||||
Wenn du beispielsweise den "buffer"-Konnektor verwendest um Beiträge nach Facebook und Google+ zu senden, dort aber nicht den gesamten Blogbeitrag posten willst sondern nur einen Anreißer, kannst du dies mit dem [abstract]-Tag realisieren.
|
||||
|
||||
<pre>[video]url[/video]</pre>
|
||||
<pre>[audio]url[/audio]</pre>
|
||||
Bei Netzwerken wie Facebook oder Google+, die selbst kein Zeichenlimit haben wird das [abstract]-Element allerdings nicht grundsätzlich verwendet.
|
||||
Daher müssen diese Netzwerke explizit genannt werden.
|
||||
|
||||
Wobei die *url* von youtube, vimeo, soundcloud oder einer anderen Seite stammen kann die die oembed oder opengraph Spezifikationen unterstützt.
|
||||
Außerdem kann *url* die genaue url zu einer ogg Datei sein, die dann per HTML5 eingebunden wird.
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[abstract]Dieser Tage hatte ich eine ungewöhnliche Begegnung...[/abstract]<br>
|
||||
[abstract=goog]Hey liebe Google+ Follower. Habt ich schon meinen neuesten Blog-Beitrag gelesen?[/abstract]<br>
|
||||
[abstract=face]Hallo liebe Facebook Freunde. Letztens ist mir etwas wirklich schönes paßiert.[/abstract]<br>
|
||||
Als ich die Bilder im Wald aufgenommen habe, hatte ich eine wirklich ungewöhnliche Begegnung...</td>
|
||||
<td>Auf Google und Facebook würde nun die entsprechende Zusammenfassung verbreitet. Für andere Netzwerke würde die allgemeine Zusammenfassung verwendet werden.<br>
|
||||
<br>Auf Friendica wird weiterhin keine Zusammenfassung angezeigt.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[url]*url*[/url]</pre>
|
||||
Für Verbindungen zu Netzwerken, zu denen Friendica den HTML Code postet, wie Tumblr, Wordpress oder Pump.io wird das [abstract] Element nicht verwendet.
|
||||
Bei nativen Verbindungen; das heißt zu z.B. Friendica, Hubzilla, Diaspora oder GNU Social Kontakten; wird der ungekürzte Beitrag übertragen.
|
||||
Die Instanz des Kontakts kümmert sich um die Darstellung.
|
||||
|
||||
Wenn *url* entweder oembed oder opengraph unterstützt wird das eingebettete Objekt (z.B. ein Dokument von scribd) eingebunden.
|
||||
Der Titel der Seite mit einem Link zur *url* wird ebenfalls angezeigt.
|
||||
## Special
|
||||
|
||||
Um eine Karte in einen Beitrag einzubinden, muss das *openstreetmap* Addon aktiviert werden. Ist dies der Fall, kann mit
|
||||
<table class="bbcodes">
|
||||
<tr>
|
||||
<th>BBCode</th>
|
||||
<th>Ergebnis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wenn du verhindern möchtest, daß der BBCode in einer Nachricht interpretiert wird, kannst du die [noparse], [nobb] oder [pre] Tag verwenden:<br>
|
||||
<ul>
|
||||
<li>[noparse][b]fett[/b][/noparse]</li>
|
||||
<li>[nobb][b]fett[/b][/nobb]</li>
|
||||
<li>[pre][b]fett[/b][/pre]</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>[b]fett[/b]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[nosmile] kann verwendet werden um für einen Beitrag das umsetzen von Smilies zu verhindern.<br>
|
||||
<br>
|
||||
[nosmile] ;-) :-O
|
||||
</td>
|
||||
<td>;-) :-O</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Benutzerdefinierte Inline-Styles<br>
|
||||
<br>
|
||||
[style=text-shadow: 0 0 4px #CC0000;]Du kannst alle CSS-Eigenschaften eines Blocks ändern-[/style]</td>
|
||||
<td><span style="text-shadow: 0 0 4px #cc0000;;">Du kannst alle CSS-Eigenschaften eines Blocks ändern-</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Benutzerdefinierte CSS Klassen<br>
|
||||
<br>
|
||||
[class=custom]Wenn die vergebene Klasse in den CSS Anweisungen existiert, wird sie angewandt.[/class]</td>
|
||||
<td><pre><span class="custom">Wenn die<br>
|
||||
vergebene Klasse in den CSS Anweisungen<br>
|
||||
existiert,wird sie angewandt.</span></pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre>[map]Broadway 26, New York[/map]</pre>
|
||||
|
||||
eine Karte von [OpenStreetmap](http://openstreetmap.org) eingebettet werden. Zur Identifikation des Ortes können entweder seine Koordinaten in der Form
|
||||
|
||||
<pre>[map=lat,long]</pre>
|
||||
|
||||
oder eine Adresse in obiger Form verwendet werden.
|
||||
|
||||
Zusammenfassung für längere Beiträge
|
||||
------------------------------------
|
||||
|
||||
Wenn man seine Beiträge über mehrere Netzwerke verbreiten möchte, hat man häufig das Problem, dass diese Netzwerke z.B. eine Längenbeschränkung haben.
|
||||
(Z.B. Twitter).
|
||||
|
||||
Friendica benutzt zum Erzeugen eines Anreißtextes eine halbwegs intelligente Logik.
|
||||
Es kann aber dennoch von Interesse sein, eine eigene Zusammenfassung zu erstellen, die nur auf dem Fremdnetzwerk dargestellt wird.
|
||||
Dies geschieht mit dem [abstract]-Element.
|
||||
Beispiel:
|
||||
|
||||
<pre>[abstract]Total spannend! Unbedingt diesen Link anklicken![/abstract]
|
||||
Hier erzähle ich euch eine total langweilige Geschichte, die ihr noch
|
||||
nie hören wolltet.</pre>
|
||||
|
||||
Auf Twitter würde das "Total spannend! Unbedingt diesen Link anklicken!" stehen, auf Friendica würde nur der Text nach "Hier erzähle ..." erscheinen.
|
||||
|
||||
Es ist sogar möglich, für einzelne Netzwerke eigene Zusammenfassungen zu erstellen:
|
||||
|
||||
<pre>
|
||||
[abstract]Hallo Leute, hier meine neuesten Bilder![abstract]
|
||||
[abstract=twit]Hallo Twitter-User, hier meine neuesten Bilder![abstract]
|
||||
[abstract=apdn]Hallo App.net-User, hier meine neuesten Bilder![abstract]
|
||||
Ich war heute wieder im Wald unterwegs und habe tolle Bilder geschossen ...
|
||||
</pre>
|
||||
|
||||
Für Twitter und App.net nimmt das System die entsprechenden Texte.
|
||||
Bei anderen Netzwerken, bei denen der Inhalt gekürzt wird (z.B. beim "statusnet"-Connector, der für das Posten nach GNU Social verwendet wird) wird dann die Zusammenfassung unter [abstract] verwendet.
|
||||
|
||||
Wenn man z.B. den "buffer"-Connector verwendet, um nach Facebook oder Google+ zu posten, kann man dieses Element ebenfalls verwenden, wenn man z.B. einen längeren Blogbeitrag erstellt hat, aber ihn nicht komplett in diese Netzwerke posten möchte.
|
||||
|
||||
Netzwerke wie Facebook oder Google+ sind nicht in der Postinglänge beschränkt.
|
||||
Aus diesem Grund greift nicht die [abstract]-Zusammenfassung. Stattdessen muss man das Netzwerk explizit angeben:
|
||||
|
||||
<pre>
|
||||
[abstract]Ich habe neulich wieder etwas erlebt, was ich euch mitteilen möchte.[abstract]
|
||||
[abstract=goog]Hallo meine Google+-Kreislinge. Ich habe neulich wieder
|
||||
etwas erlebt, was ich euch mitteilen möchte.[abstract]
|
||||
[abstract=face]Hallo Facebook-Freunde! Ich habe neulich wieder etwas
|
||||
erlebt, was ich euch mitteilen möchte.[abstract]
|
||||
Beim Bildermachen im Wald habe ich neulich eine interessante Person
|
||||
getroffen ... </pre>
|
||||
|
||||
Das [abstract]-Element greift nicht bei der nativen OStatus-Verbindung oder bei Connectoren, die den HTML-Text posten wie z.B. die Connectoren zu Tumblr, Wordpress oder Pump.io.
|
||||
|
||||
Spezielle Tags
|
||||
-------
|
||||
|
||||
Wenn Du über BBCode Tags in einer Nachricht schreiben möchtest, kannst Du [noparse], [nobb] oder [pre] verwenden um den BBCode Tags vor der Evaluierung zu schützen:
|
||||
|
||||
<pre>[noparse][b]fett[/b][/noparse]</pre> : [b]fett[/b]
|
||||
|
|
|
@ -29,7 +29,7 @@ Friendica - Dokumentation und Ressourcen
|
|||
**Technische Dokumentation**
|
||||
|
||||
* [Installation](help/Install)
|
||||
* [Konfigurationen](help/Settings)
|
||||
* [Konfigurationen & Admin-Panel](help/Settings)
|
||||
* [Plugins](help/Plugins)
|
||||
* [Konnektoren (Connectors) installieren (Twitter/GNU Social)](help/Installing-Connectors)
|
||||
* [Installation eines ejabberd Servers (XMPP-Chat) mit synchronisierten Anmeldedaten](help/install-ejabberd) (EN)
|
||||
|
|
|
@ -9,8 +9,9 @@ Diese Zahl sollte sich relativ schnell sinken.
|
|||
Die zweite Zahl gibt die Anzahl von Nachrichten an, die nicht zugestellt werden konnten.
|
||||
Die Zustellung wird zu einem späteren Zeitpunkt noch einmal versucht.
|
||||
Unter dem Punkt "Warteschlange Inspizieren" kannst du einen schnellen Blick auf die zweite Warteschlange werfen.
|
||||
Solltest du für die Hintergrundprozesse die Worker aktiviert haben, könntest du eine dritte Zahl angezeigt bekommen.
|
||||
Solltest du für die Hintergrundprozesse die Worker aktiviert haben, wird eine dritte Zahl angezeigt.
|
||||
Diese repräsentiert die Anzahl der Aufgaben, die die Worker noch vor sich haben.
|
||||
Die Aufgaben der Worker sind priorisiert und werden anhand dieser Prioritäten abgearbeitet.
|
||||
|
||||
Des weiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.
|
||||
Sowie eine Liste der derzeit aktivierten Addons.
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
Config values that can only be set in .htconfig.php
|
||||
===================================================
|
||||
|
||||
There are some config values that haven't found their way into the administration page. This has several reasons. Maybe they are part of a
|
||||
current development that isn't considered stable and will be added later in the administration page when it is considered safe. Or it triggers
|
||||
something that isn't expected to be of public interest. Or it is for testing purposes only.
|
||||
There are some config values that haven't found their way into the administration page.
|
||||
This has several reasons.
|
||||
Maybe they are part of a current development that isn't considered stable and will be added later in the administration page when it is considered safe.
|
||||
Or it triggers something that isn't expected to be of public interest. Or it is for testing purposes only.
|
||||
|
||||
**Attention:** Please be warned that you shouldn't use one of these values without the knowledge what it could trigger. Especially don't do that with
|
||||
undocumented values.
|
||||
**Attention:** Please be warned that you shouldn't use one of these values without the knowledge what it could trigger.
|
||||
Especially don't do that with undocumented values.
|
||||
|
||||
The header of the section describes the category, the value is the parameter. Example: To set the directory value please add this
|
||||
line to your .htconfig.php:
|
||||
The header of the section describes the category, the value is the parameter.
|
||||
Example: To set the directory value please add this line to your .htconfig.php:
|
||||
|
||||
$a->config['system']['directory'] = 'http://dir.friendi.ca';
|
||||
|
||||
|
||||
|
||||
## Jabber ##
|
||||
* debug (Boolean) - Enable debug level for the jabber account synchronisation.
|
||||
* logfile - Logfile for the jabber account synchronisation.
|
||||
|
@ -40,6 +39,9 @@ line to your .htconfig.php:
|
|||
* max_batch_queue - Default value is 1000.
|
||||
* max_processes_backend - Maximum number of concurrent database processes for background tasks. Default value is 5.
|
||||
* max_processes_frontend - Maximum number of concurrent database processes for foreground tasks. Default value is 20.
|
||||
* memcache (Boolean) - Use memcache. To use memcache the PECL extension "memcache" has to be installed and activated.
|
||||
* memcache_host - Hostname of the memcache daemon. Default is '127.0.0.1'.
|
||||
* memcache_port- Portnumberof the memcache daemon. Default is 11211.
|
||||
* no_oembed (Boolean) - Don't use OEmbed to fetch more information about a link.
|
||||
* no_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF).
|
||||
* no_smilies (Boolean) - Don't show smilies.
|
||||
|
@ -48,6 +50,7 @@ line to your .htconfig.php:
|
|||
* ostatus_poll_timeframe - Defines how old an item can be to try to complete the conversation with it.
|
||||
* paranoia (Boolean) - Log out users if their IP address changed.
|
||||
* permit_crawling (Boolean) - Restricts the search for not logged in users to one search per minute.
|
||||
* profiler (Boolean) - Enable internal timings to help optimize code. Needed for "rendertime" addon. Default is false.
|
||||
* free_crawls - Number of "free" searches when "permit_crawling" is activated (Default value is 10)
|
||||
* crawl_permit_period - Period in seconds between allowed searches when the number of free searches is reached and "permit_crawling" is activated (Default value is 60)
|
||||
* png_quality - Default value is 8.
|
||||
|
@ -57,7 +60,7 @@ line to your .htconfig.php:
|
|||
* qsearch_limit - Default value is 100.
|
||||
* relay_server - Experimental Diaspora feature. Address of the relay server where public posts should be send to. For example https://podrelay.net
|
||||
* relay_subscribe (Boolean) - Enables the receiving of public posts from the relay. They will be included in the search and on the community page when it is set up to show all public items.
|
||||
* relay_scope - Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts witt selected tags should be received.
|
||||
* relay_scope - Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received.
|
||||
* relay_server_tags - Comma separated list of tags for the "tags" subscription (see "relay_scrope")
|
||||
* relay_user_tags (Boolean) - If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags".
|
||||
* remove_multiplicated_lines (Boolean) - If enabled, multiple linefeeds in items are stripped to a single one.
|
||||
|
@ -67,6 +70,7 @@ line to your .htconfig.php:
|
|||
* throttle_limit_week - Maximum number of posts that a user can send per week with the API.
|
||||
* throttle_limit_month - Maximum number of posts that a user can send per month with the API.
|
||||
* wall-to-wall_share (Boolean) - Displays forwarded posts like "wall-to-wall" posts.
|
||||
* worker_cooldown - Cooldown time after each worker function call. Default value is 0 seconds.
|
||||
* xrd_timeout - Timeout for fetching the XRD links. Default value is 20 seconds.
|
||||
|
||||
## service_class ##
|
||||
|
@ -83,19 +87,15 @@ line to your .htconfig.php:
|
|||
|
||||
# Administrator Options #
|
||||
|
||||
Enabling the admin panel for an account, and thus making the account holder
|
||||
admin of the node, is done by setting the variable
|
||||
Enabling the admin panel for an account, and thus making the account holder admin of the node, is done by setting the variable
|
||||
|
||||
$a->config['admin_email'] = "someone@example.com";
|
||||
|
||||
where you have to match the email address used for the account with the one you
|
||||
enter to the .htconfig file. If more then one account should be able to access
|
||||
the admin panel, seperate the email addresses with a comma.
|
||||
Where you have to match the email address used for the account with the one you enter to the .htconfig file.
|
||||
If more then one account should be able to access the admin panel, seperate the email addresses with a comma.
|
||||
|
||||
$a->config['admin_email'] = "someone@example.com,someonelese@example.com";
|
||||
|
||||
If you want to have a more personalized closing line for the notification
|
||||
emails you can set a variable for the admin_name.
|
||||
If you want to have a more personalized closing line for the notification emails you can set a variable for the admin_name.
|
||||
|
||||
$a->config['admin_name'] = "Marvin";
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Friendica Documentation and Resources
|
|||
**Technical Documentation**
|
||||
|
||||
* [Install](help/Install)
|
||||
* [Settings](help/Settings)
|
||||
* [Settings & Admin Panel](help/Settings)
|
||||
* [Plugins](help/Plugins)
|
||||
* [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors)
|
||||
* [Install an ejabberd server (XMPP chat) with synchronized credentials](help/install-ejabberd)
|
||||
|
|
|
@ -24,12 +24,12 @@ If you want to get your work into the source tree yourself, feel free to do so a
|
|||
The process is simple and friendica ships with all the tools necessary.
|
||||
|
||||
The location of the translated files in the source tree is
|
||||
/view/LNG-CODE/
|
||||
/view/lang/LNG-CODE/
|
||||
where LNG-CODE is the language code used, e.g. de for German or fr for French.
|
||||
The translated strings come as a "message.po" file from transifex which needs to be translated into the PHP file friendica uses.
|
||||
To do so, place the file in the directory mentioned above and use the "po2php" utility from the util directory of your friendica installation.
|
||||
|
||||
Assuming you want to convert the German localization which is placed in view/de/message.po you would do the following.
|
||||
Assuming you want to convert the German localization which is placed in view/lang/de/message.po you would do the following.
|
||||
|
||||
1. Navigate at the command prompt to the base directory of your
|
||||
friendica installation
|
||||
|
@ -37,9 +37,9 @@ Assuming you want to convert the German localization which is placed in view/de/
|
|||
2. Execute the po2php script, which will place the translation
|
||||
in the strings.php file that is used by friendica.
|
||||
|
||||
$> php util/po2php.php view/de/messages.po
|
||||
$> php util/po2php.php view/lang/de/messages.po
|
||||
|
||||
The output of the script will be placed at view/de/strings.php where
|
||||
The output of the script will be placed at view/lang/de/strings.php where
|
||||
friendica is expecting it, so you can test your translation immediately.
|
||||
|
||||
3. Visit your friendica page to check if it still works in the language you
|
||||
|
@ -50,7 +50,7 @@ Assuming you want to convert the German localization which is placed in view/de/
|
|||
not give any output if the file is ok but might give a hint for
|
||||
searching the bug in the file.
|
||||
|
||||
$> php view/de/strings.php
|
||||
$> php view/lang/de/strings.php
|
||||
|
||||
4. commit the two files with a meaningful commit message to your git
|
||||
repository, push it to your fork of the friendica repository at github and
|
||||
|
|
34
doc/upgrade.md
Normal file
34
doc/upgrade.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Considerations before upgrading Friendica
|
||||
|
||||
* [Home](help)
|
||||
|
||||
## MySQL >= 5.7.4
|
||||
|
||||
Starting from MySQL version 5.7.4, the IGNORE keyword in ALTER TABLE statements is ignored.
|
||||
This prevents automatic table deduplication if a UNIQUE index is added to a Friendica table's structure.
|
||||
If a DB update fails for you while creating a UNIQUE index, make sure to manually deduplicate the table before trying the update again.
|
||||
|
||||
### Manual deduplication
|
||||
|
||||
There are two main ways of doing it, either by manually removing the duplicates or by recreating the table.
|
||||
Manually removing the duplicates is usually faster if they're not too numerous.
|
||||
To manually remove the duplicates, you need to know the UNIQUE index columns available in `database.sql`.
|
||||
|
||||
```SQL
|
||||
SELECT GROUP_CONCAT(id), <index columns>, count(*) as count FROM users
|
||||
GROUP BY <index columns> HAVING count >= 2;
|
||||
|
||||
/* delete or merge duplicate from above query */;
|
||||
```
|
||||
|
||||
If there are too many rows to handle manually, you can create a new table with the same structure as the table with duplicates and insert the existing content with INSERT IGNORE.
|
||||
To recreate the table you need to know the table structure available in `database.sql`.
|
||||
|
||||
```SQL
|
||||
CREATE TABLE <table_name>_new <rest of the CREATE TABLE>;
|
||||
INSERT IGNORE INTO <table_name>_new SELECT * FROM <table_name>;
|
||||
DROP TABLE <table_name>;
|
||||
RENAME TABLE <table_name>_new TO <table_name>;
|
||||
```
|
||||
|
||||
This method is slower overall, but it is better suited for large numbers of duplicates.
|
|
@ -16,6 +16,11 @@ $db_user = 'mysqlusername';
|
|||
$db_pass = 'mysqlpassword';
|
||||
$db_data = 'mysqldatabasename';
|
||||
|
||||
// Set the database connection charset to UTF8.
|
||||
// Changing this value will likely corrupt the special characters.
|
||||
// You have been warned.
|
||||
$a->config['system']['db_charset'] = "utf8mb4";
|
||||
|
||||
// Choose a legal default timezone. If you are unsure, use "America/Los_Angeles".
|
||||
// It can be changed later and only applies to timestamps for anonymous viewers.
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@ function user_remove($uid) {
|
|||
// don't delete yet, will be done later when contacts have deleted my stuff
|
||||
// q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
|
||||
q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
|
||||
proc_run('php', "include/notifier.php", "removeme", $uid);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "removeme", $uid);
|
||||
|
||||
// Send an update to the directory
|
||||
proc_run('php', "include/directory.php", $r[0]['url']);
|
||||
proc_run(PRIORITY_LOW, "include/directory.php", $r[0]['url']);
|
||||
|
||||
if($uid == local_user()) {
|
||||
unset($_SESSION['authenticated']);
|
||||
|
@ -196,6 +196,7 @@ function unmark_for_death($contact) {
|
|||
* @brief Get contact data for a given profile link
|
||||
*
|
||||
* The function looks at several places (contact table and gcontact table) for the contact
|
||||
* It caches its result for the same script execution to prevent duplicate calls
|
||||
*
|
||||
* @param string $url The profile link
|
||||
* @param int $uid User id
|
||||
|
@ -204,35 +205,45 @@ function unmark_for_death($contact) {
|
|||
* @return array Contact data
|
||||
*/
|
||||
function get_contact_details_by_url($url, $uid = -1, $default = array()) {
|
||||
if ($uid == -1)
|
||||
static $cache = array();
|
||||
|
||||
if ($uid == -1) {
|
||||
$uid = local_user();
|
||||
}
|
||||
|
||||
if (isset($cache[$url][$uid])) {
|
||||
return $cache[$url][$uid];
|
||||
}
|
||||
|
||||
// Fetch contact data from the contact table for the given user
|
||||
$r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
|
||||
`keywords`, `gender`, `photo`, `thumb`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, `self`
|
||||
$r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
|
||||
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
|
||||
FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
|
||||
dbesc(normalise_link($url)), intval($uid));
|
||||
|
||||
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
|
||||
if (!$r)
|
||||
$r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
|
||||
`keywords`, `gender`, `photo`, `thumb`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, 0 AS `self`
|
||||
$r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
|
||||
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
|
||||
FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
|
||||
dbesc(normalise_link($url)));
|
||||
|
||||
// Fetch the data from the gcontact table
|
||||
if (!$r)
|
||||
$r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
|
||||
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `community` AS `forum`, 0 AS `prv`, `community`, `birthday`, 0 AS `self`
|
||||
$r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
|
||||
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
|
||||
FROM `gcontact` WHERE `nurl` = '%s'",
|
||||
dbesc(normalise_link($url)));
|
||||
|
||||
if ($r) {
|
||||
// If there is more than one entry we filter out the connector networks
|
||||
if (count($r) > 1)
|
||||
foreach ($r AS $id => $result)
|
||||
if ($result["network"] == NETWORK_STATUSNET)
|
||||
if (count($r) > 1) {
|
||||
foreach ($r AS $id => $result) {
|
||||
if ($result["network"] == NETWORK_STATUSNET) {
|
||||
unset($r[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$profile = array_shift($r);
|
||||
|
||||
|
@ -251,19 +262,40 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
|
|||
$profile["bd"] = $current_year."-".$month."-".$day;
|
||||
$current = $current_year."-".$current_month."-".$current_day;
|
||||
|
||||
if ($profile["bd"] < $current)
|
||||
if ($profile["bd"] < $current) {
|
||||
$profile["bd"] = (++$current_year)."-".$month."-".$day;
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
$profile["bd"] = "0000-00-00";
|
||||
}
|
||||
} else {
|
||||
$profile = $default;
|
||||
if (!isset($profile["thumb"]) AND isset($profile["photo"]))
|
||||
}
|
||||
|
||||
if (($profile["photo"] == "") AND isset($default["photo"])) {
|
||||
$profile["photo"] = $default["photo"];
|
||||
}
|
||||
|
||||
if (($profile["name"] == "") AND isset($default["name"])) {
|
||||
$profile["name"] = $default["name"];
|
||||
}
|
||||
|
||||
if (($profile["network"] == "") AND isset($default["network"])) {
|
||||
$profile["network"] = $default["network"];
|
||||
}
|
||||
|
||||
if (($profile["thumb"] == "") AND isset($profile["photo"])) {
|
||||
$profile["thumb"] = $profile["photo"];
|
||||
}
|
||||
|
||||
if (($profile["micro"] == "") AND isset($profile["thumb"])) {
|
||||
$profile["micro"] = $profile["thumb"];
|
||||
}
|
||||
|
||||
if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND ($profile["gid"] != 0) AND
|
||||
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
|
||||
proc_run('php',"include/update_gcontact.php", $profile["gid"]);
|
||||
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
|
||||
proc_run(PRIORITY_LOW, "include/update_gcontact.php", $profile["gid"]);
|
||||
}
|
||||
|
||||
// Show contact details of Diaspora contacts only if connected
|
||||
if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
|
||||
|
@ -273,43 +305,46 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
|
|||
$profile["birthday"] = "0000-00-00";
|
||||
}
|
||||
|
||||
return($profile);
|
||||
$cache[$url][$uid] = $profile;
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
if (! function_exists('contact_photo_menu')) {
|
||||
function contact_photo_menu($contact, $uid = 0) {
|
||||
|
||||
function contact_photo_menu($contact, $uid = 0)
|
||||
{
|
||||
$a = get_app();
|
||||
|
||||
$contact_url="";
|
||||
$pm_url="";
|
||||
$status_link="";
|
||||
$photos_link="";
|
||||
$posts_link="";
|
||||
$contact_drop_link = "";
|
||||
$poke_link="";
|
||||
$contact_url = '';
|
||||
$pm_url = '';
|
||||
$status_link = '';
|
||||
$photos_link = '';
|
||||
$posts_link = '';
|
||||
$contact_drop_link = '';
|
||||
$poke_link = '';
|
||||
|
||||
if ($uid == 0)
|
||||
if ($uid == 0) {
|
||||
$uid = local_user();
|
||||
}
|
||||
|
||||
if ($contact["uid"] != $uid) {
|
||||
if ($contact['uid'] != $uid) {
|
||||
if ($uid == 0) {
|
||||
$profile_link = zrl($contact['url']);
|
||||
$menu = Array('profile' => array(t("View Profile"), $profile_link, true));
|
||||
$menu = Array('profile' => array(t('View Profile'), $profile_link, true));
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `nurl` = '%s' AND `network` = '%s' AND `uid` = %d",
|
||||
dbesc($contact["nurl"]), dbesc($contact["network"]), intval($uid));
|
||||
if ($r)
|
||||
dbesc($contact['nurl']), dbesc($contact['network']), intval($uid));
|
||||
if ($r) {
|
||||
return contact_photo_menu($r[0], $uid);
|
||||
else {
|
||||
} else {
|
||||
$profile_link = zrl($contact['url']);
|
||||
$connlnk = 'follow/?url='.$contact['url'];
|
||||
$menu = Array(
|
||||
'profile' => array(t("View Profile"), $profile_link, true),
|
||||
'follow' => array(t("Connect/Follow"), $connlnk, true)
|
||||
$menu = array(
|
||||
'profile' => array(t('View Profile'), $profile_link, true),
|
||||
'follow' => array(t('Connect/Follow'), $connlnk, true)
|
||||
);
|
||||
|
||||
return $menu;
|
||||
|
@ -320,40 +355,43 @@ function contact_photo_menu($contact, $uid = 0) {
|
|||
if ($contact['network'] === NETWORK_DFRN) {
|
||||
$sparkle = true;
|
||||
$profile_link = $a->get_baseurl() . '/redir/' . $contact['id'];
|
||||
}
|
||||
else
|
||||
} else {
|
||||
$profile_link = $contact['url'];
|
||||
}
|
||||
|
||||
if($profile_link === 'mailbox')
|
||||
if ($profile_link === 'mailbox') {
|
||||
$profile_link = '';
|
||||
}
|
||||
|
||||
if ($sparkle) {
|
||||
$status_link = $profile_link . "?url=status";
|
||||
$photos_link = $profile_link . "?url=photos";
|
||||
$profile_link = $profile_link . "?url=profile";
|
||||
$status_link = $profile_link . '?url=status';
|
||||
$photos_link = $profile_link . '?url=photos';
|
||||
$profile_link = $profile_link . '?url=profile';
|
||||
}
|
||||
|
||||
if (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA)))
|
||||
if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
|
||||
$pm_url = $a->get_baseurl() . '/message/new/' . $contact['id'];
|
||||
}
|
||||
|
||||
if ($contact["network"] == NETWORK_DFRN)
|
||||
if ($contact['network'] == NETWORK_DFRN) {
|
||||
$poke_link = $a->get_baseurl() . '/poke/?f=&c=' . $contact['id'];
|
||||
}
|
||||
|
||||
$contact_url = $a->get_baseurl() . '/contacts/' . $contact['id'];
|
||||
$posts_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/posts';
|
||||
$contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1';
|
||||
|
||||
$posts_link = $a->get_baseurl() . '/contacts/' . $contact['id'] . '/posts';
|
||||
$contact_drop_link = $a->get_baseurl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
|
||||
|
||||
/**
|
||||
* menu array:
|
||||
* "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
|
||||
*/
|
||||
$menu = Array(
|
||||
$menu = array(
|
||||
'status' => array(t("View Status"), $status_link, true),
|
||||
'profile' => array(t("View Profile"), $profile_link, true),
|
||||
'photos' => array(t("View Photos"), $photos_link, true),
|
||||
'network' => array(t("Network Posts"), $posts_link, false),
|
||||
'edit' => array(t("Edit Contact"), $contact_url, false),
|
||||
'edit' => array(t("View Contact"), $contact_url, false),
|
||||
'drop' => array(t("Drop Contact"), $contact_drop_link, false),
|
||||
'pm' => array(t("Send PM"), $pm_url, false),
|
||||
'poke' => array(t("Poke"), $poke_link, false),
|
||||
|
@ -366,9 +404,11 @@ function contact_photo_menu($contact, $uid = 0) {
|
|||
|
||||
$menucondensed = array();
|
||||
|
||||
foreach ($menu AS $menuname=>$menuitem)
|
||||
if ($menuitem[1] != "")
|
||||
foreach ($menu AS $menuname => $menuitem) {
|
||||
if ($menuitem[1] != '') {
|
||||
$menucondensed[$menuname] = $menuitem;
|
||||
}
|
||||
}
|
||||
|
||||
return $menucondensed;
|
||||
}}
|
||||
|
@ -410,9 +450,20 @@ function contacts_not_grouped($uid,$start = 0,$count = 0) {
|
|||
return $r;
|
||||
}
|
||||
|
||||
function get_contact($url, $uid = 0) {
|
||||
/**
|
||||
* @brief Fetch the contact id for a given url and user
|
||||
*
|
||||
* @param string $url Contact URL
|
||||
* @param integer $uid The user id for the contact
|
||||
* @param boolean $no_update Don't update the contact
|
||||
*
|
||||
* @return integer Contact ID
|
||||
*/
|
||||
function get_contact($url, $uid = 0, $no_update = false) {
|
||||
require_once("include/Scrape.php");
|
||||
|
||||
logger("Get contact data for url ".$url." and user ".$uid." - ".App::callstack(), LOGGER_DEBUG);;
|
||||
|
||||
$data = array();
|
||||
$contactid = 0;
|
||||
|
||||
|
@ -442,8 +493,9 @@ function get_contact($url, $uid = 0) {
|
|||
$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -7 days'));
|
||||
//$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -12 hours'));
|
||||
|
||||
if (!$update_photo)
|
||||
if (!$update_photo OR $no_update) {
|
||||
return($contactid);
|
||||
}
|
||||
} elseif ($uid != 0)
|
||||
return 0;
|
||||
|
||||
|
@ -451,17 +503,27 @@ function get_contact($url, $uid = 0) {
|
|||
$data = probe_url($url);
|
||||
|
||||
// Does this address belongs to a valid network?
|
||||
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
|
||||
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
|
||||
if ($uid != 0)
|
||||
return 0;
|
||||
|
||||
// Get data from the gcontact table
|
||||
$r = q("SELECT `name`, `nick`, `url`, `photo`, `addr`, `alias`, `network` FROM `gcontact` WHERE `nurl` = '%s'",
|
||||
dbesc(normalise_link($url)));
|
||||
if (!$r)
|
||||
return 0;
|
||||
|
||||
$data = $r[0];
|
||||
}
|
||||
|
||||
$url = $data["url"];
|
||||
|
||||
if ($contactid == 0) {
|
||||
q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,
|
||||
`name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
|
||||
`batch`, `request`, `confirm`, `poco`,
|
||||
`batch`, `request`, `confirm`, `poco`, `name-date`, `uri-date`,
|
||||
`writable`, `blocked`, `readonly`, `pending`)
|
||||
VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
|
||||
VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($data["url"]),
|
||||
|
@ -480,7 +542,9 @@ function get_contact($url, $uid = 0) {
|
|||
dbesc($data["batch"]),
|
||||
dbesc($data["request"]),
|
||||
dbesc($data["confirm"]),
|
||||
dbesc($data["poco"])
|
||||
dbesc($data["poco"]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
|
||||
$contact = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2",
|
||||
|
@ -490,6 +554,16 @@ function get_contact($url, $uid = 0) {
|
|||
return 0;
|
||||
|
||||
$contactid = $contact[0]["id"];
|
||||
|
||||
// Update the newly created contact from data in the gcontact table
|
||||
$r = q("SELECT `location`, `about`, `keywords`, `gender` FROM `gcontact` WHERE `nurl` = '%s'",
|
||||
dbesc(normalise_link($data["url"])));
|
||||
if ($r) {
|
||||
logger("Update contact ".$data["url"]);
|
||||
q("UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d",
|
||||
dbesc($r["location"]), dbesc($r["about"]), dbesc($r["keywords"]),
|
||||
dbesc($r["gender"]), intval($contactid));
|
||||
}
|
||||
}
|
||||
|
||||
if ((count($contact) > 1) AND ($uid == 0) AND ($contactid != 0) AND ($url != ""))
|
||||
|
@ -501,6 +575,17 @@ function get_contact($url, $uid = 0) {
|
|||
|
||||
update_contact_avatar($data["photo"],$uid,$contactid);
|
||||
|
||||
$r = q("SELECT `addr`, `alias`, `name`, `nick` FROM `contact` WHERE `id` = %d", intval($contactid));
|
||||
|
||||
// This condition should always be true
|
||||
if (!dbm::is_result($r))
|
||||
return $contactid;
|
||||
|
||||
// Only update if there had something been changed
|
||||
if (($data["addr"] != $r[0]["addr"]) OR
|
||||
($data["alias"] != $r[0]["alias"]) OR
|
||||
($data["name"] != $r[0]["name"]) OR
|
||||
($data["nick"] != $r[0]["nick"]))
|
||||
q("UPDATE `contact` SET `addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s',
|
||||
`name-date` = '%s', `uri-date` = '%s' WHERE `id` = %d",
|
||||
dbesc($data["addr"]),
|
||||
|
@ -599,11 +684,11 @@ function posts_from_contact($a, $contact_id) {
|
|||
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
|
||||
`author-name` AS `name`, `owner-avatar` AS `photo`,
|
||||
`owner-link` AS `url`, `owner-avatar` AS `thumb`
|
||||
FROM `item` FORCE INDEX (`uid_contactid_created`)
|
||||
FROM `item` FORCE INDEX (`uid_contactid_id`)
|
||||
WHERE `item`.`uid` = %d AND `contact-id` = %d
|
||||
AND `author-link` IN ('%s', '%s')
|
||||
AND NOT `deleted` AND NOT `moderated` AND `visible`
|
||||
ORDER BY `item`.`created` DESC LIMIT %d, %d",
|
||||
ORDER BY `item`.`id` DESC LIMIT %d, %d",
|
||||
intval(local_user()),
|
||||
intval($contact_id),
|
||||
dbesc(str_replace("https://", "http://", $contact["url"])),
|
||||
|
@ -651,4 +736,50 @@ function formatted_location($profile) {
|
|||
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the account type name
|
||||
*
|
||||
* The function can be called with either the user or the contact array
|
||||
*
|
||||
* @param array $contact contact or user array
|
||||
*/
|
||||
function account_type($contact) {
|
||||
|
||||
// There are several fields that indicate that the contact or user is a forum
|
||||
// "page-flags" is a field in the user table,
|
||||
// "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
|
||||
// "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
|
||||
if((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
|
||||
|| (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
|
||||
|| (isset($contact['forum']) && intval($contact['forum']))
|
||||
|| (isset($contact['prv']) && intval($contact['prv']))
|
||||
|| (isset($contact['community']) && intval($contact['community'])))
|
||||
$type = ACCOUNT_TYPE_COMMUNITY;
|
||||
else
|
||||
$type = ACCOUNT_TYPE_PERSON;
|
||||
|
||||
// The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
|
||||
if (isset($contact["contact-type"]))
|
||||
$type = $contact["contact-type"];
|
||||
if (isset($contact["account-type"]))
|
||||
$type = $contact["account-type"];
|
||||
|
||||
switch($type) {
|
||||
case ACCOUNT_TYPE_ORGANISATION:
|
||||
$account_type = t("Organisation");
|
||||
break;
|
||||
case ACCOUNT_TYPE_NEWS:
|
||||
$account_type = t('News');
|
||||
break;
|
||||
case ACCOUNT_TYPE_COMMUNITY:
|
||||
$account_type = t("Forum");
|
||||
break;
|
||||
default:
|
||||
$account_type = "";
|
||||
break;
|
||||
}
|
||||
|
||||
return $account_type;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -32,7 +32,7 @@ class Config {
|
|||
public static function load($family) {
|
||||
global $a;
|
||||
|
||||
$r = q("SELECT `v`, `k` FROM `config` WHERE `cat` = '%s'", dbesc($family));
|
||||
$r = q("SELECT `v`, `k` FROM `config` WHERE `cat` = '%s' ORDER BY `cat`, `k`, `id`", dbesc($family));
|
||||
if (count($r)) {
|
||||
foreach ($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
|
@ -74,7 +74,7 @@ class Config {
|
|||
|
||||
global $a;
|
||||
|
||||
if(! $instore) {
|
||||
if (!$refresh) {
|
||||
// Looking if the whole family isn't set
|
||||
if (isset($a->config[$family])) {
|
||||
if ($a->config[$family] === '!<unset>!') {
|
||||
|
@ -90,30 +90,7 @@ class Config {
|
|||
}
|
||||
}
|
||||
|
||||
// If APC is enabled then fetch the data from there, else try XCache
|
||||
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
|
||||
if (apc_exists($family."|".$key)) {
|
||||
$val = apc_fetch($family."|".$key);
|
||||
$a->config[$family][$key] = $val;
|
||||
|
||||
if ($val === '!<unset>!')
|
||||
return false;
|
||||
else
|
||||
return $val;
|
||||
}
|
||||
elseif (function_exists("xcache_fetch") AND function_exists("xcache_isset"))
|
||||
if (xcache_isset($family."|".$key)) {
|
||||
$val = xcache_fetch($family."|".$key);
|
||||
$a->config[$family][$key] = $val;
|
||||
|
||||
if ($val === '!<unset>!')
|
||||
return false;
|
||||
else
|
||||
return $val;
|
||||
}
|
||||
*/
|
||||
|
||||
$ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
|
||||
$ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' ORDER BY `id` DESC LIMIT 1",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
@ -122,22 +99,9 @@ class Config {
|
|||
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
|
||||
$a->config[$family][$key] = $val;
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($family."|".$key, $val, 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($family."|".$key, $val, 600);*/
|
||||
|
||||
return $val;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$a->config[$family][$key] = '!<unset>!';
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($family."|".$key, '!<unset>!', 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($family."|".$key, '!<unset>!', 600);*/
|
||||
}
|
||||
return $default_value;
|
||||
}
|
||||
|
@ -161,45 +125,35 @@ class Config {
|
|||
public static function set($family, $key, $value) {
|
||||
global $a;
|
||||
|
||||
// If $a->config[$family] has been previously set to '!<unset>!', then
|
||||
// $a->config[$family][$key] will evaluate to $a->config[$family][0], and
|
||||
// $a->config[$family][$key] = $value will be equivalent to
|
||||
// $a->config[$family][0] = $value[0] (this causes infuriating bugs),
|
||||
// so unset the family before assigning a value to a family's key
|
||||
if($a->config[$family] === '!<unset>!')
|
||||
unset($a->config[$family]);
|
||||
$stored = self::get($family, $key);
|
||||
|
||||
if ($stored == $value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$a->config[$family][$key] = $value;
|
||||
|
||||
// manage array value
|
||||
$dbvalue = (is_array($value) ? serialize($value) : $value);
|
||||
$dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
|
||||
if(is_null(self::get($family,$key,null,true))) {
|
||||
$a->config[$family][$key] = $value;
|
||||
$ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
|
||||
|
||||
if (is_null($stored)) {
|
||||
$ret = q("INSERT INTO `config` (`cat`, `k`, `v`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `v` = '%s'",
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
if($ret)
|
||||
return $value;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
$ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s'",
|
||||
dbesc($dbvalue),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
$a->config[$family][$key] = $value;
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($family."|".$key, $value, 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($family."|".$key, $value, 600);*/
|
||||
|
||||
if($ret)
|
||||
}
|
||||
if ($ret) {
|
||||
return $value;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
@ -218,17 +172,13 @@ class Config {
|
|||
public static function delete($family, $key) {
|
||||
|
||||
global $a;
|
||||
if(x($a->config[$family],$key))
|
||||
if (x($a->config[$family],$key)) {
|
||||
unset($a->config[$family][$key]);
|
||||
}
|
||||
$ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s'",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
// If APC is enabled then delete the data from there, else try XCache
|
||||
/*if (function_exists("apc_delete"))
|
||||
apc_delete($family."|".$key);
|
||||
elseif (function_exists("xcache_unset"))
|
||||
xcache_unset($family."|".$key);*/
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class PConfig {
|
|||
*/
|
||||
public static function load($uid, $family) {
|
||||
global $a;
|
||||
$r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
|
||||
$r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d ORDER BY `cat`, `k`, `id`",
|
||||
dbesc($family),
|
||||
intval($uid)
|
||||
);
|
||||
|
@ -67,7 +67,7 @@ class PConfig {
|
|||
|
||||
global $a;
|
||||
|
||||
if(! $instore) {
|
||||
if (!$refresh) {
|
||||
// Looking if the whole family isn't set
|
||||
if (isset($a->config[$uid][$family])) {
|
||||
if ($a->config[$uid][$family] === '!<unset>!') {
|
||||
|
@ -83,30 +83,7 @@ class PConfig {
|
|||
}
|
||||
}
|
||||
|
||||
// If APC is enabled then fetch the data from there, else try XCache
|
||||
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
|
||||
if (apc_exists($uid."|".$family."|".$key)) {
|
||||
$val = apc_fetch($uid."|".$family."|".$key);
|
||||
$a->config[$uid][$family][$key] = $val;
|
||||
|
||||
if ($val === '!<unset>!')
|
||||
return false;
|
||||
else
|
||||
return $val;
|
||||
}
|
||||
elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
|
||||
if (xcache_isset($uid."|".$family."|".$key)) {
|
||||
$val = xcache_get($uid."|".$family."|".$key);
|
||||
$a->config[$uid][$family][$key] = $val;
|
||||
|
||||
if ($val === '!<unset>!')
|
||||
return false;
|
||||
else
|
||||
return $val;
|
||||
}*/
|
||||
|
||||
|
||||
$ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
|
||||
$ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' ORDER BY `id` DESC LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
|
@ -116,22 +93,9 @@ class PConfig {
|
|||
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
|
||||
$a->config[$uid][$family][$key] = $val;
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($uid."|".$family."|".$key, $val, 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($uid."|".$family."|".$key, $val, 600);*/
|
||||
|
||||
return $val;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$a->config[$uid][$family][$key] = '!<unset>!';
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);*/
|
||||
}
|
||||
return $default_value;
|
||||
}
|
||||
|
@ -158,39 +122,37 @@ class PConfig {
|
|||
|
||||
global $a;
|
||||
|
||||
$stored = self::get($uid, $family, $key);
|
||||
|
||||
if ($stored == $value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// manage array value
|
||||
$dbvalue = (is_array($value) ? serialize($value):$value);
|
||||
|
||||
if(is_null(self::get($uid,$family,$key,null, true))) {
|
||||
$a->config[$uid][$family][$key] = $value;
|
||||
$ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
|
||||
|
||||
if (is_null($stored)) {
|
||||
$ret = q("INSERT INTO `pconfig` (`uid`, `cat`, `k`, `v`) VALUES (%d, '%s', '%s', '%s') ON DUPLICATE KEY UPDATE `v` = '%s'",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
if($ret)
|
||||
return $value;
|
||||
return $ret;
|
||||
}
|
||||
} else {
|
||||
$ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
|
||||
dbesc($dbvalue),
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
$a->config[$uid][$family][$key] = $value;
|
||||
|
||||
// If APC is enabled then store the data there, else try XCache
|
||||
/*if (function_exists("apc_store"))
|
||||
apc_store($uid."|".$family."|".$key, $value, 600);
|
||||
elseif (function_exists("xcache_set"))
|
||||
xcache_set($uid."|".$family."|".$key, $value, 600);*/
|
||||
|
||||
|
||||
if($ret)
|
||||
if ($ret) {
|
||||
return $value;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
@ -210,13 +172,17 @@ class PConfig {
|
|||
public static function delete($uid,$family,$key) {
|
||||
|
||||
global $a;
|
||||
if(x($a->config[$uid][$family],$key))
|
||||
|
||||
if (x($a->config[$uid][$family], $key)) {
|
||||
unset($a->config[$uid][$family][$key]);
|
||||
}
|
||||
|
||||
$ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ class Emailer {
|
|||
|
||||
// generate a mime boundary
|
||||
$mimeBoundary =rand(0,9)."-"
|
||||
.rand(10000000000,99999999999)."-"
|
||||
.rand(10000000000,99999999999)."=:"
|
||||
.rand(100000000,999999999)."-"
|
||||
.rand(100000000,999999999)."=:"
|
||||
.rand(10000,99999);
|
||||
|
||||
// generate a multipart/alternative message header
|
||||
|
|
|
@ -26,6 +26,7 @@ class ForumManager {
|
|||
* 'name' => forum name
|
||||
* 'id' => number of the key from the array
|
||||
* 'micro' => contact photo in format micro
|
||||
* 'thumb' => contact photo in format thumb
|
||||
*/
|
||||
public static function get_list($uid, $showhidden = true, $lastitem, $showprivate = false) {
|
||||
|
||||
|
@ -38,7 +39,7 @@ class ForumManager {
|
|||
$select = '(`forum` OR `prv`)';
|
||||
}
|
||||
|
||||
$contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro` FROM `contact`
|
||||
$contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro`, `contact`.`thumb` FROM `contact`
|
||||
WHERE `network`= 'dfrn' AND $select AND `uid` = %d
|
||||
AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
|
||||
AND `success_update` > `failure_update`
|
||||
|
@ -55,6 +56,7 @@ class ForumManager {
|
|||
'name' => $contact['name'],
|
||||
'id' => $contact['id'],
|
||||
'micro' => $contact['micro'],
|
||||
'thumb' => $contact['thumb'],
|
||||
);
|
||||
}
|
||||
return($forumlist);
|
||||
|
@ -86,7 +88,7 @@ class ForumManager {
|
|||
$total = count($contacts);
|
||||
$visible_forums = 10;
|
||||
|
||||
if(count($contacts)) {
|
||||
if(dbm::is_result($contacts)) {
|
||||
|
||||
$id = 0;
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* @file include/NotificationsManager.php
|
||||
* @brief Methods for read and write notifications from/to database
|
||||
* or for formatting notifications
|
||||
*/
|
||||
require_once('include/html2plain.php');
|
||||
require_once("include/datetime.php");
|
||||
require_once("include/bbcode.php");
|
||||
|
||||
/**
|
||||
* @brief Read and write notifications from/to database
|
||||
* @brief Methods for read and write notifications from/to database
|
||||
* or for formatting notifications
|
||||
*/
|
||||
class NotificationsManager {
|
||||
private $a;
|
||||
|
@ -44,7 +47,7 @@ class NotificationsManager {
|
|||
|
||||
|
||||
/**
|
||||
* @brief get all notifications for local_user()
|
||||
* @brief Get all notifications for local_user()
|
||||
*
|
||||
* @param array $filter optional Array "column name"=>value: filter query by columns values
|
||||
* @param string $order optional Space separated list of column to sort by. prepend name with "+" to sort ASC, "-" to sort DESC. Default to "-date"
|
||||
|
@ -78,17 +81,21 @@ class NotificationsManager {
|
|||
}
|
||||
$order_sql = implode(", ", $asOrder);
|
||||
|
||||
if ($limit!="") $limit = " LIMIT ".$limit;
|
||||
if($limit!="")
|
||||
$limit = " LIMIT ".$limit;
|
||||
|
||||
$r = q("SELECT * FROM `notify` WHERE `uid` = %d $filter_sql ORDER BY $order_sql $limit",
|
||||
intval(local_user())
|
||||
);
|
||||
if ($r!==false && count($r)>0) return $this->_set_extra($r);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $this->_set_extra($r);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get one note for local_user() by $id value
|
||||
* @brief Get one note for local_user() by $id value
|
||||
*
|
||||
* @param int $id
|
||||
* @return array note values or null if not found
|
||||
|
@ -98,7 +105,7 @@ class NotificationsManager {
|
|||
intval($id),
|
||||
intval(local_user())
|
||||
);
|
||||
if($r!==false && count($r)>0) {
|
||||
if(dbm::is_result($r)) {
|
||||
return $this->_set_extra($r)[0];
|
||||
}
|
||||
return null;
|
||||
|
@ -133,4 +140,671 @@ class NotificationsManager {
|
|||
intval(local_user())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief List of pages for the Notifications TabBar
|
||||
*
|
||||
* @param app $a The
|
||||
* @return array with with notifications TabBar data
|
||||
*/
|
||||
public function getTabs() {
|
||||
$tabs = array(
|
||||
array(
|
||||
'label' => t('System'),
|
||||
'url'=>'notifications/system',
|
||||
'sel'=> (($this->a->argv[1] == 'system') ? 'active' : ''),
|
||||
'id' => 'system-tab',
|
||||
'accesskey' => 'y',
|
||||
),
|
||||
array(
|
||||
'label' => t('Network'),
|
||||
'url'=>'notifications/network',
|
||||
'sel'=> (($this->a->argv[1] == 'network') ? 'active' : ''),
|
||||
'id' => 'network-tab',
|
||||
'accesskey' => 'w',
|
||||
),
|
||||
array(
|
||||
'label' => t('Personal'),
|
||||
'url'=>'notifications/personal',
|
||||
'sel'=> (($this->a->argv[1] == 'personal') ? 'active' : ''),
|
||||
'id' => 'personal-tab',
|
||||
'accesskey' => 'r',
|
||||
),
|
||||
array(
|
||||
'label' => t('Home'),
|
||||
'url' => 'notifications/home',
|
||||
'sel'=> (($this->a->argv[1] == 'home') ? 'active' : ''),
|
||||
'id' => 'home-tab',
|
||||
'accesskey' => 'h',
|
||||
),
|
||||
array(
|
||||
'label' => t('Introductions'),
|
||||
'url' => 'notifications/intros',
|
||||
'sel'=> (($this->a->argv[1] == 'intros') ? 'active' : ''),
|
||||
'id' => 'intro-tab',
|
||||
'accesskey' => 'i',
|
||||
),
|
||||
);
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format the notification query in an usable array
|
||||
*
|
||||
* @param array $notifs The array from the db query
|
||||
* @param string $ident The notifications identifier (e.g. network)
|
||||
* @return array
|
||||
* string 'label' => The type of the notification
|
||||
* string 'link' => URL to the source
|
||||
* string 'image' => The avatar image
|
||||
* string 'text' => The notification text
|
||||
* string 'when' => Relative date of the notification
|
||||
* bool 'seen' => Is the notification marked as "seen"
|
||||
*/
|
||||
private function formatNotifs($notifs, $ident = "") {
|
||||
|
||||
$notif = array();
|
||||
$arr = array();
|
||||
|
||||
if (dbm::is_result($notifs)) {
|
||||
|
||||
foreach ($notifs as $it) {
|
||||
// Because we use different db tables for the notification query
|
||||
// we have sometimes $it['unseen'] and sometimes $it['seen].
|
||||
// So we will have to transform $it['unseen']
|
||||
if($it['unseen'])
|
||||
$it['seen'] = ($it['unseen'] > 0 ? false : true);
|
||||
|
||||
// Depending on the identifier of the notification we need to use different defaults
|
||||
switch ($ident) {
|
||||
case 'system':
|
||||
$default_item_label = 'notify';
|
||||
$default_item_link = $this->a->get_baseurl(true).'/notify/view/'. $it['id'];
|
||||
$default_item_image = proxy_url($it['photo'], false, PROXY_SIZE_MICRO);
|
||||
$default_item_text = strip_tags(bbcode($it['msg']));
|
||||
$default_item_when = relative_date($it['date']);
|
||||
$default_tpl = $tpl_notify;
|
||||
break;
|
||||
|
||||
case 'home':
|
||||
$default_item_label = 'comment';
|
||||
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
|
||||
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
|
||||
$default_item_text = sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']);
|
||||
$default_item_when = relative_date($it['created']);
|
||||
$default_tpl = $tpl_item_comments;
|
||||
break;
|
||||
|
||||
default:
|
||||
$default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
|
||||
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
|
||||
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
|
||||
$default_item_text = (($it['id'] == $it['parent'])
|
||||
? sprintf( t("%s created a new post"), $it['author-name'])
|
||||
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
|
||||
$default_item_when = relative_date($it['created']);
|
||||
$default_tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
|
||||
|
||||
}
|
||||
|
||||
// Transform the different types of notification in an usable array
|
||||
switch($it['verb']){
|
||||
case ACTIVITY_LIKE:
|
||||
$notif = array(
|
||||
'label' => 'like',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'$image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
case ACTIVITY_DISLIKE:
|
||||
$notif = array(
|
||||
'label' => 'dislike',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
case ACTIVITY_ATTEND:
|
||||
$notif = array(
|
||||
'label' => 'attend',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s is attending %s's event"), $it['author-name'], $it['pname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
case ACTIVITY_ATTENDNO:
|
||||
$notif = array(
|
||||
'label' => 'attendno',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s is not attending %s's event"), $it['author-name'], $it['pname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
case ACTIVITY_ATTENDMAYBE:
|
||||
$notif = array(
|
||||
'label' => 'attendmaybe',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s may attend %s's event"), $it['author-name'], $it['pname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
case ACTIVITY_FRIEND:
|
||||
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
|
||||
$obj = parse_xml_string($xmlhead.$it['object']);
|
||||
$it['fname'] = $obj->title;
|
||||
|
||||
$notif = array(
|
||||
'label' => 'friend',
|
||||
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
|
||||
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
|
||||
'text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
|
||||
'when' => relative_date($it['created']),
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
$notif = array(
|
||||
'label' => $default_item_label,
|
||||
'link' => $default_item_link,
|
||||
'image' => $default_item_image,
|
||||
'text' => $default_item_text,
|
||||
'when' => $default_item_when,
|
||||
'seen' => $it['seen']
|
||||
);
|
||||
}
|
||||
|
||||
$arr[] = $notif;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Total number of network notifications
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @return int Number of network notifications
|
||||
*/
|
||||
private function networkTotal($seen = 0) {
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total`
|
||||
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
|
||||
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
|
||||
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
|
||||
$sql_seen",
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $r[0]['total'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get network notifications
|
||||
*
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @param int $start Start the query at this point
|
||||
* @param int $limit Maximum number of query results
|
||||
*
|
||||
* @return array with
|
||||
* string 'ident' => Notification identifier
|
||||
* int 'total' => Total number of available network notifications
|
||||
* array 'notifications' => Network notifications
|
||||
*/
|
||||
public function networkNotifs($seen = 0, $start = 0, $limit = 80) {
|
||||
$ident = 'network';
|
||||
$total = $this->networkTotal($seen);
|
||||
$notifs = array();
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
|
||||
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
|
||||
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
|
||||
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`
|
||||
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
|
||||
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
|
||||
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
|
||||
$sql_seen
|
||||
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
|
||||
intval(local_user()),
|
||||
intval($start),
|
||||
intval($limit)
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
$notifs = $this->formatNotifs($r, $ident);
|
||||
|
||||
$arr = array (
|
||||
'notifications' => $notifs,
|
||||
'ident' => $ident,
|
||||
'total' => $total,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Total number of system notifications
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @return int Number of system notifications
|
||||
*/
|
||||
private function systemTotal($seen = 0) {
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `seen` = 0 ";
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `notify` WHERE `uid` = %d $sql_seen",
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $r[0]['total'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get system notifications
|
||||
*
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @param int $start Start the query at this point
|
||||
* @param int $limit Maximum number of query results
|
||||
*
|
||||
* @return array with
|
||||
* string 'ident' => Notification identifier
|
||||
* int 'total' => Total number of available system notifications
|
||||
* array 'notifications' => System notifications
|
||||
*/
|
||||
public function systemNotifs($seen = 0, $start = 0, $limit = 80) {
|
||||
$ident = 'system';
|
||||
$total = $this->systemTotal($seen);
|
||||
$notifs = array();
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `seen` = 0 ";
|
||||
|
||||
$r = q("SELECT `id`, `photo`, `msg`, `date`, `seen` FROM `notify`
|
||||
WHERE `uid` = %d $sql_seen ORDER BY `date` DESC LIMIT %d, %d ",
|
||||
intval(local_user()),
|
||||
intval($start),
|
||||
intval($limit)
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
$notifs = $this->formatNotifs($r, $ident);
|
||||
|
||||
$arr = array (
|
||||
'notifications' => $notifs,
|
||||
'ident' => $ident,
|
||||
'total' => $total,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Addional SQL query string for the personal notifications
|
||||
*
|
||||
* @return string The additional sql query
|
||||
*/
|
||||
private function _personal_sql_extra() {
|
||||
$myurl = $this->a->get_baseurl(true) . '/profile/'. $this->a->user['nickname'];
|
||||
$myurl = substr($myurl,strpos($myurl,'://')+3);
|
||||
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
|
||||
$diasp_url = str_replace('/profile/','/u/',$myurl);
|
||||
$sql_extra = sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
|
||||
dbesc($myurl . '$'),
|
||||
dbesc($myurl . '\\]'),
|
||||
dbesc($diasp_url . '\\]')
|
||||
);
|
||||
|
||||
return $sql_extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Total number of personal notifications
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @return int Number of personal notifications
|
||||
*/
|
||||
private function personalTotal($seen = 0) {
|
||||
$sql_seen = "";
|
||||
$sql_extra = $this->_personal_sql_extra();
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total`
|
||||
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
|
||||
WHERE `item`.`visible` = 1
|
||||
$sql_extra
|
||||
$sql_seen
|
||||
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 " ,
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $r[0]['total'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get personal notifications
|
||||
*
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @param int $start Start the query at this point
|
||||
* @param int $limit Maximum number of query results
|
||||
*
|
||||
* @return array with
|
||||
* string 'ident' => Notification identifier
|
||||
* int 'total' => Total number of available personal notifications
|
||||
* array 'notifications' => Personal notifications
|
||||
*/
|
||||
public function personalNotifs($seen = 0, $start = 0, $limit = 80) {
|
||||
$ident = 'personal';
|
||||
$total = $this->personalTotal($seen);
|
||||
$sql_extra = $this->_personal_sql_extra();
|
||||
$notifs = array();
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
|
||||
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
|
||||
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`,
|
||||
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
|
||||
WHERE `item`.`visible` = 1
|
||||
$sql_extra
|
||||
$sql_seen
|
||||
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
|
||||
ORDER BY `item`.`created` DESC LIMIT %d, %d " ,
|
||||
intval(local_user()),
|
||||
intval($start),
|
||||
intval($limit)
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
$notifs = $this->formatNotifs($r, $ident);
|
||||
|
||||
$arr = array (
|
||||
'notifications' => $notifs,
|
||||
'ident' => $ident,
|
||||
'total' => $total,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Total number of home notifications
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @return int Number of home notifications
|
||||
*/
|
||||
private function homeTotal($seen = 0) {
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `item`
|
||||
WHERE `item`.`visible` = 1 AND
|
||||
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
|
||||
$sql_seen",
|
||||
intval(local_user())
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $r[0]['total'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get home notifications
|
||||
*
|
||||
* @param int|string $seen
|
||||
* If 0 only include notifications into the query
|
||||
* which aren't marked as "seen"
|
||||
* @param int $start Start the query at this point
|
||||
* @param int $limit Maximum number of query results
|
||||
*
|
||||
* @return array with
|
||||
* string 'ident' => Notification identifier
|
||||
* int 'total' => Total number of available home notifications
|
||||
* array 'notifications' => Home notifications
|
||||
*/
|
||||
public function homeNotifs($seen = 0, $start = 0, $limit = 80) {
|
||||
$ident = 'home';
|
||||
$total = $this->homeTotal($seen);
|
||||
$notifs = array();
|
||||
$sql_seen = "";
|
||||
|
||||
if($seen === 0)
|
||||
$sql_seen = " AND `item`.`unseen` = 1 ";
|
||||
|
||||
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
|
||||
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
|
||||
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
|
||||
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
|
||||
WHERE `item`.`visible` = 1 AND
|
||||
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
|
||||
$sql_seen
|
||||
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
|
||||
intval(local_user()),
|
||||
intval($start),
|
||||
intval($limit)
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
$notifs = $this->formatNotifs($r, $ident);
|
||||
|
||||
$arr = array (
|
||||
'notifications' => $notifs,
|
||||
'ident' => $ident,
|
||||
'total' => $total,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Total number of introductions
|
||||
* @param bool $all
|
||||
* If false only include introductions into the query
|
||||
* which aren't marked as ignored
|
||||
* @return int Number of introductions
|
||||
*/
|
||||
private function introTotal($all = false) {
|
||||
$sql_extra = "";
|
||||
|
||||
if(!$all)
|
||||
$sql_extra = " AND `ignore` = 0 ";
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `intro`
|
||||
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
return $r[0]['total'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get introductions
|
||||
*
|
||||
* @param bool $all
|
||||
* If false only include introductions into the query
|
||||
* which aren't marked as ignored
|
||||
* @param int $start Start the query at this point
|
||||
* @param int $limit Maximum number of query results
|
||||
*
|
||||
* @return array with
|
||||
* string 'ident' => Notification identifier
|
||||
* int 'total' => Total number of available introductions
|
||||
* array 'notifications' => Introductions
|
||||
*/
|
||||
public function introNotifs($all = false, $start = 0, $limit = 80) {
|
||||
$ident = 'introductions';
|
||||
$total = $this->introTotal($seen);
|
||||
$notifs = array();
|
||||
$sql_extra = "";
|
||||
|
||||
if(!$all)
|
||||
$sql_extra = " AND `ignore` = 0 ";
|
||||
|
||||
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact
|
||||
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`,
|
||||
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
|
||||
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
|
||||
`gcontact`.`network` AS `gnetwork`
|
||||
FROM `intro`
|
||||
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
|
||||
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
|
||||
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
|
||||
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0
|
||||
LIMIT %d, %d",
|
||||
intval($_SESSION['uid']),
|
||||
intval($start),
|
||||
intval($limit)
|
||||
);
|
||||
|
||||
if(dbm::is_result($r))
|
||||
$notifs = $this->formatIntros($r);
|
||||
|
||||
$arr = array (
|
||||
'ident' => $ident,
|
||||
'total' => $total,
|
||||
'notifications' => $notifs,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format the notification query in an usable array
|
||||
*
|
||||
* @param array $intros The array from the db query
|
||||
* @return array with the introductions
|
||||
*/
|
||||
private function formatIntros($intros) {
|
||||
$knowyou = '';
|
||||
|
||||
foreach($intros as $it) {
|
||||
// There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
|
||||
// We have to distinguish between these two because they use different data.
|
||||
|
||||
// Contact suggestions
|
||||
if($it['fid']) {
|
||||
|
||||
$return_addr = bin2hex($this->a->user['nickname'] . '@' . $this->a->get_hostname() . (($this->a->path) ? '/' . $this->a->path : ''));
|
||||
|
||||
$intro = array(
|
||||
'label' => 'friend_suggestion',
|
||||
'notify_type' => t('Friend Suggestion'),
|
||||
'intro_id' => $it['intro_id'],
|
||||
'madeby' => $it['name'],
|
||||
'contact_id' => $it['contact-id'],
|
||||
'photo' => ((x($it,'fphoto')) ? proxy_url($it['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
|
||||
'name' => $it['fname'],
|
||||
'url' => zrl($it['furl']),
|
||||
'hidden' => $it['hidden'] == 1,
|
||||
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
|
||||
|
||||
'knowyou' => $knowyou,
|
||||
'note' => $it['note'],
|
||||
'request' => $it['frequest'] . '?addr=' . $return_addr,
|
||||
|
||||
);
|
||||
|
||||
// Normal connection requests
|
||||
} else {
|
||||
|
||||
// Probe the contact url to get missing data
|
||||
$ret = probe_url($it["url"]);
|
||||
|
||||
if ($it['gnetwork'] == "")
|
||||
$it['gnetwork'] = $ret["network"];
|
||||
|
||||
// Don't show these data until you are connected. Diaspora is doing the same.
|
||||
if($it['gnetwork'] === NETWORK_DIASPORA) {
|
||||
$it['glocation'] = "";
|
||||
$it['gabout'] = "";
|
||||
$it['ggender'] = "";
|
||||
}
|
||||
$intro = array(
|
||||
'label' => (($it['network'] !== NETWORK_OSTATUS) ? 'friend_request' : 'follower'),
|
||||
'notify_type' => (($it['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
|
||||
'dfrn_id' => $it['issued-id'],
|
||||
'uid' => $_SESSION['uid'],
|
||||
'intro_id' => $it['intro_id'],
|
||||
'contact_id' => $it['contact-id'],
|
||||
'photo' => ((x($it,'photo')) ? proxy_url($it['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
|
||||
'name' => $it['name'],
|
||||
'location' => bbcode($it['glocation'], false, false),
|
||||
'about' => bbcode($it['gabout'], false, false),
|
||||
'keywords' => $it['gkeywords'],
|
||||
'gender' => $it['ggender'],
|
||||
'hidden' => $it['hidden'] == 1,
|
||||
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
|
||||
'url' => $it['url'],
|
||||
'zrl' => zrl($it['url']),
|
||||
'addr' => $ret['addr'],
|
||||
'network' => $it['gnetwork'],
|
||||
'knowyou' => $it['knowyou'],
|
||||
'note' => $it['note'],
|
||||
);
|
||||
}
|
||||
|
||||
$arr[] = $intro;
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* @file include/Photo.php
|
||||
* @brief This file contains the Photo class for image processing
|
||||
*/
|
||||
|
||||
require_once("include/photos.php");
|
||||
|
||||
if(! class_exists("Photo")) {
|
||||
class Photo {
|
||||
|
||||
private $image;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Put back gd stuff, not everybody have Imagick
|
||||
*/
|
||||
private $imagick;
|
||||
|
@ -16,14 +21,13 @@ class Photo {
|
|||
private $types;
|
||||
|
||||
/**
|
||||
* supported mimetypes and corresponding file extensions
|
||||
* @brief supported mimetypes and corresponding file extensions
|
||||
*/
|
||||
static function supportedTypes() {
|
||||
if (class_exists('Imagick')) {
|
||||
/**
|
||||
* Imagick::queryFormats won't help us a lot there...
|
||||
* At least, not yet, other parts of friendica uses this array
|
||||
*/
|
||||
|
||||
// Imagick::queryFormats won't help us a lot there...
|
||||
// At least, not yet, other parts of friendica uses this array
|
||||
$t = array(
|
||||
'image/jpeg' => 'jpg',
|
||||
'image/png' => 'png',
|
||||
|
@ -32,7 +36,9 @@ class Photo {
|
|||
} else {
|
||||
$t = array();
|
||||
$t['image/jpeg'] ='jpg';
|
||||
if (imagetypes() & IMG_PNG) $t['image/png'] = 'png';
|
||||
if (imagetypes() & IMG_PNG) {
|
||||
$t['image/png'] = 'png';
|
||||
}
|
||||
}
|
||||
|
||||
return $t;
|
||||
|
@ -71,7 +77,8 @@ class Photo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Maps Mime types to Imagick formats
|
||||
* @brief Maps Mime types to Imagick formats
|
||||
* @return arr With with image formats (mime type as key)
|
||||
*/
|
||||
public function get_FormatsMap() {
|
||||
$m = array(
|
||||
|
@ -87,13 +94,12 @@ class Photo {
|
|||
$this->image = new Imagick();
|
||||
try {
|
||||
$this->image->readImageBlob($data);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Imagick couldn't use the data
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Setup the image to the format it will be saved to
|
||||
*/
|
||||
$map = $this->get_FormatsMap();
|
||||
|
@ -103,15 +109,16 @@ class Photo {
|
|||
// Always coalesce, if it is not a multi-frame image it won't hurt anyway
|
||||
$this->image = $this->image->coalesceImages();
|
||||
|
||||
/**
|
||||
/*
|
||||
* setup the compression here, so we'll do it only once
|
||||
*/
|
||||
switch($this->getType()){
|
||||
case "image/png":
|
||||
$quality = get_config('system', 'png_quality');
|
||||
if((! $quality) || ($quality > 9))
|
||||
if ((! $quality) || ($quality > 9)) {
|
||||
$quality = PNG_QUALITY;
|
||||
/**
|
||||
}
|
||||
/*
|
||||
* From http://www.imagemagick.org/script/command-line-options.php#quality:
|
||||
*
|
||||
* 'For the MNG and PNG image formats, the quality value sets
|
||||
|
@ -124,8 +131,9 @@ class Photo {
|
|||
break;
|
||||
case "image/jpeg":
|
||||
$quality = get_config('system', 'jpeg_quality');
|
||||
if((! $quality) || ($quality > 100))
|
||||
if ((! $quality) || ($quality > 100)) {
|
||||
$quality = JPEG_QUALITY;
|
||||
}
|
||||
$this->image->setCompressionQuality($quality);
|
||||
}
|
||||
|
||||
|
@ -139,7 +147,7 @@ class Photo {
|
|||
|
||||
$this->valid = false;
|
||||
$this->image = @imagecreatefromstring($data);
|
||||
if($this->image !== FALSE) {
|
||||
if ($this->image !== false) {
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
$this->valid = true;
|
||||
|
@ -153,32 +161,38 @@ class Photo {
|
|||
}
|
||||
|
||||
public function is_valid() {
|
||||
if($this->is_imagick())
|
||||
return ($this->image !== FALSE);
|
||||
if ($this->is_imagick()) {
|
||||
return ($this->image !== false);
|
||||
}
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
public function getWidth() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->is_imagick())
|
||||
if ($this->is_imagick()) {
|
||||
return $this->image->getImageWidth();
|
||||
}
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function getHeight() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->is_imagick())
|
||||
if ($this->is_imagick()) {
|
||||
return $this->image->getImageHeight();
|
||||
}
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
public function getImage() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
/* Clean it */
|
||||
|
@ -189,30 +203,34 @@ class Photo {
|
|||
}
|
||||
|
||||
public function getType() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getExt() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->types[$this->getType()];
|
||||
}
|
||||
|
||||
public function scaleImage($max) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$width = $this->getWidth();
|
||||
$height = $this->getHeight();
|
||||
|
||||
$dest_width = $dest_height = 0;
|
||||
|
||||
if((! $width)|| (! $height))
|
||||
return FALSE;
|
||||
if ((! $width)|| (! $height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($width > $max && $height > $max) {
|
||||
|
||||
|
@ -222,25 +240,19 @@ class Photo {
|
|||
if ((($height * 9) / 16) > $width) {
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
}
|
||||
|
||||
} elseif ($width > $height) {
|
||||
// else constrain both dimensions
|
||||
|
||||
elseif($width > $height) {
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$dest_width = intval(($width * $max) / $height);
|
||||
$dest_height = $max;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if ($width > $max) {
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if ($height > $max) {
|
||||
|
||||
// very tall image (greater than 16:9)
|
||||
|
@ -249,13 +261,11 @@ class Photo {
|
|||
if ((($height * 9) / 16) > $width) {
|
||||
$dest_width = $width;
|
||||
$dest_height = $height;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$dest_width = intval(($width * $max) / $height);
|
||||
$dest_height = $max;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$dest_width = $width;
|
||||
$dest_height = $height;
|
||||
}
|
||||
|
@ -264,7 +274,7 @@ class Photo {
|
|||
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
/**
|
||||
/*
|
||||
* If it is not animated, there will be only one iteration here,
|
||||
* so don't bother checking
|
||||
*/
|
||||
|
@ -289,18 +299,22 @@ class Photo {
|
|||
$dest = imagecreatetruecolor($dest_width, $dest_height);
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
if ($this->type=='image/png') {
|
||||
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
}
|
||||
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
|
||||
if($this->image)
|
||||
if ($this->image) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
$this->image = $dest;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
}
|
||||
|
||||
public function rotate($degrees) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
$this->image->setFirstIterator();
|
||||
|
@ -316,14 +330,19 @@ class Photo {
|
|||
}
|
||||
|
||||
public function flip($horiz = true, $vert = false) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
$this->image->setFirstIterator();
|
||||
do {
|
||||
if($horiz) $this->image->flipImage();
|
||||
if($vert) $this->image->flopImage();
|
||||
if ($horiz) {
|
||||
$this->image->flipImage();
|
||||
}
|
||||
if ($vert) {
|
||||
$this->image->flopImage();
|
||||
}
|
||||
} while ($this->image->nextImage());
|
||||
return;
|
||||
}
|
||||
|
@ -361,19 +380,22 @@ class Photo {
|
|||
}
|
||||
|
||||
$this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
// based off comment on http://php.net/manual/en/function.imagerotate.php
|
||||
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') )
|
||||
if ((!function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$exif = @exif_read_data($filename,null,true);
|
||||
if(! $exif)
|
||||
if (!$exif) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ort = $exif['IFD0']['Orientation'];
|
||||
|
||||
|
@ -421,8 +443,9 @@ class Photo {
|
|||
|
||||
|
||||
public function scaleImageUp($min) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$width = $this->getWidth();
|
||||
|
@ -430,46 +453,47 @@ class Photo {
|
|||
|
||||
$dest_width = $dest_height = 0;
|
||||
|
||||
if((! $width)|| (! $height))
|
||||
return FALSE;
|
||||
if ((!$width)|| (!$height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($width < $min && $height < $min) {
|
||||
if ($width > $height) {
|
||||
$dest_width = $min;
|
||||
$dest_height = intval(($height * $min) / $width);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$dest_width = intval(($width * $min) / $height);
|
||||
$dest_height = $min;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if ($width < $min) {
|
||||
$dest_width = $min;
|
||||
$dest_height = intval(($height * $min) / $width);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if ($height < $min) {
|
||||
$dest_width = intval(($width * $min) / $height);
|
||||
$dest_height = $min;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$dest_width = $width;
|
||||
$dest_height = $height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->is_imagick())
|
||||
if ($this->is_imagick()) {
|
||||
return $this->scaleImage($dest_width, $dest_height);
|
||||
}
|
||||
|
||||
$dest = imagecreatetruecolor($dest_width, $dest_height);
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
if ($this->type=='image/png') {
|
||||
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
}
|
||||
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
|
||||
if($this->image)
|
||||
if ($this->image) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
$this->image = $dest;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
@ -478,8 +502,9 @@ class Photo {
|
|||
|
||||
|
||||
public function scaleImageSquare($dim) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
$this->image->setFirstIterator();
|
||||
|
@ -492,10 +517,13 @@ class Photo {
|
|||
$dest = imagecreatetruecolor($dim, $dim);
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
if ($this->type=='image/png') {
|
||||
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
}
|
||||
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height);
|
||||
if($this->image)
|
||||
if ($this->image) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
$this->image = $dest;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
@ -503,14 +531,15 @@ class Photo {
|
|||
|
||||
|
||||
public function cropImage($max, $x, $y, $w, $h) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
$this->image->setFirstIterator();
|
||||
do {
|
||||
$this->image->cropImage($w, $h, $x, $y);
|
||||
/**
|
||||
/*
|
||||
* We need to remove the canva,
|
||||
* or the image is not resized to the crop:
|
||||
* http://php.net/manual/en/imagick.cropimage.php#97232
|
||||
|
@ -523,18 +552,22 @@ class Photo {
|
|||
$dest = imagecreatetruecolor($max, $max);
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
if ($this->type=='image/png') {
|
||||
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
|
||||
}
|
||||
imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h);
|
||||
if($this->image)
|
||||
if ($this->image) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
$this->image = $dest;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
}
|
||||
|
||||
public function saveImage($path) {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$string = $this->imageString();
|
||||
|
||||
|
@ -546,8 +579,9 @@ class Photo {
|
|||
}
|
||||
|
||||
public function imageString() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
if (!$this->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->is_imagick()) {
|
||||
/* Clean it */
|
||||
|
@ -556,7 +590,7 @@ class Photo {
|
|||
return $string;
|
||||
}
|
||||
|
||||
$quality = FALSE;
|
||||
$quality = false;
|
||||
|
||||
ob_start();
|
||||
|
||||
|
@ -566,15 +600,17 @@ class Photo {
|
|||
switch($this->getType()){
|
||||
case "image/png":
|
||||
$quality = get_config('system', 'png_quality');
|
||||
if((! $quality) || ($quality > 9))
|
||||
if ((!$quality) || ($quality > 9)) {
|
||||
$quality = PNG_QUALITY;
|
||||
imagepng($this->image,NULL, $quality);
|
||||
}
|
||||
imagepng($this->image, null, $quality);
|
||||
break;
|
||||
case "image/jpeg":
|
||||
$quality = get_config('system', 'jpeg_quality');
|
||||
if((! $quality) || ($quality > 100))
|
||||
if ((!$quality) || ($quality > 100)) {
|
||||
$quality = JPEG_QUALITY;
|
||||
imagejpeg($this->image,NULL,$quality);
|
||||
}
|
||||
imagejpeg($this->image, null, $quality);
|
||||
}
|
||||
$string = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
@ -586,23 +622,24 @@ class Photo {
|
|||
|
||||
public function store($uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
|
||||
|
||||
$r = q("select `guid` from photo where `resource-id` = '%s' and `guid` != '' limit 1",
|
||||
$r = q("SELECT `guid` FROM `photo` WHERE `resource-id` = '%s' AND `guid` != '' LIMIT 1",
|
||||
dbesc($rid)
|
||||
);
|
||||
if(count($r))
|
||||
if (dbm::is_result($r)) {
|
||||
$guid = $r[0]['guid'];
|
||||
else
|
||||
} else {
|
||||
$guid = get_guid();
|
||||
}
|
||||
|
||||
$x = q("select id from photo where `resource-id` = '%s' and uid = %d and `contact-id` = %d and `scale` = %d limit 1",
|
||||
$x = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `contact-id` = %d AND `scale` = %d LIMIT 1",
|
||||
dbesc($rid),
|
||||
intval($uid),
|
||||
intval($cid),
|
||||
intval($scale)
|
||||
);
|
||||
if(count($x)) {
|
||||
if (dbm::is_result($x)) {
|
||||
$r = q("UPDATE `photo`
|
||||
set `uid` = %d,
|
||||
SET `uid` = %d,
|
||||
`contact-id` = %d,
|
||||
`guid` = '%s',
|
||||
`resource-id` = '%s',
|
||||
|
@ -621,7 +658,7 @@ class Photo {
|
|||
`allow_gid` = '%s',
|
||||
`deny_cid` = '%s',
|
||||
`deny_gid` = '%s'
|
||||
where id = %d",
|
||||
WHERE `id` = %d",
|
||||
|
||||
intval($uid),
|
||||
intval($cid),
|
||||
|
@ -644,8 +681,7 @@ class Photo {
|
|||
dbesc($deny_gid),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$r = q("INSERT INTO `photo`
|
||||
(`uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`)
|
||||
VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s')",
|
||||
|
@ -670,9 +706,15 @@ class Photo {
|
|||
dbesc($deny_gid)
|
||||
);
|
||||
}
|
||||
|
||||
// Update the cached values
|
||||
if ($album != 'Contact Photos') {
|
||||
photo_albums($uid, true);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -711,7 +753,9 @@ function guess_image_type($filename, $fromcurl=false) {
|
|||
$types = Photo::supportedTypes();
|
||||
$type = "image/jpeg";
|
||||
foreach ($types as $m => $e){
|
||||
if ($ext==$e) $type = $m;
|
||||
if ($ext == $e) {
|
||||
$type = $m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -733,10 +777,11 @@ function guess_image_type($filename, $fromcurl=false) {
|
|||
function update_contact_avatar($avatar, $uid, $cid, $force = false) {
|
||||
|
||||
$r = q("SELECT `avatar`, `photo`, `thumb`, `micro` FROM `contact` WHERE `id` = %d LIMIT 1", intval($cid));
|
||||
if (!$r)
|
||||
if (!dbm::is_result($r)) {
|
||||
return false;
|
||||
else
|
||||
} else {
|
||||
$data = array($r[0]["photo"], $r[0]["thumb"], $r[0]["micro"]);
|
||||
}
|
||||
|
||||
if (($r[0]["avatar"] != $avatar) OR $force) {
|
||||
$photos = import_profile_photo($avatar, $uid, $cid, true);
|
||||
|
@ -756,11 +801,11 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
|
|||
|
||||
$a = get_app();
|
||||
|
||||
$r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1",
|
||||
$r = q("SELECT `resource-id` FROM `photo` WHERE `uid` = %d AND `contact-id` = %d AND `scale` = 4 AND `album` = 'Contact Photos' LIMIT 1",
|
||||
intval($uid),
|
||||
intval($cid)
|
||||
);
|
||||
if(count($r) && strlen($r[0]['resource-id'])) {
|
||||
if (dbm::is_result($r) && strlen($r[0]['resource-id'])) {
|
||||
$hash = $r[0]['resource-id'];
|
||||
} else {
|
||||
$hash = photo_new_resource();
|
||||
|
@ -771,8 +816,9 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
|
|||
$filename = basename($photo);
|
||||
$img_str = fetch_url($photo, true);
|
||||
|
||||
if ($quit_on_error AND ($img_str == ""))
|
||||
if ($quit_on_error AND ($img_str == "")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = guess_image_type($photo, true);
|
||||
$img = new Photo($img_str, $type);
|
||||
|
@ -796,17 +842,20 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
|
|||
|
||||
$r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6);
|
||||
|
||||
if($r === false)
|
||||
if ($r === false) {
|
||||
$photo_failure = true;
|
||||
}
|
||||
|
||||
$photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt();
|
||||
$thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt();
|
||||
$micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt();
|
||||
} else
|
||||
} else {
|
||||
$photo_failure = true;
|
||||
}
|
||||
|
||||
if($photo_failure AND $quit_on_error)
|
||||
if ($photo_failure AND $quit_on_error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($photo_failure) {
|
||||
$photo = $a->get_baseurl() . '/images/person-175.jpg';
|
||||
|
@ -823,17 +872,13 @@ function get_photo_info($url) {
|
|||
|
||||
$data = Cache::get($url);
|
||||
|
||||
// Unserialise to be able to check in the next step if the cached data is alright.
|
||||
if (!is_null($data))
|
||||
$data = unserialize($data);
|
||||
|
||||
if (is_null($data) OR !$data) {
|
||||
$img_str = fetch_url($url, true, $redirects, 4);
|
||||
$filesize = strlen($img_str);
|
||||
|
||||
if (function_exists("getimagesizefromstring"))
|
||||
if (function_exists("getimagesizefromstring")) {
|
||||
$data = getimagesizefromstring($img_str);
|
||||
else {
|
||||
} else {
|
||||
$tempfile = tempnam(get_temppath(), "cache");
|
||||
|
||||
$a = get_app();
|
||||
|
@ -845,10 +890,11 @@ function get_photo_info($url) {
|
|||
unlink($tempfile);
|
||||
}
|
||||
|
||||
if ($data)
|
||||
if ($data) {
|
||||
$data["size"] = $filesize;
|
||||
}
|
||||
|
||||
Cache::set($url, serialize($data));
|
||||
Cache::set($url, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
@ -858,8 +904,9 @@ function scale_image($width, $height, $max) {
|
|||
|
||||
$dest_width = $dest_height = 0;
|
||||
|
||||
if((!$width) || (!$height))
|
||||
return FALSE;
|
||||
if ((!$width) || (!$height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($width > $max && $height > $max) {
|
||||
|
||||
|
@ -905,10 +952,10 @@ function scale_image($width, $height, $max) {
|
|||
|
||||
function store_photo($a, $uid, $imagedata = "", $url = "") {
|
||||
$r = q("SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
|
||||
WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1",
|
||||
WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 AND `contact`.`self` = 1 LIMIT 1",
|
||||
intval($uid));
|
||||
|
||||
if(!count($r)) {
|
||||
if (!dbm::is_result($r)) {
|
||||
logger("Can't detect user data for uid ".$uid, LOGGER_DEBUG);
|
||||
return(array());
|
||||
}
|
||||
|
@ -976,10 +1023,12 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
|
|||
unlink($tempfile);
|
||||
|
||||
$max_length = get_config('system', 'max_image_length');
|
||||
if(! $max_length)
|
||||
if (! $max_length) {
|
||||
$max_length = MAX_IMAGE_LENGTH;
|
||||
if($max_length > 0)
|
||||
}
|
||||
if ($max_length > 0) {
|
||||
$ph->scaleImage($max_length);
|
||||
}
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
@ -1003,44 +1052,50 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
|
|||
$image = array("page" => $a->get_baseurl().'/photos/'.$page_owner_nick.'/image/'.$hash,
|
||||
"full" => $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt());
|
||||
|
||||
if($width > 800 || $height > 800)
|
||||
if ($width > 800 || $height > 800) {
|
||||
$image["large"] = $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt();
|
||||
}
|
||||
|
||||
if ($width > 640 || $height > 640) {
|
||||
$ph->scaleImage(640);
|
||||
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm);
|
||||
if($r)
|
||||
if ($r) {
|
||||
$image["medium"] = $a->get_baseurl()."/photo/{$hash}-1.".$ph->getExt();
|
||||
}
|
||||
}
|
||||
|
||||
if ($width > 320 || $height > 320) {
|
||||
$ph->scaleImage(320);
|
||||
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm);
|
||||
if($r)
|
||||
if ($r) {
|
||||
$image["small"] = $a->get_baseurl()."/photo/{$hash}-2.".$ph->getExt();
|
||||
}
|
||||
}
|
||||
|
||||
if ($width > 160 AND $height > 160) {
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
|
||||
$min = $ph->getWidth();
|
||||
if ($min > 160)
|
||||
if ($min > 160) {
|
||||
$x = ($min - 160) / 2;
|
||||
}
|
||||
|
||||
if ($ph->getHeight() < $min) {
|
||||
$min = $ph->getHeight();
|
||||
if ($min > 160)
|
||||
if ($min > 160) {
|
||||
$y = ($min - 160) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
$min = 160;
|
||||
$ph->cropImage(160, $x, $y, $min, $min);
|
||||
|
||||
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm);
|
||||
if($r)
|
||||
if ($r) {
|
||||
$image["thumb"] = $a->get_baseurl()."/photo/{$hash}-3.".$ph->getExt();
|
||||
}
|
||||
}
|
||||
|
||||
// Set the full image as preview image. This will be overwritten, if the picture is larger than 640.
|
||||
$image["preview"] = $image["full"];
|
||||
|
@ -1053,9 +1108,9 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
|
|||
//if (isset($image["small"]))
|
||||
// $image["preview"] = $image["small"];
|
||||
|
||||
if (isset($image["medium"]))
|
||||
if (isset($image["medium"])) {
|
||||
$image["preview"] = $image["medium"];
|
||||
}
|
||||
|
||||
return($image);
|
||||
}
|
||||
|
||||
|
|
1139
include/Probe.php
Normal file
1139
include/Probe.php
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,335 +1,5 @@
|
|||
<?php
|
||||
|
||||
require_once('library/HTML5/Parser.php');
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/feed.php');
|
||||
|
||||
if(! function_exists('scrape_dfrn')) {
|
||||
function scrape_dfrn($url, $dont_probe = false) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$ret = array();
|
||||
|
||||
logger('scrape_dfrn: url=' . $url);
|
||||
|
||||
// Try to fetch the data from noscrape. This is faster than parsing the HTML
|
||||
$noscrape = str_replace("/hcard/", "/noscrape/", $url);
|
||||
$noscrapejson = fetch_url($noscrape);
|
||||
$noscrapedata = array();
|
||||
if ($noscrapejson) {
|
||||
$noscrapedata = json_decode($noscrapejson, true);
|
||||
|
||||
if (is_array($noscrapedata)) {
|
||||
if ($noscrapedata["nick"] != "")
|
||||
return($noscrapedata);
|
||||
else
|
||||
unset($noscrapedata["nick"]);
|
||||
} else
|
||||
$noscrapedata = array();
|
||||
}
|
||||
|
||||
$s = fetch_url($url);
|
||||
|
||||
if (!$s)
|
||||
return $ret;
|
||||
|
||||
if (!$dont_probe) {
|
||||
$probe = probe_url($url);
|
||||
|
||||
if (isset($probe["addr"]))
|
||||
$ret["addr"] = $probe["addr"];
|
||||
}
|
||||
|
||||
$headers = $a->get_curl_headers();
|
||||
logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG);
|
||||
|
||||
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
// don't try and run feeds through the html5 parser
|
||||
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$dom = HTML5_Parser::parse($s);
|
||||
} catch (DOMException $e) {
|
||||
logger('scrape_dfrn: parse error: ' . $e);
|
||||
}
|
||||
|
||||
if(! $dom)
|
||||
return $ret;
|
||||
|
||||
$items = $dom->getElementsByTagName('link');
|
||||
|
||||
// get DFRN link elements
|
||||
|
||||
foreach($items as $item) {
|
||||
$x = $item->getAttribute('rel');
|
||||
if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml'))
|
||||
$ret['feed_atom'] = $item->getAttribute('href');
|
||||
if(substr($x,0,5) == "dfrn-") {
|
||||
$ret[$x] = $item->getAttribute('href');
|
||||
}
|
||||
if($x === 'lrdd') {
|
||||
$decoded = urldecode($item->getAttribute('href'));
|
||||
if(preg_match('/acct:([^@]*)@/',$decoded,$matches))
|
||||
$ret['nick'] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Pull out hCard profile elements
|
||||
|
||||
$largest_photo = 0;
|
||||
|
||||
$items = $dom->getElementsByTagName('*');
|
||||
foreach($items as $item) {
|
||||
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
|
||||
$level2 = $item->getElementsByTagName('*');
|
||||
foreach($level2 as $x) {
|
||||
if(attribute_contains($x->getAttribute('class'),'fn')) {
|
||||
$ret['fn'] = $x->textContent;
|
||||
}
|
||||
if((attribute_contains($x->getAttribute('class'),'photo'))
|
||||
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
|
||||
$size = intval($x->getAttribute('width'));
|
||||
// dfrn prefers 175, so if we find this, we set largest_size so it can't be topped.
|
||||
if(($size > $largest_photo) || ($size == 175) || (! $largest_photo)) {
|
||||
$ret['photo'] = $x->getAttribute('src');
|
||||
$largest_photo = (($size == 175) ? 9999 : $size);
|
||||
}
|
||||
}
|
||||
if(attribute_contains($x->getAttribute('class'),'key')) {
|
||||
$ret['key'] = $x->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_merge($ret, $noscrapedata);
|
||||
}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(! function_exists('validate_dfrn')) {
|
||||
function validate_dfrn($a) {
|
||||
$errors = 0;
|
||||
if(! x($a,'key'))
|
||||
$errors ++;
|
||||
if(! x($a,'dfrn-request'))
|
||||
$errors ++;
|
||||
if(! x($a,'dfrn-confirm'))
|
||||
$errors ++;
|
||||
if(! x($a,'dfrn-notify'))
|
||||
$errors ++;
|
||||
if(! x($a,'dfrn-poll'))
|
||||
$errors ++;
|
||||
return $errors;
|
||||
}}
|
||||
|
||||
if(! function_exists('scrape_meta')) {
|
||||
function scrape_meta($url) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$ret = array();
|
||||
|
||||
logger('scrape_meta: url=' . $url);
|
||||
|
||||
$s = fetch_url($url);
|
||||
|
||||
if(! $s)
|
||||
return $ret;
|
||||
|
||||
$headers = $a->get_curl_headers();
|
||||
logger('scrape_meta: headers=' . $headers, LOGGER_DEBUG);
|
||||
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
// don't try and run feeds through the html5 parser
|
||||
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$dom = HTML5_Parser::parse($s);
|
||||
} catch (DOMException $e) {
|
||||
logger('scrape_meta: parse error: ' . $e);
|
||||
}
|
||||
|
||||
if(! $dom)
|
||||
return $ret;
|
||||
|
||||
$items = $dom->getElementsByTagName('meta');
|
||||
|
||||
// get DFRN link elements
|
||||
|
||||
foreach($items as $item) {
|
||||
$x = $item->getAttribute('name');
|
||||
if(substr($x,0,5) == "dfrn-")
|
||||
$ret[$x] = $item->getAttribute('content');
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}}
|
||||
|
||||
|
||||
if(! function_exists('scrape_vcard')) {
|
||||
function scrape_vcard($url) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$ret = array();
|
||||
|
||||
logger('scrape_vcard: url=' . $url);
|
||||
|
||||
$s = fetch_url($url);
|
||||
|
||||
if(! $s)
|
||||
return $ret;
|
||||
|
||||
$headers = $a->get_curl_headers();
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
// don't try and run feeds through the html5 parser
|
||||
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$dom = HTML5_Parser::parse($s);
|
||||
} catch (DOMException $e) {
|
||||
logger('scrape_vcard: parse error: ' . $e);
|
||||
}
|
||||
|
||||
if(! $dom)
|
||||
return $ret;
|
||||
|
||||
// Pull out hCard profile elements
|
||||
|
||||
$largest_photo = 0;
|
||||
|
||||
$items = $dom->getElementsByTagName('*');
|
||||
foreach($items as $item) {
|
||||
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
|
||||
$level2 = $item->getElementsByTagName('*');
|
||||
foreach($level2 as $x) {
|
||||
if(attribute_contains($x->getAttribute('class'),'fn'))
|
||||
$ret['fn'] = $x->textContent;
|
||||
if((attribute_contains($x->getAttribute('class'),'photo'))
|
||||
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
|
||||
$size = intval($x->getAttribute('width'));
|
||||
if(($size > $largest_photo) || (! $largest_photo)) {
|
||||
$ret['photo'] = $x->getAttribute('src');
|
||||
$largest_photo = $size;
|
||||
}
|
||||
}
|
||||
if((attribute_contains($x->getAttribute('class'),'nickname'))
|
||||
|| (attribute_contains($x->getAttribute('class'),'uid'))) {
|
||||
$ret['nick'] = $x->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}}
|
||||
|
||||
|
||||
if(! function_exists('scrape_feed')) {
|
||||
function scrape_feed($url) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$ret = array();
|
||||
$cookiejar = tempnam(get_temppath(), 'cookiejar-scrape-feed-');
|
||||
$s = fetch_url($url, false, $redirects, 0, Null, $cookiejar);
|
||||
unlink($cookiejar);
|
||||
|
||||
$headers = $a->get_curl_headers();
|
||||
$code = $a->get_curl_code();
|
||||
|
||||
logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG);
|
||||
|
||||
if(! $s) {
|
||||
logger('scrape_feed: no data returned for ' . $url);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
if(stristr($line,'content-type:')) {
|
||||
if(stristr($line,'application/atom+xml') || stristr($s,'<feed')) {
|
||||
$ret['feed_atom'] = $url;
|
||||
return $ret;
|
||||
}
|
||||
if(stristr($line,'application/rss+xml') || stristr($s,'<rss')) {
|
||||
$ret['feed_rss'] = $url;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
// perhaps an RSS version 1 feed with a generic or incorrect content-type?
|
||||
if(stristr($s,'</item>')) {
|
||||
$ret['feed_rss'] = $url;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
$basename = implode('/', array_slice(explode('/',$url),0,3)) . '/';
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($s);
|
||||
$xpath = new DomXPath($doc);
|
||||
|
||||
$base = $xpath->query("//base");
|
||||
foreach ($base as $node) {
|
||||
$attr = array();
|
||||
|
||||
if ($node->attributes->length)
|
||||
foreach ($node->attributes as $attribute)
|
||||
$attr[$attribute->name] = $attribute->value;
|
||||
|
||||
if ($attr["href"] != "")
|
||||
$basename = $attr["href"] ;
|
||||
}
|
||||
|
||||
$list = $xpath->query("//link");
|
||||
foreach ($list as $node) {
|
||||
$attr = array();
|
||||
|
||||
if ($node->attributes->length)
|
||||
foreach ($node->attributes as $attribute)
|
||||
$attr[$attribute->name] = $attribute->value;
|
||||
|
||||
if (($attr["rel"] == "alternate") AND ($attr["type"] == "application/atom+xml"))
|
||||
$ret["feed_atom"] = $attr["href"];
|
||||
|
||||
if (($attr["rel"] == "alternate") AND ($attr["type"] == "application/rss+xml"))
|
||||
$ret["feed_rss"] = $attr["href"];
|
||||
}
|
||||
|
||||
// Drupal and perhaps others only provide relative URLs. Turn them into absolute.
|
||||
|
||||
if(x($ret,'feed_atom') && (! strstr($ret['feed_atom'],'://')))
|
||||
$ret['feed_atom'] = $basename . $ret['feed_atom'];
|
||||
if(x($ret,'feed_rss') && (! strstr($ret['feed_rss'],'://')))
|
||||
$ret['feed_rss'] = $basename . $ret['feed_rss'];
|
||||
|
||||
return $ret;
|
||||
}}
|
||||
|
||||
require_once('include/Probe.php');
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -349,594 +19,17 @@ function scrape_feed($url) {
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
define('PROBE_NORMAL', 0);
|
||||
define('PROBE_DIASPORA', 1);
|
||||
|
||||
function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
|
||||
require_once('include/email.php');
|
||||
|
||||
$result = array();
|
||||
|
||||
if (!$url)
|
||||
return $result;
|
||||
|
||||
$result = Cache::get("probe_url:".$mode.":".$url);
|
||||
if (!is_null($result)) {
|
||||
$result = unserialize($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$original_url = $url;
|
||||
$network = null;
|
||||
$diaspora = false;
|
||||
$diaspora_base = '';
|
||||
$diaspora_guid = '';
|
||||
$diaspora_key = '';
|
||||
$has_lrdd = false;
|
||||
$email_conversant = false;
|
||||
$connectornetworks = false;
|
||||
$appnet = false;
|
||||
|
||||
if (strpos($url,'twitter.com')) {
|
||||
$connectornetworks = true;
|
||||
$network = NETWORK_TWITTER;
|
||||
}
|
||||
|
||||
$lastfm = ((strpos($url,'last.fm/user') !== false) ? true : false);
|
||||
|
||||
$at_addr = ((strpos($url,'@') !== false) ? true : false);
|
||||
|
||||
if((!$appnet) && (!$lastfm) && !$connectornetworks) {
|
||||
|
||||
if(strpos($url,'mailto:') !== false && $at_addr) {
|
||||
$url = str_replace('mailto:','',$url);
|
||||
$links = array();
|
||||
}
|
||||
else
|
||||
$links = lrdd($url);
|
||||
|
||||
if ((count($links) == 0) AND strstr($url, "/index.php")) {
|
||||
$url = str_replace("/index.php", "", $url);
|
||||
$links = lrdd($url);
|
||||
}
|
||||
|
||||
if (count($links)) {
|
||||
$has_lrdd = true;
|
||||
|
||||
logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA);
|
||||
foreach($links as $link) {
|
||||
if($link['@attributes']['rel'] === NAMESPACE_ZOT)
|
||||
$zot = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
|
||||
$dfrn = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === 'salmon')
|
||||
$notify = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === NAMESPACE_FEED)
|
||||
$poll = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
|
||||
$hcard = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
|
||||
$profile = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
|
||||
$poco = unamp($link['@attributes']['href']);
|
||||
if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
|
||||
$diaspora_base = unamp($link['@attributes']['href']);
|
||||
$diaspora = true;
|
||||
}
|
||||
if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
|
||||
$diaspora_guid = unamp($link['@attributes']['href']);
|
||||
$diaspora = true;
|
||||
}
|
||||
if($link['@attributes']['rel'] === 'diaspora-public-key') {
|
||||
$diaspora_key = base64_decode(unamp($link['@attributes']['href']));
|
||||
if(strstr($diaspora_key,'RSA '))
|
||||
$pubkey = rsatopem($diaspora_key);
|
||||
else
|
||||
$pubkey = $diaspora_key;
|
||||
$diaspora = true;
|
||||
}
|
||||
if(($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe') AND ($mode == PROBE_NORMAL)) {
|
||||
$diaspora = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Status.Net can have more than one profile URL. We need to match the profile URL
|
||||
// to a contact on incoming messages to prevent spam, and we won't know which one
|
||||
// to match. So in case of two, one of them is stored as an alias. Only store URL's
|
||||
// and not webfinger user@host aliases. If they've got more than two non-email style
|
||||
// aliases, let's hope we're lucky and get one that matches the feed author-uri because
|
||||
// otherwise we're screwed.
|
||||
|
||||
$backup_alias = "";
|
||||
|
||||
foreach($links as $link) {
|
||||
if($link['@attributes']['rel'] === 'alias') {
|
||||
if(strpos($link['@attributes']['href'],'@') === false) {
|
||||
if(isset($profile)) {
|
||||
$alias_url = $link['@attributes']['href'];
|
||||
|
||||
if(($alias_url !== $profile) AND ($backup_alias == "") AND
|
||||
($alias_url !== str_replace("/index.php", "", $profile)))
|
||||
$backup_alias = $alias_url;
|
||||
|
||||
if(($alias_url !== $profile) AND !strstr($alias_url, "index.php") AND
|
||||
($alias_url !== str_replace("/index.php", "", $profile)))
|
||||
$alias = $alias_url;
|
||||
}
|
||||
else
|
||||
$profile = unamp($link['@attributes']['href']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($alias == "")
|
||||
$alias = $backup_alias;
|
||||
|
||||
// If the profile is different from the url then the url is abviously an alias
|
||||
if (($alias == "") AND ($profile != "") AND !$at_addr AND (normalise_link($profile) != normalise_link($url)))
|
||||
$alias = $url;
|
||||
}
|
||||
elseif($mode == PROBE_NORMAL) {
|
||||
|
||||
// Check email
|
||||
|
||||
$orig_url = $url;
|
||||
if((strpos($orig_url,'@')) && validate_email($orig_url)) {
|
||||
$x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval(local_user())
|
||||
);
|
||||
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1",
|
||||
intval(local_user())
|
||||
);
|
||||
if(count($x) && count($r)) {
|
||||
$mailbox = construct_mailbox_name($r[0]);
|
||||
$password = '';
|
||||
openssl_private_decrypt(hex2bin($r[0]['pass']),$password,$x[0]['prvkey']);
|
||||
$mbox = email_connect($mailbox,$r[0]['user'],$password);
|
||||
if(! $mbox)
|
||||
logger('probe_url: email_connect failed.');
|
||||
unset($password);
|
||||
}
|
||||
if($mbox) {
|
||||
$msgs = email_poll($mbox,$orig_url);
|
||||
logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
|
||||
if(count($msgs)) {
|
||||
$addr = $orig_url;
|
||||
$network = NETWORK_MAIL;
|
||||
$name = substr($url,0,strpos($url,'@'));
|
||||
$phost = substr($url,strpos($url,'@')+1);
|
||||
$profile = 'http://' . $phost;
|
||||
// fix nick character range
|
||||
$vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
|
||||
$notify = 'smtp ' . random_string();
|
||||
$poll = 'email ' . random_string();
|
||||
$priority = 0;
|
||||
$x = email_msg_meta($mbox,$msgs[0]);
|
||||
if(stristr($x[0]->from,$orig_url))
|
||||
$adr = imap_rfc822_parse_adrlist($x[0]->from,'');
|
||||
elseif(stristr($x[0]->to,$orig_url))
|
||||
$adr = imap_rfc822_parse_adrlist($x[0]->to,'');
|
||||
if(isset($adr)) {
|
||||
foreach($adr as $feadr) {
|
||||
if((strcasecmp($feadr->mailbox,$name) == 0)
|
||||
&&(strcasecmp($feadr->host,$phost) == 0)
|
||||
&& (strlen($feadr->personal))) {
|
||||
|
||||
$personal = imap_mime_header_decode($feadr->personal);
|
||||
$vcard['fn'] = "";
|
||||
foreach($personal as $perspart)
|
||||
if ($perspart->charset != "default")
|
||||
$vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
|
||||
else
|
||||
$vcard['fn'] .= $perspart->text;
|
||||
|
||||
$vcard['fn'] = notags($vcard['fn']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
imap_close($mbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($mode == PROBE_NORMAL) {
|
||||
|
||||
if(strlen($zot)) {
|
||||
$s = fetch_url($zot);
|
||||
if($s) {
|
||||
$j = json_decode($s);
|
||||
if($j) {
|
||||
$network = NETWORK_ZOT;
|
||||
$vcard = array(
|
||||
'fn' => $j->fullname,
|
||||
'nick' => $j->nickname,
|
||||
'photo' => $j->photo
|
||||
);
|
||||
$profile = $j->url;
|
||||
$notify = $j->post;
|
||||
$pubkey = $j->pubkey;
|
||||
$poll = 'N/A';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(strlen($dfrn)) {
|
||||
$ret = scrape_dfrn(($hcard) ? $hcard : $dfrn, true);
|
||||
if(is_array($ret) && x($ret,'dfrn-request')) {
|
||||
$network = NETWORK_DFRN;
|
||||
$request = $ret['dfrn-request'];
|
||||
$confirm = $ret['dfrn-confirm'];
|
||||
$notify = $ret['dfrn-notify'];
|
||||
$poll = $ret['dfrn-poll'];
|
||||
|
||||
$vcard = array();
|
||||
$vcard['fn'] = $ret['fn'];
|
||||
$vcard['nick'] = $ret['nick'];
|
||||
$vcard['photo'] = $ret['photo'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scrape the public key from the hcard.
|
||||
// Diaspora will remove it from the webfinger somewhere in the future.
|
||||
if (($hcard != "") AND ($pubkey == "")) {
|
||||
$ret = scrape_dfrn(($hcard) ? $hcard : $dfrn, true);
|
||||
if (isset($ret["key"])) {
|
||||
$hcard_key = $ret["key"];
|
||||
if(strstr($hcard_key,'RSA '))
|
||||
$pubkey = rsatopem($hcard_key);
|
||||
else
|
||||
$pubkey = $hcard_key;
|
||||
}
|
||||
}
|
||||
if($diaspora && $diaspora_base && $diaspora_guid) {
|
||||
$diaspora_notify = $diaspora_base.'receive/users/'.$diaspora_guid;
|
||||
|
||||
if($mode == PROBE_DIASPORA || !$notify || ($notify == $diaspora_notify)) {
|
||||
$notify = $diaspora_notify;
|
||||
$batch = $diaspora_base . 'receive/public' ;
|
||||
}
|
||||
if(strpos($url,'@'))
|
||||
$addr = str_replace('acct:', '', $url);
|
||||
}
|
||||
|
||||
if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
|
||||
if($diaspora)
|
||||
if ($mode == PROBE_DIASPORA)
|
||||
$network = NETWORK_DIASPORA;
|
||||
elseif($has_lrdd AND ($notify))
|
||||
$network = NETWORK_OSTATUS;
|
||||
else
|
||||
$network = "";
|
||||
|
||||
if(strpos($url,'@'))
|
||||
$addr = str_replace('acct:', '', $url);
|
||||
$data = Probe::uri($url, $network);
|
||||
|
||||
$priority = 0;
|
||||
|
||||
if($hcard && ! $vcard) {
|
||||
$vcard = scrape_vcard($hcard);
|
||||
|
||||
// Google doesn't use absolute url in profile photos
|
||||
|
||||
if((x($vcard,'photo')) && substr($vcard['photo'],0,1) == '/') {
|
||||
$h = @parse_url($hcard);
|
||||
if($h)
|
||||
$vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
|
||||
}
|
||||
|
||||
logger('probe_url: scrape_vcard: ' . print_r($vcard,true), LOGGER_DATA);
|
||||
}
|
||||
|
||||
if($diaspora && $addr) {
|
||||
// Diaspora returns the name as the nick. As the nick will never be updated,
|
||||
// let's use the Diaspora nickname (the first part of the handle) as the nick instead
|
||||
$addr_parts = explode('@', $addr);
|
||||
$vcard['nick'] = $addr_parts[0];
|
||||
}
|
||||
|
||||
if($lastfm) {
|
||||
$profile = $url;
|
||||
$poll = str_replace(array('www.','last.fm/'),array('','ws.audioscrobbler.com/1.0/'),$url) . '/recenttracks.rss';
|
||||
$vcard['nick'] = basename($url);
|
||||
$vcard['fn'] = $vcard['nick'] . t(' on Last.fm');
|
||||
$network = NETWORK_FEED;
|
||||
}
|
||||
|
||||
if(! x($vcard,'fn'))
|
||||
if(x($vcard,'nick'))
|
||||
$vcard['fn'] = $vcard['nick'];
|
||||
|
||||
$check_feed = false;
|
||||
|
||||
if(stristr($url,'tumblr.com') && (! stristr($url,'/rss'))) {
|
||||
$poll = $url . '/rss';
|
||||
$check_feed = true;
|
||||
// Will leave it to others to figure out how to grab the avatar, which is on the $url page in the open graph meta links
|
||||
}
|
||||
|
||||
if($appnet || ! $poll)
|
||||
$check_feed = true;
|
||||
if((! isset($vcard)) || (! x($vcard,'fn')) || (! $profile))
|
||||
$check_feed = true;
|
||||
if(($at_addr) && (! count($links)))
|
||||
$check_feed = false;
|
||||
|
||||
if ($connectornetworks)
|
||||
$check_feed = false;
|
||||
|
||||
if($check_feed) {
|
||||
|
||||
$feedret = scrape_feed(($poll) ? $poll : $url);
|
||||
|
||||
logger('probe_url: scrape_feed ' . (($poll)? $poll : $url) . ' returns: ' . print_r($feedret,true), LOGGER_DATA);
|
||||
if(count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
|
||||
$poll = ((x($feedret,'feed_atom')) ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']));
|
||||
if(! x($vcard))
|
||||
$vcard = array();
|
||||
}
|
||||
|
||||
if(x($feedret,'photo') && (! x($vcard,'photo')))
|
||||
$vcard['photo'] = $feedret['photo'];
|
||||
|
||||
$cookiejar = tempnam(get_temppath(), 'cookiejar-scrape-feed-');
|
||||
$xml = fetch_url($poll, false, $redirects, 0, Null, $cookiejar);
|
||||
unlink($cookiejar);
|
||||
|
||||
logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
|
||||
|
||||
if ($xml == "") {
|
||||
logger("scrape_feed: XML is empty for feed ".$poll);
|
||||
$network = NETWORK_PHANTOM;
|
||||
} else {
|
||||
$data = feed_import($xml,$dummy1,$dummy2, $dummy3, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
logger("scrape_feed: This doesn't seem to be a feed: ".$poll);
|
||||
$network = NETWORK_PHANTOM;
|
||||
} else {
|
||||
if (($vcard["photo"] == "") AND ($data["header"]["author-avatar"] != ""))
|
||||
$vcard["photo"] = $data["header"]["author-avatar"];
|
||||
|
||||
if (($vcard["fn"] == "") AND ($data["header"]["author-name"] != ""))
|
||||
$vcard["fn"] = $data["header"]["author-name"];
|
||||
|
||||
if (($vcard["nick"] == "") AND ($data["header"]["author-nick"] != ""))
|
||||
$vcard["nick"] = $data["header"]["author-nick"];
|
||||
|
||||
if ($network == NETWORK_OSTATUS) {
|
||||
if ($data["header"]["author-id"] != "")
|
||||
$alias = $data["header"]["author-id"];
|
||||
|
||||
if ($data["header"]["author-link"] != "")
|
||||
$profile = $data["header"]["author-link"];
|
||||
|
||||
} elseif(!$profile AND ($data["header"]["author-link"] != "") AND !in_array($network, array("", NETWORK_FEED)))
|
||||
$profile = $data["header"]["author-link"];
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for misconfigured Friendica servers
|
||||
if (($network == "") AND (strstr($url, "/profile/"))) {
|
||||
$noscrape = str_replace("/profile/", "/noscrape/", $url);
|
||||
$noscrapejson = fetch_url($noscrape);
|
||||
if ($noscrapejson) {
|
||||
|
||||
$network = NETWORK_DFRN;
|
||||
|
||||
$poco = str_replace("/profile/", "/poco/", $url);
|
||||
|
||||
$noscrapedata = json_decode($noscrapejson, true);
|
||||
|
||||
if (isset($noscrapedata["addr"]))
|
||||
$addr = $noscrapedata["addr"];
|
||||
|
||||
if (isset($noscrapedata["fn"]))
|
||||
$vcard["fn"] = $noscrapedata["fn"];
|
||||
|
||||
if (isset($noscrapedata["key"]))
|
||||
$pubkey = $noscrapedata["key"];
|
||||
|
||||
if (isset($noscrapedata["photo"]))
|
||||
$vcard["photo"] = $noscrapedata["photo"];
|
||||
|
||||
if (isset($noscrapedata["dfrn-request"]))
|
||||
$request = $noscrapedata["dfrn-request"];
|
||||
|
||||
if (isset($noscrapedata["dfrn-confirm"]))
|
||||
$confirm = $noscrapedata["dfrn-confirm"];
|
||||
|
||||
if (isset($noscrapedata["dfrn-notify"]))
|
||||
$notify = $noscrapedata["dfrn-notify"];
|
||||
|
||||
if (isset($noscrapedata["dfrn-poll"]))
|
||||
$poll = $noscrapedata["dfrn-poll"];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(! $network)
|
||||
$network = NETWORK_FEED;
|
||||
|
||||
if(! x($vcard,'nick')) {
|
||||
$vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
|
||||
if(strpos($vcard['nick'],' '))
|
||||
$vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' ')));
|
||||
}
|
||||
if(! $priority)
|
||||
$priority = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if(! x($vcard,'photo')) {
|
||||
$a = get_app();
|
||||
$vcard['photo'] = App::get_baseurl() . '/images/person-175.jpg' ;
|
||||
}
|
||||
|
||||
if(! $profile)
|
||||
$profile = $url;
|
||||
|
||||
// No human could be associated with this link, use the URL as the contact name
|
||||
|
||||
if(($network === NETWORK_FEED) && ($poll) && (! x($vcard,'fn')))
|
||||
$vcard['fn'] = $url;
|
||||
|
||||
if (($notify != "") AND ($poll != "")) {
|
||||
$baseurl = matching_url(normalise_link($notify), normalise_link($poll));
|
||||
|
||||
$baseurl2 = matching_url($baseurl, normalise_link($profile));
|
||||
if ($baseurl2 != "")
|
||||
$baseurl = $baseurl2;
|
||||
}
|
||||
|
||||
if (($baseurl == "") AND ($notify != ""))
|
||||
$baseurl = matching_url(normalise_link($profile), normalise_link($notify));
|
||||
|
||||
if (($baseurl == "") AND ($poll != ""))
|
||||
$baseurl = matching_url(normalise_link($profile), normalise_link($poll));
|
||||
|
||||
if (substr($baseurl, -10) == "/index.php")
|
||||
$baseurl = str_replace("/index.php", "", $baseurl);
|
||||
|
||||
if ($network == "")
|
||||
$network = NETWORK_PHANTOM;
|
||||
|
||||
$baseurl = rtrim($baseurl, "/");
|
||||
|
||||
if(strpos($url,'@') AND ($addr == "") AND ($network == NETWORK_DFRN))
|
||||
$addr = str_replace('acct:', '', $url);
|
||||
|
||||
$vcard['fn'] = notags($vcard['fn']);
|
||||
$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
|
||||
|
||||
$result['name'] = $vcard['fn'];
|
||||
$result['nick'] = $vcard['nick'];
|
||||
$result['url'] = $profile;
|
||||
$result['addr'] = $addr;
|
||||
$result['batch'] = $batch;
|
||||
$result['notify'] = $notify;
|
||||
$result['poll'] = $poll;
|
||||
$result['request'] = $request;
|
||||
$result['confirm'] = $confirm;
|
||||
$result['poco'] = $poco;
|
||||
$result['photo'] = $vcard['photo'];
|
||||
$result['priority'] = $priority;
|
||||
$result['network'] = $network;
|
||||
$result['alias'] = $alias;
|
||||
$result['pubkey'] = $pubkey;
|
||||
$result['baseurl'] = $baseurl;
|
||||
|
||||
logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
|
||||
|
||||
if ($level == 1) {
|
||||
// Trying if it maybe a diaspora account
|
||||
if (($result['network'] == NETWORK_FEED) OR ($result['addr'] == "")) {
|
||||
require_once('include/bbcode.php');
|
||||
$address = GetProfileUsername($url, "", true);
|
||||
$result2 = probe_url($address, $mode, ++$level);
|
||||
if (!in_array($result2['network'], array("", NETWORK_PHANTOM, NETWORK_FEED)))
|
||||
$result = $result2;
|
||||
}
|
||||
|
||||
// Maybe it's some non standard GNU Social installation (Single user, subfolder or no uri rewrite)
|
||||
if (($result['network'] == NETWORK_FEED) AND ($result['baseurl'] != "") AND ($result['nick'] != "")) {
|
||||
$addr = $result['nick'].'@'.str_replace("http://", "", $result['baseurl']);
|
||||
$result2 = probe_url($addr, $mode, ++$level);
|
||||
if (!in_array($result2['network'], array("", NETWORK_PHANTOM, NETWORK_FEED)))
|
||||
$result = $result2;
|
||||
}
|
||||
|
||||
// Quickfix for Hubzilla systems with enabled OStatus plugin
|
||||
if (($result['network'] == NETWORK_DIASPORA) AND ($result["batch"] == "")) {
|
||||
$result2 = probe_url($url, PROBE_DIASPORA, ++$level);
|
||||
if ($result2['network'] == NETWORK_DIASPORA) {
|
||||
$addr = $result["addr"];
|
||||
$result = $result2;
|
||||
|
||||
if (($result["addr"] == "") AND ($addr != ""))
|
||||
$result["addr"] = $addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only store into the cache if the value seems to be valid
|
||||
if ($result['network'] != NETWORK_PHANTOM) {
|
||||
Cache::set("probe_url:".$mode.":".$original_url,serialize($result), CACHE_DAY);
|
||||
|
||||
/// @todo temporary fix - we need a real contact update function that updates only changing fields
|
||||
/// The biggest problem is the avatar picture that could have a reduced image size.
|
||||
/// It should only be updated if the existing picture isn't existing anymore.
|
||||
if (($result['network'] != NETWORK_FEED) AND ($mode == PROBE_NORMAL) AND
|
||||
$result["name"] AND $result["nick"] AND $result["url"] AND $result["addr"] AND $result["poll"])
|
||||
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `url` = '%s', `addr` = '%s',
|
||||
`notify` = '%s', `poll` = '%s', `alias` = '%s', `success_update` = '%s'
|
||||
WHERE `nurl` = '%s' AND NOT `self` AND `uid` = 0",
|
||||
dbesc($result["name"]),
|
||||
dbesc($result["nick"]),
|
||||
dbesc($result["url"]),
|
||||
dbesc($result["addr"]),
|
||||
dbesc($result["notify"]),
|
||||
dbesc($result["poll"]),
|
||||
dbesc($result["alias"]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(normalise_link($result['url']))
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the matching part between two url
|
||||
*
|
||||
* @param string $url1
|
||||
* @param string $url2
|
||||
* @return string The matching part
|
||||
*/
|
||||
function matching_url($url1, $url2) {
|
||||
|
||||
if (($url1 == "") OR ($url2 == ""))
|
||||
return "";
|
||||
|
||||
$url1 = normalise_link($url1);
|
||||
$url2 = normalise_link($url2);
|
||||
|
||||
$parts1 = parse_url($url1);
|
||||
$parts2 = parse_url($url2);
|
||||
|
||||
if (!isset($parts1["host"]) OR !isset($parts2["host"]))
|
||||
return "";
|
||||
|
||||
if ($parts1["scheme"] != $parts2["scheme"])
|
||||
return "";
|
||||
|
||||
if ($parts1["host"] != $parts2["host"])
|
||||
return "";
|
||||
|
||||
if ($parts1["port"] != $parts2["port"])
|
||||
return "";
|
||||
|
||||
$match = $parts1["scheme"]."://".$parts1["host"];
|
||||
|
||||
if ($parts1["port"])
|
||||
$match .= ":".$parts1["port"];
|
||||
|
||||
$pathparts1 = explode("/", $parts1["path"]);
|
||||
$pathparts2 = explode("/", $parts2["path"]);
|
||||
|
||||
$i = 0;
|
||||
$path = "";
|
||||
do {
|
||||
$path1 = $pathparts1[$i];
|
||||
$path2 = $pathparts2[$i];
|
||||
|
||||
if ($path1 == $path2)
|
||||
$path .= $path1."/";
|
||||
|
||||
} while (($path1 == $path2) AND ($i++ <= count($pathparts1)));
|
||||
|
||||
$match .= $path;
|
||||
|
||||
return normalise_link($match);
|
||||
return $data;
|
||||
}
|
||||
|
|
|
@ -399,7 +399,7 @@ function acl_lookup(&$a, $out_type = 'json') {
|
|||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
||||
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : "");
|
||||
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : "");
|
||||
$mode = (x($_REQUEST,'mode') ? $_REQUEST['mode'] : "");
|
||||
$mode = (x($_REQUEST,'smode') ? $_REQUEST['smode'] : "");
|
||||
$conv_id = (x($_REQUEST,'conversation') ? $_REQUEST['conversation'] : null);
|
||||
|
||||
// For use with jquery.textcomplete for private mail completion
|
||||
|
@ -481,11 +481,11 @@ function acl_lookup(&$a, $out_type = 'json') {
|
|||
if ($type=='' || $type=='g'){
|
||||
|
||||
$r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
|
||||
FROM `group`,`group_member`
|
||||
WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d
|
||||
AND `group_member`.`gid`=`group`.`id`
|
||||
FROM `group`
|
||||
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id` AND `group_member`.`uid` = `group`.`uid`
|
||||
WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
|
||||
$sql_extra
|
||||
GROUP BY `group`.`id`
|
||||
GROUP BY `group`.`name`
|
||||
ORDER BY `group`.`name`
|
||||
LIMIT %d,%d",
|
||||
intval(local_user()),
|
||||
|
@ -690,7 +690,7 @@ function navbar_complete(&$a) {
|
|||
$localsearch = get_config('system','poco_local_search');
|
||||
|
||||
$search = $prefix.notags(trim($_REQUEST['search']));
|
||||
$mode = $_REQUEST['mode'];
|
||||
$mode = $_REQUEST['smode'];
|
||||
|
||||
// don't search if search term has less than 2 characters
|
||||
if(! $search || mb_strlen($search) < 2)
|
||||
|
|
1636
include/api.php
1636
include/api.php
File diff suppressed because it is too large
Load diff
|
@ -47,9 +47,8 @@ require_once("boot.php");
|
|||
|
||||
global $a, $db;
|
||||
|
||||
if(is_null($a)) {
|
||||
if (is_null($a))
|
||||
$a = new App;
|
||||
}
|
||||
|
||||
if (is_null($db)) {
|
||||
@include(".htconfig.php");
|
||||
|
@ -66,94 +65,177 @@ $bDebug = get_config('jabber','debug');
|
|||
|
||||
$oAuth = new exAuth($sLogFile, $bDebug);
|
||||
|
||||
class exAuth
|
||||
{
|
||||
class exAuth {
|
||||
private $sLogFile;
|
||||
private $bDebug;
|
||||
|
||||
private $rLogFile;
|
||||
|
||||
public function __construct($sLogFile, $bDebug)
|
||||
{
|
||||
/**
|
||||
* @brief Create the class and do the authentification studd
|
||||
*
|
||||
* @param string $sLogFile The logfile name
|
||||
* @param boolean $bDebug Debug mode
|
||||
*/
|
||||
public function __construct($sLogFile, $bDebug) {
|
||||
global $db;
|
||||
|
||||
// setter
|
||||
$this->sLogFile = $sLogFile;
|
||||
$this->bDebug = $bDebug;
|
||||
|
||||
// ovo ne provjeravamo jer ako ne mozes kreirati log file, onda si u kvascu :)
|
||||
// Open the logfile if the logfile name is defined
|
||||
if ($this->sLogFile != '')
|
||||
$this->rLogFile = fopen($this->sLogFile, "a") or die("Error opening log file: ". $this->sLogFile);
|
||||
|
||||
$this->writeLog("[exAuth] start");
|
||||
|
||||
// ovdje bi trebali biti spojeni na MySQL, imati otvoren log i zavrtit cekalicu
|
||||
// We are connected to the SQL server and are having a log file.
|
||||
do {
|
||||
// Quit if the database connection went down
|
||||
if (!$db->connected()) {
|
||||
$this->writeDebugLog("[debug] the database connection went down");
|
||||
return;
|
||||
}
|
||||
|
||||
$iHeader = fgets(STDIN, 3);
|
||||
$aLength = unpack("n", $iHeader);
|
||||
$iLength = $aLength["1"];
|
||||
if($iLength > 0) {
|
||||
// ovo znaci da smo nesto dobili
|
||||
|
||||
// No data? Then quit
|
||||
if ($iLength == 0) {
|
||||
$this->writeDebugLog("[debug] we got no data");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetching the data
|
||||
$sData = fgets(STDIN, $iLength + 1);
|
||||
$this->writeDebugLog("[debug] received data: ". $sData);
|
||||
$aCommand = explode(":", $sData);
|
||||
if (is_array($aCommand)) {
|
||||
switch ($aCommand[0]) {
|
||||
case "isuser":
|
||||
// provjeravamo je li korisnik dobar
|
||||
// Check the existance of a given username
|
||||
$this->isuser($aCommand);
|
||||
break;
|
||||
case "auth":
|
||||
// Check if the givven password is correct
|
||||
$this->auth($aCommand);
|
||||
break;
|
||||
case "setpass":
|
||||
// We don't accept the setting of passwords here
|
||||
$this->writeLog("[exAuth] setpass command disabled");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
break;
|
||||
default:
|
||||
// We don't know the given command
|
||||
$this->writeLog("[exAuth] unknown command ". $aCommand[0]);
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$this->writeDebugLog("[debug] invalid command string");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the given username exists
|
||||
*
|
||||
* @param array $aCommand The command array
|
||||
*/
|
||||
private function isuser($aCommand) {
|
||||
global $a;
|
||||
|
||||
// Check if there is a username
|
||||
if (!isset($aCommand[1])) {
|
||||
$this->writeLog("[exAuth] invalid isuser command, no username given");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
} else {
|
||||
// ovdje provjeri je li korisnik OK
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we check if the given user is valid
|
||||
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
|
||||
$this->writeDebugLog("[debug] checking isuser for ". $sUser);
|
||||
$sQuery = "SELECT `uid` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
|
||||
$this->writeDebugLog("[debug] checking isuser for ". $sUser."@".$aCommand[2]);
|
||||
|
||||
// If the hostnames doesn't match, we try to check remotely
|
||||
if ($a->get_hostname() != $aCommand[2])
|
||||
$found = $this->check_user($aCommand[2], $aCommand[1], true);
|
||||
else {
|
||||
$sQuery = "SELECT `uid` FROM `user` WHERE `nickname`='".dbesc($sUser)."'";
|
||||
$this->writeDebugLog("[debug] using query ". $sQuery);
|
||||
if ($oResult = q($sQuery)){
|
||||
if ($oResult) {
|
||||
// korisnik OK
|
||||
$r = q($sQuery);
|
||||
$found = dbm::is_result($r);
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
// The user is okay
|
||||
$this->writeLog("[exAuth] valid user: ". $sUser);
|
||||
fwrite(STDOUT, pack("nn", 2, 1));
|
||||
} else {
|
||||
// korisnik nije OK
|
||||
// The user isn't okay
|
||||
$this->writeLog("[exAuth] invalid user: ". $sUser);
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
}
|
||||
//$oResult->close();
|
||||
} else {
|
||||
$this->writeLog("[MySQL] invalid query: ". $sQuery);
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check remote user existance via HTTP(S)
|
||||
*
|
||||
* @param string $host The hostname
|
||||
* @param string $user Username
|
||||
* @param boolean $ssl Should the check be done via SSL?
|
||||
*
|
||||
* @return boolean Was the user found?
|
||||
*/
|
||||
private function check_user($host, $user, $ssl) {
|
||||
|
||||
$url = ($ssl ? "https":"http")."://".$host."/noscrape/".$user;
|
||||
|
||||
$data = z_fetch_url($url);
|
||||
|
||||
if (!is_array($data))
|
||||
return(false);
|
||||
|
||||
if ($data["return_code"] != "200")
|
||||
return(false);
|
||||
|
||||
$json = @json_decode($data["body"]);
|
||||
if (!is_object($json))
|
||||
return(false);
|
||||
|
||||
return($json->nick == $user);
|
||||
}
|
||||
break;
|
||||
case "auth":
|
||||
// provjeravamo autentifikaciju korisnika
|
||||
|
||||
/**
|
||||
* @brief Authenticate the givven user and password
|
||||
*
|
||||
* @param array $aCommand The command array
|
||||
*/
|
||||
private function auth($aCommand) {
|
||||
global $a;
|
||||
|
||||
// check user authentication
|
||||
if (sizeof($aCommand) != 4) {
|
||||
$this->writeLog("[exAuth] invalid auth command, data missing");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
} else {
|
||||
// ovdje provjeri prijavu
|
||||
return;
|
||||
}
|
||||
|
||||
// We now check if the password match
|
||||
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
|
||||
$this->writeDebugLog("[debug] doing auth for ". $sUser);
|
||||
//$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `password`='".hash('whirlpool',$aCommand[3])."' AND `nickname`='". $db->escape($sUser) ."'";
|
||||
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
|
||||
$this->writeDebugLog("[debug] doing auth for ".$sUser."@".$aCommand[2]);
|
||||
|
||||
// If the hostnames doesn't match, we try to authenticate remotely
|
||||
if ($a->get_hostname() != $aCommand[2])
|
||||
$Error = !$this->check_credentials($aCommand[2], $aCommand[1], $aCommand[3], true);
|
||||
else {
|
||||
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='".dbesc($sUser)."'";
|
||||
$this->writeDebugLog("[debug] using query ". $sQuery);
|
||||
if ($oResult = q($sQuery)) {
|
||||
$uid = $oResult[0]["uid"];
|
||||
$Error = ($oResult[0]["password"] != hash('whirlpool',$aCommand[3]));
|
||||
/*
|
||||
if ($oResult[0]["password"] == hash('whirlpool',$aCommand[3])) {
|
||||
// korisnik OK
|
||||
$this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]);
|
||||
fwrite(STDOUT, pack("nn", 2, 1));
|
||||
} else {
|
||||
// korisnik nije OK
|
||||
$this->writeLog("[exAuth] authentification failed for user ". $sUser ."@". $aCommand[2]);
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
}
|
||||
$oResult->close();
|
||||
*/
|
||||
} else {
|
||||
$this->writeLog("[MySQL] invalid query: ". $sQuery);
|
||||
$Error = true;
|
||||
|
@ -164,6 +246,7 @@ class exAuth
|
|||
$this->writeLog("[exAuth] got password ".$oConfig[0]["v"]);
|
||||
$Error = ($aCommand[3] != $oConfig[0]["v"]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($Error) {
|
||||
$this->writeLog("[exAuth] authentification failed for user ".$sUser."@". $aCommand[2]);
|
||||
|
@ -173,55 +256,70 @@ class exAuth
|
|||
fwrite(STDOUT, pack("nn", 2, 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "setpass":
|
||||
// postavljanje zaporke, onemoguceno
|
||||
$this->writeLog("[exAuth] setpass command disabled");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
break;
|
||||
default:
|
||||
// ako je uhvaceno ista drugo
|
||||
$this->writeLog("[exAuth] unknown command ". $aCommand[0]);
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$this->writeDebugLog("[debug] invalid command string");
|
||||
fwrite(STDOUT, pack("nn", 2, 0));
|
||||
}
|
||||
}
|
||||
unset ($iHeader);
|
||||
unset ($aLength);
|
||||
unset ($iLength);
|
||||
unset($aCommand);
|
||||
} while (true);
|
||||
|
||||
/**
|
||||
* @brief Check remote credentials via HTTP(S)
|
||||
*
|
||||
* @param string $host The hostname
|
||||
* @param string $user Username
|
||||
* @param string $password Password
|
||||
* @param boolean $ssl Should the check be done via SSL?
|
||||
*
|
||||
* @return boolean Are the credentials okay?
|
||||
*/
|
||||
private function check_credentials($host, $user, $password, $ssl) {
|
||||
$this->writeDebugLog("[debug] check credentials for user ".$user." on ".$host);
|
||||
|
||||
$url = ($ssl ? "https":"http")."://".$host."/api/account/verify_credentials.json";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password);
|
||||
|
||||
$header = curl_exec($ch);
|
||||
$curl_info = @curl_getinfo($ch);
|
||||
$http_code = $curl_info["http_code"];
|
||||
curl_close($ch);
|
||||
|
||||
$this->writeDebugLog("[debug] got HTTP code ".$http_code);
|
||||
|
||||
return ($http_code == 200);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// zatvori log file
|
||||
/**
|
||||
* @brief write data to the logfile
|
||||
*
|
||||
* @param string $sMessage The logfile message
|
||||
*/
|
||||
private function writeLog($sMessage) {
|
||||
if (is_resource($this->rLogFile))
|
||||
fwrite($this->rLogFile, date("r")." ".$sMessage."\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief write debug data to the logfile
|
||||
*
|
||||
* @param string $sMessage The logfile message
|
||||
*/
|
||||
private function writeDebugLog($sMessage) {
|
||||
if ($this->bDebug)
|
||||
$this->writeLog($sMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief destroy the class
|
||||
*/
|
||||
public function __destruct() {
|
||||
// close the log file
|
||||
$this->writeLog("[exAuth] stop");
|
||||
|
||||
if (is_resource($this->rLogFile)){
|
||||
if (is_resource($this->rLogFile))
|
||||
fclose($this->rLogFile);
|
||||
}
|
||||
}
|
||||
|
||||
private function writeLog($sMessage)
|
||||
{
|
||||
if (is_resource($this->rLogFile)) {
|
||||
fwrite($this->rLogFile, date("r") ." ". $sMessage ."\n");
|
||||
}
|
||||
}
|
||||
|
||||
private function writeDebugLog($sMessage)
|
||||
{
|
||||
if ($this->bDebug){
|
||||
$this->writeLog($sMessage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ function bb_map_location($match) {
|
|||
function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
|
||||
|
||||
$data = get_attachment_data($Text);
|
||||
|
||||
if (!$data)
|
||||
return $Text;
|
||||
|
||||
|
@ -85,7 +84,7 @@ function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
|
|||
$text .= $oembed;
|
||||
|
||||
if (trim($data["description"]) != "")
|
||||
$text .= sprintf('<blockquote>%s</blockquote></span>', trim($data["description"]));
|
||||
$text .= sprintf('<blockquote>%s</blockquote></span>', trim(bbcode($data["description"])));
|
||||
}
|
||||
}
|
||||
return $data["text"].$text.$data["after"];
|
||||
|
@ -147,7 +146,7 @@ function cleancss($input) {
|
|||
if (($char >= "a") and ($char <= "z"))
|
||||
$cleaned .= $char;
|
||||
|
||||
if (!(strpos(" #;:0123456789-_", $char) === false))
|
||||
if (!(strpos(" #;:0123456789-_.%", $char) === false))
|
||||
$cleaned .= $char;
|
||||
}
|
||||
|
||||
|
@ -408,23 +407,28 @@ function bb_ShareAttributes($share, $simplehtml) {
|
|||
if ($itemcache == "")
|
||||
$reldate = (($posted) ? " " . relative_date($posted) : '');
|
||||
|
||||
// We only call this so that a previously unknown contact can be added.
|
||||
// This is important for the function "get_contact_details_by_url".
|
||||
// This function then can fetch an entry from the contact table.
|
||||
get_contact($profile, 0);
|
||||
|
||||
$data = get_contact_details_by_url($profile);
|
||||
|
||||
if (isset($data["name"]) AND isset($data["addr"]))
|
||||
if (isset($data["name"]) AND ($data["name"] != "") AND isset($data["addr"]) AND ($data["addr"] != ""))
|
||||
$userid_compact = $data["name"]." (".$data["addr"].")";
|
||||
else
|
||||
$userid_compact = GetProfileUsername($profile,$author, true);
|
||||
|
||||
if (isset($data["addr"]))
|
||||
if (isset($data["addr"]) AND ($data["addr"] != ""))
|
||||
$userid = $data["addr"];
|
||||
else
|
||||
$userid = GetProfileUsername($profile,$author, false);
|
||||
|
||||
if (isset($data["name"]))
|
||||
if (isset($data["name"]) AND ($data["name"] != ""))
|
||||
$author = $data["name"];
|
||||
|
||||
if (isset($data["photo"]))
|
||||
$avatar = $data["photo"];
|
||||
if (isset($data["micro"]) AND ($data["micro"] != ""))
|
||||
$avatar = $data["micro"];
|
||||
|
||||
$preshare = trim($share[1]);
|
||||
|
||||
|
@ -490,6 +494,8 @@ function bb_ShareAttributes($share, $simplehtml) {
|
|||
default:
|
||||
$text = trim($share[1])."\n";
|
||||
|
||||
$avatar = proxy_url($avatar, false, PROXY_SIZE_THUMB);
|
||||
|
||||
$tpl = get_markup_template('shared_content.tpl');
|
||||
$text .= replace_macros($tpl,
|
||||
array(
|
||||
|
@ -717,6 +723,13 @@ function bb_CleanPictureLinks($text) {
|
|||
return ($text);
|
||||
}
|
||||
|
||||
function bb_highlight($match) {
|
||||
if(in_array(strtolower($match[1]),['php','css','mysql','sql','abap','diff','html','perl','ruby',
|
||||
'vbscript','avrc','dtd','java','xml','cpp','python','javascript','js','sh']))
|
||||
return text_highlight($match[2],strtolower($match[1]));
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
// BBcode 2 HTML was written by WAY2WEB.net
|
||||
// extended to work with Mistpark/Friendica - Mike Macgirvin
|
||||
|
||||
|
@ -769,6 +782,11 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
|
|||
if (!$tryoembed)
|
||||
$Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","\n[share$1$2]$3[/share]",$Text);
|
||||
|
||||
// Check for [code] text here, before the linefeeds are messed with.
|
||||
// The highlighter will unescape and re-escape the content.
|
||||
if (strpos($Text,'[code=') !== false) {
|
||||
$Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
|
||||
}
|
||||
// Convert new line chars to html <br /> tags
|
||||
|
||||
// nlbr seems to be hopelessly messed up
|
||||
|
@ -874,8 +892,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
|
|||
// we may need to restrict this further if it picks up too many strays
|
||||
// link acct:user@host to a webfinger profile redirector
|
||||
|
||||
$Text = preg_replace('/acct:(.*?)@(.*?)([ ,])/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=' . "$1@$2"
|
||||
. '" target="extlink" >acct:' . "$1@$2$3" . '</a>',$Text);
|
||||
$Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=$1@$2" target="extlink">acct:$1@$2</a>',$Text);
|
||||
|
||||
// Perform MAIL Search
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
|
||||
|
@ -902,6 +919,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
|
|||
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
|
||||
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
|
||||
|
||||
// Check for paragraph
|
||||
$Text = preg_replace("(\[p\](.*?)\[\/p\])ism",'<p>$1</p>',$Text);
|
||||
|
||||
// Check for bold text
|
||||
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
|
||||
|
||||
|
@ -1121,6 +1141,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
|
|||
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
|
||||
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
|
||||
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
|
||||
$Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,72 +1,197 @@
|
|||
<?php
|
||||
/**
|
||||
* cache api
|
||||
* @file include/cache.php
|
||||
*
|
||||
* @brief Class for storing data for a short time
|
||||
*/
|
||||
|
||||
use \Friendica\Core\Config;
|
||||
use \Friendica\Core\PConfig;
|
||||
|
||||
class Cache {
|
||||
/**
|
||||
* @brief Check for memcache and open a connection if configured
|
||||
*
|
||||
* @return object|boolean The memcache object - or "false" if not successful
|
||||
*/
|
||||
public static function memcache() {
|
||||
if (!function_exists('memcache_connect')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Config::get('system', 'memcache')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$memcache_host = Config::get('system', 'memcache_host', '127.0.0.1');
|
||||
$memcache_port = Config::get('system', 'memcache_port', 11211);
|
||||
|
||||
$memcache = new Memcache;
|
||||
|
||||
if (!$memcache->connect($memcache_host, $memcache_port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the duration for a given cache level
|
||||
*
|
||||
* @param integer $level Cache level
|
||||
*
|
||||
* @return integer The cache duration in seconds
|
||||
*/
|
||||
private function duration($level) {
|
||||
switch($level) {
|
||||
case CACHE_MONTH;
|
||||
$seconds = 2592000;
|
||||
break;
|
||||
case CACHE_WEEK;
|
||||
$seconds = 604800;
|
||||
break;
|
||||
case CACHE_DAY;
|
||||
$seconds = 86400;
|
||||
break;
|
||||
case CACHE_HOUR;
|
||||
$seconds = 3600;
|
||||
break;
|
||||
case CACHE_HALF_HOUR;
|
||||
$seconds = 1800;
|
||||
break;
|
||||
case CACHE_QUARTER_HOUR;
|
||||
$seconds = 900;
|
||||
break;
|
||||
case CACHE_FIVE_MINUTES;
|
||||
$seconds = 300;
|
||||
break;
|
||||
case CACHE_MINUTE;
|
||||
$seconds = 60;
|
||||
break;
|
||||
}
|
||||
return $seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch cached data according to the key
|
||||
*
|
||||
* @param string $key The key to the cached data
|
||||
*
|
||||
* @return mixed Cached $value or "null" if not found
|
||||
*/
|
||||
public static function get($key) {
|
||||
|
||||
$r = q("SELECT `v` FROM `cache` WHERE `k`='%s' limit 1",
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if (count($r))
|
||||
return $r[0]['v'];
|
||||
$memcache = self::memcache();
|
||||
if (is_object($memcache)) {
|
||||
// We fetch with the hostname as key to avoid problems with other applications
|
||||
$value = $memcache->get(get_app()->get_hostname().":".$key);
|
||||
if (!is_bool($value)) {
|
||||
return unserialize($value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Frequently clear cache
|
||||
self::clear($duration);
|
||||
|
||||
$r = q("SELECT `v` FROM `cache` WHERE `k`='%s' LIMIT 1",
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if (dbm::is_result($r)) {
|
||||
return unserialize($r[0]['v']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put data in the cache according to the key
|
||||
*
|
||||
* The input $value can have multiple formats.
|
||||
*
|
||||
* @param string $key The key to the cached data
|
||||
* @param mixed $valie The value that is about to be stored
|
||||
* @param integer $duration The cache lifespan
|
||||
*/
|
||||
public static function set($key, $value, $duration = CACHE_MONTH) {
|
||||
|
||||
// Do we have an installed memcache? Use it instead.
|
||||
$memcache = self::memcache();
|
||||
if (is_object($memcache)) {
|
||||
// We store with the hostname as key to avoid problems with other applications
|
||||
$memcache->set(get_app()->get_hostname().":".$key, serialize($value), MEMCACHE_COMPRESSED, self::duration($duration));
|
||||
return;
|
||||
}
|
||||
|
||||
/// @todo store the cache data in the same way like the config data
|
||||
q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
|
||||
dbesc($key),
|
||||
dbesc($value),
|
||||
dbesc(serialize($value)),
|
||||
intval($duration),
|
||||
dbesc(datetime_convert()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Remove outdated data from the cache
|
||||
*
|
||||
* Leaving this legacy code temporaily to see how REPLACE fares
|
||||
* as opposed to non-atomic checks when faced with fast moving key duplication.
|
||||
* As a MySQL extension it isn't portable, but we're not yet very portable.
|
||||
* @param integer $maxlevel The maximum cache level that is to be cleared
|
||||
*/
|
||||
public static function clear($max_level = CACHE_MONTH) {
|
||||
|
||||
/*
|
||||
* $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
|
||||
* dbesc($key)
|
||||
* );
|
||||
* if(count($r)) {
|
||||
* q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s'",
|
||||
* dbesc($value),
|
||||
* dbesc(datetime_convert()),
|
||||
* dbesc($key));
|
||||
* }
|
||||
* else {
|
||||
* q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
|
||||
* dbesc($key),
|
||||
* dbesc($value),
|
||||
* dbesc(datetime_convert()));
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
|
||||
public static function clear(){
|
||||
// Clear long lasting cache entries only once a day
|
||||
if (get_config("system", "cache_cleared_day") < time() - self::duration(CACHE_DAY)) {
|
||||
if ($max_level == CACHE_MONTH) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 30 days")), intval(CACHE_MONTH));
|
||||
}
|
||||
|
||||
if ($max_level <= CACHE_WEEK) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 7 days")), intval(CACHE_WEEK));
|
||||
}
|
||||
|
||||
if ($max_level <= CACHE_DAY) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 1 days")), intval(CACHE_DAY));
|
||||
}
|
||||
set_config("system", "cache_cleared_day", time());
|
||||
}
|
||||
|
||||
if (($max_level <= CACHE_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_HOUR)) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 1 hours")), intval(CACHE_HOUR));
|
||||
|
||||
set_config("system", "cache_cleared_hour", time());
|
||||
}
|
||||
|
||||
if (($max_level <= CACHE_HALF_HOUR) AND (get_config("system", "cache_cleared_half_hour")) < time() - self::duration(CACHE_HALF_HOUR)) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 30 minutes")), intval(CACHE_HALF_HOUR));
|
||||
|
||||
set_config("system", "cache_cleared_half_hour", time());
|
||||
}
|
||||
|
||||
if (($max_level <= CACHE_QUARTER_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_QUARTER_HOUR)) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 15 minutes")), intval(CACHE_QUARTER_HOUR));
|
||||
|
||||
set_config("system", "cache_cleared_quarter_hour", time());
|
||||
}
|
||||
|
||||
if (($max_level <= CACHE_FIVE_MINUTES) AND (get_config("system", "cache_cleared_five_minute")) < time() - self::duration(CACHE_FIVE_MINUTES)) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 5 minutes")), intval(CACHE_FIVE_MINUTES));
|
||||
|
||||
set_config("system", "cache_cleared_five_minute", time());
|
||||
}
|
||||
|
||||
if (($max_level <= CACHE_MINUTE) AND (get_config("system", "cache_cleared_minute")) < time() - self::duration(CACHE_MINUTE)) {
|
||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 1 minutes")), intval(CACHE_MINUTE));
|
||||
|
||||
set_config("system", "cache_cleared_minute", time());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ function contact_profile_assign($current,$foreign_net) {
|
|||
|
||||
$disabled = (($foreign_net) ? ' disabled="true" ' : '');
|
||||
|
||||
$o .= "<select id=\"contact-profile-selector\" $disabled name=\"profile-assign\" />\r\n";
|
||||
$o .= "<select id=\"contact-profile-selector\" class=\"form-control\" $disabled name=\"profile-assign\" />\r\n";
|
||||
|
||||
$r = q("SELECT `id`, `profile-name` FROM `profile` WHERE `uid` = %d",
|
||||
intval($_SESSION['uid']));
|
||||
|
|
|
@ -374,30 +374,18 @@ function visible_activity($item) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief List of all contact fields that are needed for the conversation function
|
||||
* @brief SQL query for items
|
||||
*/
|
||||
function contact_fieldlist() {
|
||||
function item_query() {
|
||||
|
||||
$fieldlist = "`contact`.`network`, `contact`.`url`, `contact`.`name`, `contact`.`writable`,
|
||||
`contact`.`self`, `contact`.`id` AS `cid`, `contact`.`alias`";
|
||||
|
||||
return $fieldlist;
|
||||
return "SELECT ".item_fieldlists()." FROM `item` ".
|
||||
item_joins()." WHERE ".item_condition();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SQL condition for contacts
|
||||
* @brief List of all data fields that are needed for displaying items
|
||||
*/
|
||||
function contact_condition() {
|
||||
|
||||
$condition = "NOT `contact`.`blocked` AND NOT `contact`.`pending`";
|
||||
|
||||
return $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief List of all item fields that are needed for the conversation function
|
||||
*/
|
||||
function item_fieldlist() {
|
||||
function item_fieldlists() {
|
||||
|
||||
/*
|
||||
These Fields are not added below (yet). They are here to for bug search.
|
||||
|
@ -405,19 +393,15 @@ These Fields are not added below (yet). They are here to for bug search.
|
|||
`item`.`extid`,
|
||||
`item`.`received`,
|
||||
`item`.`changed`,
|
||||
`item`.`author-avatar`,
|
||||
`item`.`object`,
|
||||
`item`.`moderated`,
|
||||
`item`.`target-type`,
|
||||
`item`.`target`,
|
||||
`item`.`resource-id`,
|
||||
`item`.`tag`,
|
||||
`item`.`attach`,
|
||||
`item`.`inform`,
|
||||
`item`.`pubmail`,
|
||||
`item`.`moderated`,
|
||||
`item`.`visible`,
|
||||
`item`.`spam`,
|
||||
`item`.`starred`,
|
||||
`item`.`bookmark`,
|
||||
`item`.`unseen`,
|
||||
`item`.`deleted`,
|
||||
|
@ -430,28 +414,42 @@ These Fields are not added below (yet). They are here to for bug search.
|
|||
`item`.`shadow`,
|
||||
*/
|
||||
|
||||
$fieldlist = "`item`.`author-link`, `item`.`verb`, `item`.`id`, `item`.`parent`, `item`.`file`,
|
||||
`item`.`uid`, `item`.`author-name`, `item`.`location`, `item`.`coord`,
|
||||
`item`.`title`, `item`.`uri`, `item`.`created`, `item`.`app`, `item`.`guid`,
|
||||
`item`.`contact-id`, `item`.`thr-parent`, `item`.`parent-uri`, `item`.`rendered-hash`,
|
||||
`item`.`body`, `item`.`rendered-html`, `item`.`private`, `item`.`edited`,
|
||||
return "`item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`,
|
||||
`item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`,
|
||||
`item`.`contact-id`, `item`.`uid`, `item`.`id`, `item`.`parent`,
|
||||
`item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`,
|
||||
`item`.`commented`, `item`.`created`, `item`.`edited`,
|
||||
`item`.`verb`, `item`.`object-type`, `item`.`postopts`, `item`.`plink`,
|
||||
`item`.`guid`, `item`.`wall`, `item`.`private`, `item`.`starred`,
|
||||
`item`.`title`, `item`.`body`, `item`.`file`, `item`.`event-id`,
|
||||
`item`.`location`, `item`.`coord`, `item`.`app`, `item`.`attach`,
|
||||
`item`.`rendered-hash`, `item`.`rendered-html`, `item`.`object`,
|
||||
`item`.`allow_cid`, `item`.`allow_gid`, `item`.`deny_cid`, `item`.`deny_gid`,
|
||||
`item`.`event-id`, `item`.`object-type`, `item`.`starred`, `item`.`created`,
|
||||
`item`.`postopts`, `item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`,
|
||||
`item`.`plink`, `item`.`wall`, `item`.`commented`,
|
||||
`item`.`id` AS `item_id`, `item`.`network` AS `item_network`";
|
||||
`item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
|
||||
|
||||
return $fieldlist;
|
||||
`author`.`thumb` AS `author-thumb`, `owner`.`thumb` AS `owner-thumb`,
|
||||
|
||||
`contact`.`network`, `contact`.`url`, `contact`.`name`, `contact`.`writable`,
|
||||
`contact`.`self`, `contact`.`id` AS `cid`, `contact`.`alias`";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SQL condition for items
|
||||
* @brief SQL join for contacts that are needed for displaying items
|
||||
*/
|
||||
function item_joins() {
|
||||
|
||||
return "STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND
|
||||
NOT `contact`.`blocked` AND NOT `contact`.`pending`
|
||||
LEFT JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
|
||||
LEFT JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id`";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SQL condition for items that are needed for displaying items
|
||||
*/
|
||||
function item_condition() {
|
||||
|
||||
$condition = "`item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`";
|
||||
|
||||
return $condition;
|
||||
return "`item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -623,7 +621,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
|
||||
$comment = '';
|
||||
$owner_url = '';
|
||||
$owner_photo = '';
|
||||
$owner_name = '';
|
||||
$sparkle = '';
|
||||
|
||||
|
@ -668,18 +665,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
$tags[] = $prefix."<a href=\"".$tag["url"]."\" target=\"_blank\">".$tag["term"]."</a>";
|
||||
}
|
||||
|
||||
/*foreach(explode(',',$item['tag']) as $tag){
|
||||
$tag = trim($tag);
|
||||
if ($tag!="") {
|
||||
$t = bbcode($tag);
|
||||
$tags[] = $t;
|
||||
if($t[0] == '#')
|
||||
$hashtags[] = $t;
|
||||
elseif($t[0] == '@')
|
||||
$mentions[] = $t;
|
||||
}
|
||||
}*/
|
||||
|
||||
$sp = false;
|
||||
$profile_link = best_link_url($item,$sp);
|
||||
if($profile_link === 'mailbox')
|
||||
|
@ -689,12 +674,21 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
else
|
||||
$profile_link = zrl($profile_link);
|
||||
|
||||
// Don't rely on the author-avatar. It is better to use the data from the contact table
|
||||
if (!isset($item['author-thumb']) OR ($item['author-thumb'] == "")) {
|
||||
$author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
|
||||
if ($author_contact["thumb"])
|
||||
$profile_avatar = $author_contact["thumb"];
|
||||
$item['author-thumb'] = $author_contact["thumb"];
|
||||
else
|
||||
$profile_avatar = $item['author-avatar'];
|
||||
$item['author-thumb'] = $item['author-avatar'];
|
||||
}
|
||||
|
||||
if (!isset($item['owner-thumb']) OR ($item['owner-thumb'] == "")) {
|
||||
$owner_contact = get_contact_details_by_url($item['owner-link'], $profile_owner);
|
||||
if ($owner_contact["thumb"])
|
||||
$item['owner-thumb'] = $owner_contact["thumb"];
|
||||
else
|
||||
$item['owner-thumb'] = $item['owner-avatar'];
|
||||
}
|
||||
|
||||
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
|
||||
call_hooks('render_location',$locate);
|
||||
|
@ -762,7 +756,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
'name' => $profile_name_e,
|
||||
'sparkle' => $sparkle,
|
||||
'lock' => $lock,
|
||||
'thumb' => App::remove_baseurl(proxy_url($profile_avatar, false, PROXY_SIZE_THUMB)),
|
||||
'thumb' => App::remove_baseurl(proxy_url($item['author-thumb'], false, PROXY_SIZE_THUMB)),
|
||||
'title' => $item['title_e'],
|
||||
'body' => $body_e,
|
||||
'tags' => $tags_e,
|
||||
|
@ -781,7 +775,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
'indent' => '',
|
||||
'owner_name' => $owner_name_e,
|
||||
'owner_url' => $owner_url,
|
||||
'owner_photo' => proxy_url($owner_photo, false, PROXY_SIZE_THUMB),
|
||||
'owner_photo' => App::remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
|
||||
'plink' => get_plink($item),
|
||||
'edpost' => false,
|
||||
'isstarred' => $isstarred,
|
||||
|
@ -885,15 +879,13 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
|
||||
function best_link_url($item,&$sparkle,$ssl_state = false) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$best_url = '';
|
||||
$sparkle = false;
|
||||
|
||||
$clean_url = normalise_link($item['author-link']);
|
||||
|
||||
if (local_user()) {
|
||||
$r = q("SELECT `id` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s' LIMIT 1",
|
||||
$r = q("SELECT `id` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s' AND NOT `pending` LIMIT 1",
|
||||
dbesc(NETWORK_DFRN), intval(local_user()), dbesc(normalise_link($clean_url)));
|
||||
if ($r) {
|
||||
$best_url = 'redir/'.$r[0]['id'];
|
||||
|
@ -912,22 +904,22 @@ function best_link_url($item,&$sparkle,$ssl_state = false) {
|
|||
|
||||
|
||||
if (! function_exists('item_photo_menu')) {
|
||||
function item_photo_menu($item){
|
||||
$a = get_app();
|
||||
|
||||
function item_photo_menu($item)
|
||||
{
|
||||
$ssl_state = false;
|
||||
|
||||
if(local_user())
|
||||
if(local_user()) {
|
||||
$ssl_state = true;
|
||||
}
|
||||
|
||||
$sub_link="";
|
||||
$poke_link="";
|
||||
$contact_url="";
|
||||
$pm_url="";
|
||||
$status_link="";
|
||||
$photos_link="";
|
||||
$posts_link="";
|
||||
$network = "";
|
||||
$sub_link = '';
|
||||
$poke_link = '';
|
||||
$contact_url = '';
|
||||
$pm_url = '';
|
||||
$status_link = '';
|
||||
$photos_link = '';
|
||||
$posts_link = '';
|
||||
$network = '';
|
||||
|
||||
if ((local_user()) && local_user() == $item['uid'] && $item['parent'] == $item['id'] && (! $item['self'])) {
|
||||
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
|
||||
|
@ -935,56 +927,62 @@ function item_photo_menu($item){
|
|||
|
||||
$sparkle = false;
|
||||
$profile_link = best_link_url($item, $sparkle, $ssl_state);
|
||||
if($profile_link === 'mailbox')
|
||||
if ($profile_link === 'mailbox') {
|
||||
$profile_link = '';
|
||||
}
|
||||
|
||||
$cid = 0;
|
||||
$network = "";
|
||||
$network = '';
|
||||
$rel = 0;
|
||||
$r = q("SELECT `id`, `network`, `rel` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
|
||||
intval(local_user()), dbesc(normalise_link($item['author-link'])));
|
||||
if ($r) {
|
||||
$cid = $r[0]["id"];
|
||||
$network = $r[0]["network"];
|
||||
$rel = $r[0]["rel"];
|
||||
$cid = $r[0]['id'];
|
||||
$network = $r[0]['network'];
|
||||
$rel = $r[0]['rel'];
|
||||
}
|
||||
|
||||
if($sparkle) {
|
||||
$status_link = $profile_link."?url=status";
|
||||
$photos_link = $profile_link."?url=photos";
|
||||
$profile_link = $profile_link."?url=profile";
|
||||
$status_link = $profile_link . '?url=status';
|
||||
$photos_link = $profile_link . '?url=photos';
|
||||
$profile_link = $profile_link . '?url=profile';
|
||||
$zurl = '';
|
||||
} else
|
||||
} else {
|
||||
$profile_link = zrl($profile_link);
|
||||
}
|
||||
|
||||
if ($cid && !$item['self']) {
|
||||
$poke_link = 'poke/?f=&c=' . $cid;
|
||||
$contact_url = 'contacts/' . $cid;
|
||||
$posts_link = 'contacts/' . $cid . '/posts';
|
||||
|
||||
if (in_array($network, array(NETWORK_DFRN, NETWORK_DIASPORA)))
|
||||
if (in_array($network, array(NETWORK_DFRN, NETWORK_DIASPORA))) {
|
||||
$pm_url = 'message/new/' . $cid;
|
||||
}
|
||||
}
|
||||
|
||||
if (local_user()) {
|
||||
$menu = Array(
|
||||
t("Follow Thread") => $sub_link,
|
||||
t("View Status") => $status_link,
|
||||
t("View Profile") => $profile_link,
|
||||
t("View Photos") => $photos_link,
|
||||
t("Network Posts") => $posts_link,
|
||||
t("Edit Contact") => $contact_url,
|
||||
t("Send PM") => $pm_url
|
||||
t('Follow Thread') => $sub_link,
|
||||
t('View Status') => $status_link,
|
||||
t('View Profile') => $profile_link,
|
||||
t('View Photos') => $photos_link,
|
||||
t('Network Posts') => $posts_link,
|
||||
t('View Contact') => $contact_url,
|
||||
t('Send PM') => $pm_url
|
||||
);
|
||||
|
||||
if ($network == NETWORK_DFRN)
|
||||
if ($network == NETWORK_DFRN) {
|
||||
$menu[t("Poke")] = $poke_link;
|
||||
}
|
||||
|
||||
if ((($cid == 0) OR ($rel == CONTACT_IS_FOLLOWER)) AND
|
||||
in_array($item['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
|
||||
$menu[t("Connect/Follow")] = "follow?url=".urlencode($item['author-link']);
|
||||
} else
|
||||
$menu = array(t("View Profile") => $item['author-link']);
|
||||
in_array($item['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
|
||||
$menu[t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']);
|
||||
}
|
||||
} else {
|
||||
$menu = array(t('View Profile') => $item['author-link']);
|
||||
}
|
||||
|
||||
$args = array('item' => $item, 'menu' => $menu);
|
||||
|
||||
|
@ -992,13 +990,14 @@ function item_photo_menu($item){
|
|||
|
||||
$menu = $args['menu'];
|
||||
|
||||
$o = "";
|
||||
$o = '';
|
||||
foreach ($menu as $k => $v) {
|
||||
if (strpos($v, 'javascript:') === 0) {
|
||||
$v = substr($v, 11);
|
||||
$o .= "<li role=\"menuitem\"><a onclick=\"$v\">$k</a></li>\n";
|
||||
$o .= '<li role="menuitem"><a onclick="' . $v . '">' . $k . '</a></li>' . PHP_EOL;
|
||||
} elseif ($v!='') {
|
||||
$o .= '<li role="menuitem"><a href="' . $v . '">' . $k . '</a></li>' . PHP_EOL;
|
||||
}
|
||||
elseif ($v!="") $o .= "<li role=\"menuitem\"><a href=\"$v\">$k</a></li>\n";
|
||||
}
|
||||
return $o;
|
||||
}}
|
||||
|
@ -1145,7 +1144,7 @@ function format_like($cnt,$arr,$type,$id) {
|
|||
$explikers = sprintf( t('%s don\'t attend.'), $likers);
|
||||
break;
|
||||
case 'attendmaybe':
|
||||
$phrase = sprintf( t('<span %1$s>%2$d people</span> anttend maybe'), $spanatts, $cnt);
|
||||
$phrase = sprintf( t('<span %1$s>%2$d people</span> attend maybe'), $spanatts, $cnt);
|
||||
$explikers = sprintf( t('%s anttend maybe.'), $likers);
|
||||
break;
|
||||
}
|
||||
|
@ -1289,6 +1288,10 @@ function status_editor($a,$x, $notes_cid = 0, $popup=false) {
|
|||
'$private' => t('Private post'),
|
||||
'$is_private' => $private_post,
|
||||
'$public_link' => $public_post_link,
|
||||
|
||||
//jot nav tab (used in some themes)
|
||||
'$message' => t('Message'),
|
||||
'$browser' => t('Browser'),
|
||||
));
|
||||
|
||||
|
||||
|
|
119
include/cron.php
119
include/cron.php
|
@ -11,6 +11,7 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
|
|||
}
|
||||
|
||||
require_once("boot.php");
|
||||
require_once("include/photos.php");
|
||||
|
||||
|
||||
function cron_run(&$argv, &$argc){
|
||||
|
@ -27,7 +28,6 @@ function cron_run(&$argv, &$argc){
|
|||
unset($db_host, $db_user, $db_pass, $db_data);
|
||||
};
|
||||
|
||||
|
||||
require_once('include/session.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/items.php');
|
||||
|
@ -70,36 +70,33 @@ function cron_run(&$argv, &$argc){
|
|||
|
||||
// run queue delivery process in the background
|
||||
|
||||
proc_run('php',"include/queue.php");
|
||||
proc_run(PRIORITY_NEGLIGIBLE, "include/queue.php");
|
||||
|
||||
// run the process to discover global contacts in the background
|
||||
|
||||
proc_run('php',"include/discover_poco.php");
|
||||
proc_run(PRIORITY_LOW, "include/discover_poco.php");
|
||||
|
||||
// run the process to update locally stored global contacts in the background
|
||||
|
||||
proc_run('php',"include/discover_poco.php", "checkcontact");
|
||||
proc_run(PRIORITY_LOW, "include/discover_poco.php", "checkcontact");
|
||||
|
||||
// expire any expired accounts
|
||||
// Expire and remove user entries
|
||||
cron_expire_and_remove_users();
|
||||
|
||||
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() ");
|
||||
// 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");
|
||||
|
||||
// delete user and contact records for recently removed accounts
|
||||
// Check every conversation
|
||||
proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_conversations");
|
||||
|
||||
$r = q("SELECT * FROM `user` WHERE `account_removed` = 1 AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
|
||||
if ($r) {
|
||||
foreach($r as $user) {
|
||||
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
|
||||
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
|
||||
}
|
||||
}
|
||||
|
||||
$abandon_days = intval(get_config('system','account_abandon_days'));
|
||||
if($abandon_days < 1)
|
||||
$abandon_days = 0;
|
||||
// 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);
|
||||
|
@ -113,9 +110,7 @@ function cron_run(&$argv, &$argc){
|
|||
|
||||
// update nodeinfo data
|
||||
nodeinfo_cron();
|
||||
|
||||
/// @TODO Regenerate usage statistics
|
||||
// q("ANALYZE TABLE `item`");
|
||||
}
|
||||
|
||||
// once daily run birthday_updates and then expire in background
|
||||
|
||||
|
@ -126,11 +121,15 @@ function cron_run(&$argv, &$argc){
|
|||
|
||||
update_contact_birthdays();
|
||||
|
||||
proc_run('php',"include/discover_poco.php", "suggestions");
|
||||
proc_run(PRIORITY_LOW, "include/discover_poco.php", "suggestions");
|
||||
|
||||
set_config('system','last_expire_day',$d2);
|
||||
|
||||
proc_run('php','include/expire.php');
|
||||
proc_run(PRIORITY_LOW, 'include/expire.php');
|
||||
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php');
|
||||
|
||||
cron_update_photo_albums();
|
||||
}
|
||||
|
||||
// Clear cache entries
|
||||
|
@ -142,6 +141,56 @@ function cron_run(&$argv, &$argc){
|
|||
// Repair entries in the database
|
||||
cron_repair_database();
|
||||
|
||||
// Poll contacts
|
||||
cron_poll_contacts($argc, $argv);
|
||||
|
||||
logger('cron: end');
|
||||
|
||||
set_config('system','last_cron', time());
|
||||
|
||||
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
|
||||
*
|
||||
* @param Integer $argc Number of command line arguments
|
||||
* @param Array $argv Array of command line arguments
|
||||
*/
|
||||
function cron_poll_contacts($argc, $argv) {
|
||||
$manual_id = 0;
|
||||
$generation = 0;
|
||||
$force = false;
|
||||
|
@ -180,6 +229,10 @@ function cron_run(&$argv, &$argc){
|
|||
// and which have a polling address and ignore Diaspora since
|
||||
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
|
||||
|
||||
$abandon_days = intval(get_config('system','account_abandon_days'));
|
||||
if($abandon_days < 1)
|
||||
$abandon_days = 0;
|
||||
|
||||
$abandon_sql = (($abandon_days)
|
||||
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
|
||||
: ''
|
||||
|
@ -272,18 +325,16 @@ function cron_run(&$argv, &$argc){
|
|||
|
||||
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
|
||||
|
||||
proc_run('php','include/onepoll.php',$contact['id']);
|
||||
if ($contact["remote_self"]) {
|
||||
proc_run(PRIORITY_MEDIUM, 'include/onepoll.php', $contact['id']);
|
||||
} else {
|
||||
proc_run(PRIORITY_LOW, 'include/onepoll.php', $contact['id']);
|
||||
}
|
||||
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
logger('cron: end');
|
||||
|
||||
set_config('system','last_cron', time());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,10 +378,10 @@ function cron_clear_cache(&$a) {
|
|||
}
|
||||
|
||||
// Delete the cached OEmbed entries that are older than one year
|
||||
q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 1 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 1 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;
|
||||
|
|
|
@ -31,6 +31,17 @@ function cronhooks_run(&$argv, &$argc){
|
|||
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]) {
|
||||
logger("Calling cron hook '".$hook[1]."'", LOGGER_DEBUG);
|
||||
call_single_hook($a, $name, $hook, $data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$last = get_config('system','last_cronhook');
|
||||
|
||||
$poll_interval = intval(get_config('system','cronhook_interval'));
|
||||
|
@ -47,12 +58,16 @@ function cronhooks_run(&$argv, &$argc){
|
|||
|
||||
$a->set_baseurl(get_config('system','url'));
|
||||
|
||||
load_hooks();
|
||||
|
||||
logger('cronhooks: start');
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
if (get_config("system", "worker") AND 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');
|
||||
|
|
77
include/cronjobs.php
Normal file
77
include/cronjobs.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
|
||||
$directory = dirname($_SERVER["argv"][0]);
|
||||
|
||||
if (substr($directory, 0, 1) != "/")
|
||||
$directory = $_SERVER["PWD"]."/".$directory;
|
||||
|
||||
$directory = realpath($directory."/..");
|
||||
|
||||
chdir($directory);
|
||||
}
|
||||
|
||||
require_once("boot.php");
|
||||
|
||||
|
||||
function cronjobs_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/ostatus.php');
|
||||
require_once('include/post_update.php');
|
||||
require_once('mod/nodeinfo.php');
|
||||
|
||||
load_config('config');
|
||||
load_config('system');
|
||||
|
||||
$a->set_baseurl(get_config('system','url'));
|
||||
|
||||
// No parameter set? So return
|
||||
if ($argc <= 1)
|
||||
return;
|
||||
|
||||
// Check OStatus conversations
|
||||
// Check only conversations with mentions (for a longer time)
|
||||
if ($argv[1] == 'ostatus_mentions') {
|
||||
ostatus::check_conversations(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check every conversation
|
||||
if ($argv[1] == 'ostatus_conversations') {
|
||||
ostatus::check_conversations(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Call possible post update functions
|
||||
// see include/post_update.php for more details
|
||||
if ($argv[1] == 'post_update') {
|
||||
post_update();
|
||||
return;
|
||||
}
|
||||
|
||||
// update nodeinfo data
|
||||
if ($argv[1] == 'nodeinfo') {
|
||||
nodeinfo_cron();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_search(__file__,get_included_files())===0){
|
||||
cronjobs_run($_SERVER["argv"],$_SERVER["argc"]);
|
||||
killme();
|
||||
}
|
|
@ -213,7 +213,7 @@ function dob($dob) {
|
|||
* @return string Parsed HTML output.
|
||||
*/
|
||||
function datesel($format, $min, $max, $default, $id = 'datepicker') {
|
||||
return datetimesel($format,$min,$max,$default,$id,true,false, '','');
|
||||
return datetimesel($format,$min,$max,$default,'',$id,true,false, '','');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -231,7 +231,7 @@ function datesel($format, $min, $max, $default, $id = 'datepicker') {
|
|||
* @return string Parsed HTML output.
|
||||
*/
|
||||
function timesel($format, $h, $m, $id='timepicker') {
|
||||
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),$id,false,true);
|
||||
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),'',$id,false,true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,7 +262,7 @@ function timesel($format, $h, $m, $id='timepicker') {
|
|||
* @todo Once browser support is better this could probably be replaced with
|
||||
* native HTML5 date picker.
|
||||
*/
|
||||
function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
|
||||
function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
|
||||
|
||||
// First day of the week (0 = Sunday)
|
||||
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
|
||||
|
@ -284,7 +284,7 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
|
|||
$minjs = $min ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : '';
|
||||
$maxjs = $max ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : '';
|
||||
|
||||
$input_text = $default ? 'value="' . date($dateformat, $default->getTimestamp()) . '"' : '';
|
||||
$input_text = $default ? date($dateformat, $default->getTimestamp()) : '';
|
||||
$defaultdatejs = $default ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : '';
|
||||
|
||||
$pickers = '';
|
||||
|
@ -294,9 +294,9 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
|
|||
$extra_js = '';
|
||||
$pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'";
|
||||
if($minfrom != '')
|
||||
$extra_js .= "\$('#$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
|
||||
$extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
|
||||
if($maxfrom != '')
|
||||
$extra_js .= "\$('#$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
|
||||
$extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
|
||||
|
||||
$readable_format = $dateformat;
|
||||
$readable_format = str_replace('Y','yyyy',$readable_format);
|
||||
|
@ -305,10 +305,13 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
|
|||
$readable_format = str_replace('H','HH',$readable_format);
|
||||
$readable_format = str_replace('i','MM',$readable_format);
|
||||
|
||||
$o .= "<div class='date'><input type='text' placeholder='$readable_format' name='$id' id='$id' $input_text />";
|
||||
$o .= '</div>';
|
||||
$tpl = get_markup_template('field_input.tpl');
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$field' => array($id, $label, $input_text, '', (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'),
|
||||
));
|
||||
|
||||
$o .= "<script type='text/javascript'>";
|
||||
$o .= "\$(function () {var picker = \$('#$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
|
||||
$o .= "\$(function () {var picker = \$('#id_$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
|
||||
$o .= "</script>";
|
||||
|
||||
return $o;
|
||||
|
@ -322,7 +325,7 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
|
|||
* Results relative to current timezone.
|
||||
* Limited to range of timestamps.
|
||||
*
|
||||
* @param string $posted_date
|
||||
* @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS)
|
||||
* @param string $format (optional) Parsed with sprintf()
|
||||
* <tt>%1$d %2$s ago</tt>, e.g. 22 hours ago, 1 minute ago
|
||||
*
|
||||
|
@ -330,7 +333,7 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
|
|||
*/
|
||||
function relative_date($posted_date, $format = null) {
|
||||
|
||||
$localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date);
|
||||
$localtime = $posted_date . ' UTC';
|
||||
|
||||
$abs = strtotime($localtime);
|
||||
|
||||
|
@ -344,13 +347,6 @@ function relative_date($posted_date,$format = null) {
|
|||
return t('less than a second ago');
|
||||
}
|
||||
|
||||
/*
|
||||
$time_append = '';
|
||||
if ($etime >= 86400) {
|
||||
$time_append = ' ('.$localtime.')';
|
||||
}
|
||||
*/
|
||||
|
||||
$a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')),
|
||||
30 * 24 * 60 * 60 => array( t('month'), t('months')),
|
||||
7 * 24 * 60 * 60 => array( t('week'), t('weeks')),
|
||||
|
@ -365,8 +361,9 @@ function relative_date($posted_date,$format = null) {
|
|||
if ($d >= 1) {
|
||||
$r = round($d);
|
||||
// translators - e.g. 22 hours ago, 1 minute ago
|
||||
if(! $format)
|
||||
if (!$format) {
|
||||
$format = t('%1$d %2$s ago');
|
||||
}
|
||||
|
||||
return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1]));
|
||||
}
|
||||
|
|
188
include/dba.php
188
include/dba.php
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
require_once("dbm.php");
|
||||
|
||||
# if PDO is avaible for mysql, use the new database abstraction
|
||||
# TODO: PDO is disabled for release 3.3. We need to investigate why
|
||||
|
@ -65,19 +66,24 @@ class dba {
|
|||
if (! mysqli_connect_errno()) {
|
||||
$this->connected = true;
|
||||
}
|
||||
if (isset($a->config["system"]["db_charset"])) {
|
||||
$this->db->set_charset($a->config["system"]["db_charset"]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->mysqli = false;
|
||||
$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);
|
||||
}
|
||||
if (!$this->connected) {
|
||||
$this->db = null;
|
||||
if(! $install)
|
||||
if (!$install) {
|
||||
system_unavailable();
|
||||
}
|
||||
}
|
||||
|
||||
$a->save_timestamp($stamp1, "network");
|
||||
}
|
||||
|
@ -86,26 +92,79 @@ class dba {
|
|||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the MySQL server version string
|
||||
*
|
||||
* This function discriminate between the deprecated mysql API and the current
|
||||
* object-oriented mysqli API. Example of returned string: 5.5.46-0+deb8u1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function server_info() {
|
||||
if ($this->mysqli) {
|
||||
$return = $this->db->server_info;
|
||||
} else {
|
||||
$return = mysql_get_server_info($this->db);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of rows
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function num_rows() {
|
||||
if (!$this->result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($this->mysqli) {
|
||||
$return = $this->result->num_rows;
|
||||
} else {
|
||||
$return = mysql_num_rows($this->result);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function q($sql, $onlyquery = false) {
|
||||
global $a;
|
||||
|
||||
if((! $this->db) || (! $this->connected))
|
||||
if (!$this->db || !$this->connected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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");
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
if($this->mysqli)
|
||||
$result = @$this->db->query($sql);
|
||||
else
|
||||
$result = @mysql_query($sql,$this->db);
|
||||
$orig_sql = $sql;
|
||||
|
||||
if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) {
|
||||
$sql = "/*".$a->callstack()." */ ".$sql;
|
||||
}
|
||||
|
||||
if ($this->mysqli) {
|
||||
$result = @$this->db->query($sql);
|
||||
} else {
|
||||
$result = @mysql_query($sql,$this->db);
|
||||
}
|
||||
$stamp2 = microtime(true);
|
||||
$duration = (float)($stamp2-$stamp1);
|
||||
|
||||
$a->save_timestamp($stamp1, "database");
|
||||
|
||||
if (strtolower(substr($orig_sql, 0, 6)) != "select") {
|
||||
$a->save_timestamp($stamp1, "database_write");
|
||||
}
|
||||
if (x($a->config,'system') && x($a->config['system'],'db_log')) {
|
||||
if (($duration > $a->config["system"]["db_loglimit"])) {
|
||||
$duration = round($duration, 3);
|
||||
|
@ -118,30 +177,34 @@ class dba {
|
|||
}
|
||||
|
||||
if ($this->mysqli) {
|
||||
if($this->db->errno)
|
||||
if ($this->db->errno) {
|
||||
$this->error = $this->db->error;
|
||||
$this->errorno = $this->db->errno;
|
||||
}
|
||||
elseif(mysql_errno($this->db))
|
||||
} elseif (mysql_errno($this->db)) {
|
||||
$this->error = mysql_error($this->db);
|
||||
$this->errorno = mysql_errno($this->db);
|
||||
}
|
||||
|
||||
if (strlen($this->error)) {
|
||||
logger('dba: ' . $this->error);
|
||||
logger('DB Error ('.$connstr.') '.$this->errorno.': '.$this->error);
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
|
||||
$mesg = '';
|
||||
|
||||
if($result === false)
|
||||
if ($result === false) {
|
||||
$mesg = 'false';
|
||||
elseif($result === true)
|
||||
} elseif ($result === true) {
|
||||
$mesg = 'true';
|
||||
else {
|
||||
if($this->mysqli)
|
||||
} else {
|
||||
if ($this->mysqli) {
|
||||
$mesg = $result->num_rows . ' results' . EOL;
|
||||
else
|
||||
} else {
|
||||
$mesg = mysql_num_rows($result) . ' results' . EOL;
|
||||
}
|
||||
}
|
||||
|
||||
$str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
|
||||
. (($this->error) ? ' error: ' . $this->error : '')
|
||||
|
@ -158,13 +221,14 @@ class dba {
|
|||
|
||||
if ($result === false) {
|
||||
logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
|
||||
if(file_exists('dbfail.out'))
|
||||
if (file_exists('dbfail.out')) {
|
||||
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
if(($result === true) || ($result === false))
|
||||
if (($result === true) || ($result === false)) {
|
||||
return $result;
|
||||
|
||||
}
|
||||
if ($onlyquery) {
|
||||
$this->result = $result;
|
||||
return true;
|
||||
|
@ -177,8 +241,7 @@ class dba {
|
|||
$r[] = $x;
|
||||
$result->free_result();
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (mysql_num_rows($result)) {
|
||||
while($x = mysql_fetch_array($result, MYSQL_ASSOC))
|
||||
$r[] = $x;
|
||||
|
@ -188,15 +251,16 @@ class dba {
|
|||
|
||||
//$a->save_timestamp($stamp1, "database");
|
||||
|
||||
if($this->debug)
|
||||
if ($this->debug) {
|
||||
logger('dba: ' . printable(print_r($r, true)));
|
||||
}
|
||||
return($r);
|
||||
}
|
||||
|
||||
public function qfetch() {
|
||||
$x = false;
|
||||
|
||||
if ($this->result)
|
||||
if ($this->result) {
|
||||
if ($this->mysqli) {
|
||||
if ($this->result->num_rows)
|
||||
$x = $this->result->fetch_array(MYSQLI_ASSOC);
|
||||
|
@ -204,18 +268,19 @@ class dba {
|
|||
if (mysql_num_rows($this->result))
|
||||
$x = mysql_fetch_array($this->result, MYSQL_ASSOC);
|
||||
}
|
||||
|
||||
}
|
||||
return($x);
|
||||
}
|
||||
|
||||
public function qclose() {
|
||||
if ($this->result)
|
||||
if ($this->result) {
|
||||
if ($this->mysqli) {
|
||||
$this->result->free_result();
|
||||
} else {
|
||||
mysql_free_result($this->result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function dbg($dbg) {
|
||||
$this->debug = $dbg;
|
||||
|
@ -223,28 +288,41 @@ class dba {
|
|||
|
||||
public function escape($str) {
|
||||
if ($this->db && $this->connected) {
|
||||
if($this->mysqli)
|
||||
if ($this->mysqli) {
|
||||
return @$this->db->real_escape_string($str);
|
||||
else
|
||||
} else {
|
||||
return @mysql_real_escape_string($str,$this->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connected() {
|
||||
if ($this->mysqli) {
|
||||
$connected = $this->db->ping();
|
||||
} else {
|
||||
$connected = mysql_ping($this->db);
|
||||
}
|
||||
return $connected;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
if ($this->db)
|
||||
if($this->mysqli)
|
||||
if ($this->db) {
|
||||
if ($this->mysqli) {
|
||||
$this->db->close();
|
||||
else
|
||||
} else {
|
||||
mysql_close($this->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
if (! function_exists('printable')) {
|
||||
function printable($s) {
|
||||
$s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
|
||||
$s = str_replace("\x00",'.',$s);
|
||||
if(x($_SERVER,'SERVER_NAME'))
|
||||
if (x($_SERVER,'SERVER_NAME')) {
|
||||
$s = escape_tags($s);
|
||||
}
|
||||
return $s;
|
||||
}}
|
||||
|
||||
|
@ -252,17 +330,19 @@ function printable($s) {
|
|||
if (! function_exists('dbg')) {
|
||||
function dbg($state) {
|
||||
global $db;
|
||||
if($db)
|
||||
if ($db) {
|
||||
$db->dbg($state);
|
||||
}
|
||||
}}
|
||||
|
||||
if (! function_exists('dbesc')) {
|
||||
function dbesc($str) {
|
||||
global $db;
|
||||
if($db && $db->connected)
|
||||
if ($db && $db->connected) {
|
||||
return($db->escape($str));
|
||||
else
|
||||
} else {
|
||||
return(str_replace("'","\\'",$str));
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
|
@ -298,6 +378,42 @@ function q($sql) {
|
|||
|
||||
}}
|
||||
|
||||
/**
|
||||
* @brief Performs a query with "dirty reads"
|
||||
*
|
||||
* By doing dirty reads (reading uncommitted data) no locks are performed
|
||||
* This function can be used to fetch data that doesn't need to be reliable.
|
||||
*
|
||||
* @param $args Query parameters (1 to N parameters of different types)
|
||||
* @return array Query array
|
||||
*/
|
||||
function qu($sql) {
|
||||
|
||||
global $db;
|
||||
$args = func_get_args();
|
||||
unset($args[0]);
|
||||
|
||||
if ($db && $db->connected) {
|
||||
$stmt = @vsprintf($sql,$args); // Disabled warnings
|
||||
if ($stmt === false)
|
||||
logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
|
||||
$db->q("SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
|
||||
$retval = $db->q($stmt);
|
||||
$db->q("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;");
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This will happen occasionally trying to store the
|
||||
* session data after abnormal program termination
|
||||
*
|
||||
*/
|
||||
logger('dba: no database: ' . print_r($args,true));
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Raw db query, no arguments
|
||||
|
@ -308,10 +424,11 @@ if(! function_exists('dbq')) {
|
|||
function dbq($sql) {
|
||||
|
||||
global $db;
|
||||
if($db && $db->connected)
|
||||
if ($db && $db->connected) {
|
||||
$ret = $db->q($sql);
|
||||
else
|
||||
} else {
|
||||
$ret = false;
|
||||
}
|
||||
return $ret;
|
||||
}}
|
||||
|
||||
|
@ -340,4 +457,3 @@ function dbesc_array(&$arr) {
|
|||
function dba_timer() {
|
||||
return microtime(true);
|
||||
}
|
||||
|
||||
|
|
157
include/dbclean.php
Normal file
157
include/dbclean.php
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
/**
|
||||
* @file include/dbclean.php
|
||||
* @brief The script is called from time to time to clean the database entries and remove orphaned data.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
load_config('config');
|
||||
load_config('system');
|
||||
|
||||
if ($argc == 2) {
|
||||
$stage = intval($argv[1]);
|
||||
} else {
|
||||
$stage = 0;
|
||||
}
|
||||
|
||||
if (get_config("system", "worker") AND ($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);
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php', 4);
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php', 5);
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php', 6);
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php', 7);
|
||||
} else {
|
||||
remove_orphans($stage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove orphaned database entries
|
||||
*/
|
||||
function remove_orphans($stage = 0) {
|
||||
global $db;
|
||||
|
||||
$count = 0;
|
||||
|
||||
if (($stage == 1) OR ($stage == 0)) {
|
||||
logger("Deleting old global item entries from item table without user copy");
|
||||
if ($db->q("SELECT `id` FROM `item` WHERE `uid` = 0
|
||||
AND NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0)
|
||||
AND `received` < UTC_TIMESTAMP() - INTERVAL 90 DAY LIMIT 10000", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found global item orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `item` WHERE `id` = %d", intval($orphan["id"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting old global item entries from item table without user copy");
|
||||
}
|
||||
|
||||
if (($stage == 2) OR ($stage == 0)) {
|
||||
logger("Deleting items without parents");
|
||||
if ($db->q("SELECT `id` FROM `item` WHERE NOT EXISTS (SELECT `id` FROM `item` AS `i` WHERE `item`.`parent` = `i`.`id`) LIMIT 10000", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found item orphans without parents: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `item` WHERE `id` = %d", intval($orphan["id"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting items without parents");
|
||||
}
|
||||
|
||||
if (($stage == 3) OR ($stage == 0)) {
|
||||
logger("Deleting orphaned data from thread table");
|
||||
if ($db->q("SELECT `iid` FROM `thread` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `thread`.`iid`)", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found thread orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `thread` WHERE `iid` = %d", intval($orphan["iid"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting orphaned data from thread table");
|
||||
}
|
||||
|
||||
if (($stage == 4) OR ($stage == 0)) {
|
||||
logger("Deleting orphaned data from notify table");
|
||||
if ($db->q("SELECT `iid` FROM `notify` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `notify`.`iid`)", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found notify orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `notify` WHERE `iid` = %d", intval($orphan["iid"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting orphaned data from notify table");
|
||||
}
|
||||
|
||||
if (($stage == 5) OR ($stage == 0)) {
|
||||
logger("Deleting orphaned data from notify-threads table");
|
||||
if ($db->q("SELECT `id` FROM `notify-threads` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `notify-threads`.`master-parent-item`)", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found notify-threads orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `notify-threads` WHERE `id` = %d", intval($orphan["id"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting orphaned data from notify-threads table");
|
||||
}
|
||||
|
||||
|
||||
if (($stage == 6) OR ($stage == 0)) {
|
||||
logger("Deleting orphaned data from sign table");
|
||||
if ($db->q("SELECT `iid` FROM `sign` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `sign`.`iid`)", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found sign orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `sign` WHERE `iid` = %d", intval($orphan["iid"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting orphaned data from sign table");
|
||||
}
|
||||
|
||||
|
||||
if (($stage == 7) OR ($stage == 0)) {
|
||||
logger("Deleting orphaned data from term table");
|
||||
if ($db->q("SELECT `oid` FROM `term` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `term`.`oid`)", true)) {
|
||||
$count = $db->num_rows();
|
||||
logger("found term orphans: ".$count);
|
||||
while ($orphan = $db->qfetch()) {
|
||||
q("DELETE FROM `term` WHERE `oid` = %d", intval($orphan["oid"]));
|
||||
}
|
||||
}
|
||||
$db->qclose();
|
||||
logger("Done deleting orphaned data from term table");
|
||||
}
|
||||
|
||||
// Call it again if not all entries were purged
|
||||
if (($stage != 0) AND ($count > 0) AND get_config("system", "worker")) {
|
||||
proc_run(PRIORITY_LOW, 'include/dbclean.php');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (array_search(__file__,get_included_files())===0){
|
||||
dbclean_run($_SERVER["argv"],$_SERVER["argc"]);
|
||||
killme();
|
||||
}
|
||||
?>
|
|
@ -20,8 +20,8 @@ class dbm {
|
|||
foreach ($r AS $process) {
|
||||
$state = trim($process["State"]);
|
||||
|
||||
// Filter out all idle processes
|
||||
if (!in_array($state, array("", "init", "statistics"))) {
|
||||
// Filter out all non blocking processes
|
||||
if (!in_array($state, array("", "init", "statistics", "updating"))) {
|
||||
++$states[$state];
|
||||
++$processes;
|
||||
}
|
||||
|
@ -35,5 +35,19 @@ class dbm {
|
|||
}
|
||||
return(array("list" => $statelist, "amount" => $processes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if $array is a filled array with at least one entry.
|
||||
*
|
||||
* @param $array mixed A filled array with at least one entry
|
||||
* @return Whether $array is a filled array
|
||||
*/
|
||||
public static function is_result($array) {
|
||||
// It could be a return value from an update statement
|
||||
if (is_bool($array)) {
|
||||
return $array;
|
||||
}
|
||||
return (is_array($array) && count($array) > 0);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -78,8 +78,16 @@ function table_structure($table) {
|
|||
if ($index["Index_type"] == "FULLTEXT")
|
||||
continue;
|
||||
|
||||
if ($index['Key_name'] != 'PRIMARY' && $index['Non_unique'] == '0' && !isset($indexdata[$index["Key_name"]])) {
|
||||
$indexdata[$index["Key_name"]] = array('UNIQUE');
|
||||
}
|
||||
|
||||
$column = $index["Column_name"];
|
||||
if ($index["Sub_part"] != "")
|
||||
// On utf8mb4 a varchar index can only have a length of 191
|
||||
// To avoid the need to add this to every index definition we just ignore it here.
|
||||
// Exception are primary indexes
|
||||
// Since there are some combindex primary indexes we use the limit of 180 here.
|
||||
if (($index["Sub_part"] != "") AND (($index["Sub_part"] < 180) OR ($index["Key_name"] == "PRIMARY")))
|
||||
$column .= "(".$index["Sub_part"].")";
|
||||
|
||||
$indexdata[$index["Key_name"]][] = $column;
|
||||
|
@ -104,7 +112,7 @@ function table_structure($table) {
|
|||
return(array("fields"=>$fielddata, "indexes"=>$indexdata));
|
||||
}
|
||||
|
||||
function print_structure($database) {
|
||||
function print_structure($database, $charset) {
|
||||
echo "-- ------------------------------------------\n";
|
||||
echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
|
||||
echo "-- DB_UPDATE_VERSION ".DB_UPDATE_VERSION."\n";
|
||||
|
@ -113,7 +121,7 @@ function print_structure($database) {
|
|||
echo "--\n";
|
||||
echo "-- TABLE $name\n";
|
||||
echo "--\n";
|
||||
db_create_table($name, $structure['fields'], true, false, $structure["indexes"]);
|
||||
db_create_table($name, $structure['fields'], $charset, true, false, $structure["indexes"]);
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
|
@ -122,6 +130,14 @@ function print_structure($database) {
|
|||
function update_structure($verbose, $action, $tables=null, $definition=null) {
|
||||
global $a, $db;
|
||||
|
||||
if ($action)
|
||||
set_config('system', 'maintenance', 1);
|
||||
|
||||
if (isset($a->config["system"]["db_charset"]))
|
||||
$charset = $a->config["system"]["db_charset"];
|
||||
else
|
||||
$charset = "utf8";
|
||||
|
||||
$errors = false;
|
||||
|
||||
logger('updating structure', LOGGER_DEBUG);
|
||||
|
@ -140,15 +156,29 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
|
|||
|
||||
// Get the definition
|
||||
if (is_null($definition))
|
||||
$definition = db_definition();
|
||||
$definition = db_definition($charset);
|
||||
|
||||
// Ensure index conversion to unique removes duplicates
|
||||
$sql_config = "SET session old_alter_table=1;";
|
||||
if ($verbose)
|
||||
echo $sql_config."\n";
|
||||
if ($action)
|
||||
@$db->q($sql_config);
|
||||
|
||||
// MySQL >= 5.7.4 doesn't support the IGNORE keyword in ALTER TABLE statements
|
||||
if ((version_compare($db->server_info(), '5.7.4') >= 0) AND
|
||||
!(strpos($db->server_info(), 'MariaDB') !== false)) {
|
||||
$ignore = '';
|
||||
}else {
|
||||
$ignore = ' IGNORE';
|
||||
}
|
||||
|
||||
// Compare it
|
||||
foreach ($definition AS $name => $structure) {
|
||||
$is_new_table = False;
|
||||
$sql3="";
|
||||
if (!isset($database[$name])) {
|
||||
$r = db_create_table($name, $structure["fields"], $verbose, $action, $structure['indexes']);
|
||||
$r = db_create_table($name, $structure["fields"], $charset, $verbose, $action, $structure['indexes']);
|
||||
if(false === $r) {
|
||||
$errors .= t('Errors encountered creating database tables.').$name.EOL;
|
||||
}
|
||||
|
@ -167,7 +197,7 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
|
|||
if ($current_index_definition != $new_index_definition && substr($indexname, 0, 6) != 'local_') {
|
||||
$sql2=db_drop_index($indexname);
|
||||
if ($sql3 == "")
|
||||
$sql3 = "ALTER TABLE `".$name."` ".$sql2;
|
||||
$sql3 = "ALTER".$ignore." TABLE `".$name."` ".$sql2;
|
||||
else
|
||||
$sql3 .= ", ".$sql2;
|
||||
}
|
||||
|
@ -211,7 +241,7 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
|
|||
$sql2=db_create_index($indexname, $fieldnames);
|
||||
if ($sql2 != "") {
|
||||
if ($sql3 == "")
|
||||
$sql3 = "ALTER TABLE `".$name."` ".$sql2;
|
||||
$sql3 = "ALTER" . $ignore . " TABLE `".$name."` ".$sql2;
|
||||
else
|
||||
$sql3 .= ", ".$sql2;
|
||||
}
|
||||
|
@ -232,6 +262,9 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
|
|||
}
|
||||
}
|
||||
|
||||
if ($action)
|
||||
set_config('system', 'maintenance', 0);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
@ -257,7 +290,7 @@ function db_field_command($parameters, $create = true) {
|
|||
return($fieldstruct);
|
||||
}
|
||||
|
||||
function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
|
||||
function db_create_table($name, $fields, $charset, $verbose, $action, $indexes=null) {
|
||||
global $a, $db;
|
||||
|
||||
$r = true;
|
||||
|
@ -282,7 +315,7 @@ function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
|
|||
|
||||
$sql = implode(",\n\t", $sql_rows);
|
||||
|
||||
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
|
||||
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=".$charset;
|
||||
if ($verbose)
|
||||
echo $sql.";\n";
|
||||
|
||||
|
@ -315,9 +348,9 @@ function db_create_index($indexname, $fieldnames, $method="ADD") {
|
|||
killme();
|
||||
}
|
||||
|
||||
|
||||
if ($indexname == "PRIMARY") {
|
||||
return sprintf("%s PRIMARY KEY(`%s`)", $method, implode("`,`", $fieldnames));
|
||||
if ($fieldnames[0] == "UNIQUE") {
|
||||
array_shift($fieldnames);
|
||||
$method .= ' UNIQUE';
|
||||
}
|
||||
|
||||
$names = "";
|
||||
|
@ -331,12 +364,26 @@ function db_create_index($indexname, $fieldnames, $method="ADD") {
|
|||
$names .= "`".dbesc($fieldname)."`";
|
||||
}
|
||||
|
||||
if ($indexname == "PRIMARY") {
|
||||
return sprintf("%s PRIMARY KEY(%s)", $method, $names);
|
||||
}
|
||||
|
||||
|
||||
$sql = sprintf("%s INDEX `%s` (%s)", $method, dbesc($indexname), $names);
|
||||
return($sql);
|
||||
}
|
||||
|
||||
function db_definition() {
|
||||
function db_index_suffix($charset, $reduce = 0) {
|
||||
if ($charset != "utf8mb4")
|
||||
return "";
|
||||
|
||||
// On utf8mb4 indexes can only have a length of 191
|
||||
$indexlength = 191 - $reduce;
|
||||
|
||||
return "(".$indexlength.")";
|
||||
}
|
||||
|
||||
function db_definition($charset) {
|
||||
|
||||
$database = array();
|
||||
|
||||
|
@ -365,10 +412,10 @@ function db_definition() {
|
|||
"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"),
|
||||
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_cid" => array("type" => "mediumtext"),
|
||||
"allow_gid" => array("type" => "mediumtext"),
|
||||
"deny_cid" => array("type" => "mediumtext"),
|
||||
"deny_gid" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -389,13 +436,14 @@ function db_definition() {
|
|||
$database["cache"] = array(
|
||||
"fields" => array(
|
||||
"k" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
|
||||
"v" => array("type" => "text", "not null" => "1"),
|
||||
"v" => array("type" => "text"),
|
||||
"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"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("k"),
|
||||
"PRIMARY" => array("k".db_index_suffix($charset)),
|
||||
"updated" => array("updated"),
|
||||
"expire_mode_updated" => array("expire_mode", "updated"),
|
||||
)
|
||||
);
|
||||
$database["challenge"] = array(
|
||||
|
@ -429,11 +477,11 @@ function db_definition() {
|
|||
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"v" => array("type" => "text", "not null" => "1"),
|
||||
"v" => array("type" => "text"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
"cat_k" => array("cat(30)","k(30)"),
|
||||
"cat_k" => array("UNIQUE", "cat(30)","k(30)"),
|
||||
)
|
||||
);
|
||||
$database["contact"] = array(
|
||||
|
@ -449,29 +497,30 @@ function db_definition() {
|
|||
"name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"about" => array("type" => "text", "not null" => "1"),
|
||||
"keywords" => array("type" => "text", "not null" => "1"),
|
||||
"about" => array("type" => "text"),
|
||||
"keywords" => array("type" => "text"),
|
||||
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"xmpp" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"attag" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"photo" => array("type" => "text", "not null" => "1"),
|
||||
"thumb" => array("type" => "text", "not null" => "1"),
|
||||
"micro" => array("type" => "text", "not null" => "1"),
|
||||
"site-pubkey" => array("type" => "text", "not null" => "1"),
|
||||
"photo" => array("type" => "text"),
|
||||
"thumb" => array("type" => "text"),
|
||||
"micro" => array("type" => "text"),
|
||||
"site-pubkey" => array("type" => "text"),
|
||||
"issued-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"dfrn-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"pubkey" => array("type" => "text", "not null" => "1"),
|
||||
"prvkey" => array("type" => "text", "not null" => "1"),
|
||||
"pubkey" => array("type" => "text"),
|
||||
"prvkey" => array("type" => "text"),
|
||||
"batch" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"request" => array("type" => "text", "not null" => "1"),
|
||||
"notify" => array("type" => "text", "not null" => "1"),
|
||||
"poll" => array("type" => "text", "not null" => "1"),
|
||||
"confirm" => array("type" => "text", "not null" => "1"),
|
||||
"poco" => array("type" => "text", "not null" => "1"),
|
||||
"request" => array("type" => "text"),
|
||||
"notify" => array("type" => "text"),
|
||||
"poll" => array("type" => "text"),
|
||||
"confirm" => array("type" => "text"),
|
||||
"poco" => array("type" => "text"),
|
||||
"aes_allow" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"ret-aes" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
|
@ -491,23 +540,25 @@ function db_definition() {
|
|||
"writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"contact-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
|
||||
"hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
|
||||
"rating" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"reason" => array("type" => "text", "not null" => "1"),
|
||||
"reason" => array("type" => "text"),
|
||||
"closeness" => array("type" => "tinyint(2)", "not null" => "1", "default" => "99"),
|
||||
"info" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"info" => array("type" => "mediumtext"),
|
||||
"profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"bdyear" => array("type" => "varchar(4)", "not null" => "1", "default" => ""),
|
||||
"bd" => array("type" => "date", "not null" => "1", "default" => "0000-00-00"),
|
||||
"notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"ffi_keyword_blacklist" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"ffi_keyword_blacklist" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
"uid" => array("uid"),
|
||||
"addr_uid" => array("addr", "uid"),
|
||||
"nurl" => array("nurl"),
|
||||
)
|
||||
);
|
||||
|
@ -515,12 +566,12 @@ function db_definition() {
|
|||
"fields" => array(
|
||||
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""),
|
||||
"recips" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"recips" => array("type" => "mediumtext"),
|
||||
"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"),
|
||||
"subject" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"subject" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -536,6 +587,7 @@ function db_definition() {
|
|||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
"cmd_item_contact" => array("UNIQUE", "cmd", "item", "contact"),
|
||||
)
|
||||
);
|
||||
$database["event"] = array(
|
||||
|
@ -548,17 +600,17 @@ function db_definition() {
|
|||
"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"),
|
||||
"summary" => array("type" => "text", "not null" => "1"),
|
||||
"desc" => array("type" => "text", "not null" => "1"),
|
||||
"location" => array("type" => "text", "not null" => "1"),
|
||||
"summary" => array("type" => "text"),
|
||||
"desc" => array("type" => "text"),
|
||||
"location" => array("type" => "text"),
|
||||
"type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"nofinish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"adjust" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
|
||||
"ignore" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
|
||||
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_cid" => array("type" => "mediumtext"),
|
||||
"allow_gid" => array("type" => "mediumtext"),
|
||||
"deny_cid" => array("type" => "mediumtext"),
|
||||
"deny_gid" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -568,6 +620,7 @@ function db_definition() {
|
|||
$database["fcontact"] = array(
|
||||
"fields" => array(
|
||||
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
|
@ -581,7 +634,7 @@ function db_definition() {
|
|||
"priority" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"pubkey" => array("type" => "text", "not null" => "1"),
|
||||
"pubkey" => array("type" => "text"),
|
||||
"updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -605,7 +658,7 @@ function db_definition() {
|
|||
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"server" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"posturl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"key" => array("type" => "text", "not null" => "1"),
|
||||
"key" => array("type" => "text"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -621,7 +674,7 @@ function db_definition() {
|
|||
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"note" => array("type" => "text", "not null" => "1"),
|
||||
"note" => array("type" => "text"),
|
||||
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -654,16 +707,17 @@ function db_definition() {
|
|||
"last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
|
||||
"last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
|
||||
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"about" => array("type" => "text", "not null" => "1"),
|
||||
"keywords" => array("type" => "text", "not null" => "1"),
|
||||
"about" => array("type" => "text"),
|
||||
"keywords" => array("type" => "text"),
|
||||
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00"),
|
||||
"community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"contact-type" => array("type" => "tinyint(1)", "not null" => "1", "default" => "-1"),
|
||||
"hide" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"nsfw" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"notify" => array("type" => "text", "not null" => "1"),
|
||||
"notify" => array("type" => "text"),
|
||||
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
|
||||
"server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
|
@ -725,7 +779,7 @@ function db_definition() {
|
|||
"nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"site_name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"info" => array("type" => "text", "not null" => "1"),
|
||||
"info" => array("type" => "text"),
|
||||
"register_policy" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"poco" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
|
@ -762,7 +816,7 @@ function db_definition() {
|
|||
"contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"knowyou" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"note" => array("type" => "text", "not null" => "1"),
|
||||
"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"),
|
||||
"blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
|
||||
|
@ -792,34 +846,36 @@ function db_definition() {
|
|||
"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"),
|
||||
"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" => ""),
|
||||
"owner-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"author-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"author-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"author-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"author-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"body" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"body" => array("type" => "mediumtext"),
|
||||
"app" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"object-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"object" => array("type" => "text", "not null" => "1"),
|
||||
"object" => array("type" => "text"),
|
||||
"target-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"target" => array("type" => "text", "not null" => "1"),
|
||||
"postopts" => array("type" => "text", "not null" => "1"),
|
||||
"target" => array("type" => "text"),
|
||||
"postopts" => array("type" => "text"),
|
||||
"plink" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"resource-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"event-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"tag" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"attach" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"inform" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"file" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"tag" => array("type" => "mediumtext"),
|
||||
"attach" => array("type" => "mediumtext"),
|
||||
"inform" => array("type" => "mediumtext"),
|
||||
"file" => array("type" => "mediumtext"),
|
||||
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"coord" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_cid" => array("type" => "mediumtext"),
|
||||
"allow_gid" => array("type" => "mediumtext"),
|
||||
"deny_cid" => array("type" => "mediumtext"),
|
||||
"deny_gid" => array("type" => "mediumtext"),
|
||||
"private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"moderated" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
|
@ -835,7 +891,7 @@ function db_definition() {
|
|||
"mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"rendered-hash" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"rendered-html" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"rendered-html" => array("type" => "mediumtext"),
|
||||
"global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -855,15 +911,18 @@ function db_definition() {
|
|||
"uid_title" => array("uid","title"),
|
||||
"uid_thrparent" => array("uid","thr-parent"),
|
||||
"uid_parenturi" => array("uid","parent-uri"),
|
||||
"uid_contactid_id" => array("uid","contact-id","id"),
|
||||
"uid_contactid_created" => array("uid","contact-id","created"),
|
||||
"gcontactid_uid_created" => array("gcontact-id","uid","created"),
|
||||
"authorid_created" => array("author-id","created"),
|
||||
"ownerid_created" => array("owner-id","created"),
|
||||
"wall_body" => array("wall","body(6)"),
|
||||
"uid_visible_moderated_created" => array("uid","visible","moderated","created"),
|
||||
"uid_uri" => array("uid", "uri"),
|
||||
"uid_wall_created" => array("uid","wall","created"),
|
||||
"resource-id" => array("resource-id"),
|
||||
"uid_type" => array("uid","type"),
|
||||
"uid_starred" => array("uid","starred"),
|
||||
"uid_starred_id" => array("uid","starred", "id"),
|
||||
"contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
|
||||
"uid_wall_parent_created" => array("uid","wall","parent","created"),
|
||||
"uid_type_changed" => array("uid","type","changed"),
|
||||
|
@ -913,7 +972,7 @@ function db_definition() {
|
|||
"contact-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"convid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
|
||||
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"body" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"body" => array("type" => "mediumtext"),
|
||||
"seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"reply" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"replied" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
|
@ -941,7 +1000,7 @@ function db_definition() {
|
|||
"ssltype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""),
|
||||
"mailbox" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"user" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"pass" => array("type" => "text", "not null" => "1"),
|
||||
"pass" => array("type" => "text"),
|
||||
"reply_to" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"action" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"movetofolder" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
|
@ -972,7 +1031,7 @@ function db_definition() {
|
|||
"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"),
|
||||
"msg" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"msg" => array("type" => "mediumtext"),
|
||||
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"iid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
|
@ -980,6 +1039,8 @@ function db_definition() {
|
|||
"seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"otype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""),
|
||||
"name_cache" => array("type" => "tinytext"),
|
||||
"msg_cache" => array("type" => "mediumtext")
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -1003,11 +1064,11 @@ function db_definition() {
|
|||
$database["oembed"] = array(
|
||||
"fields" => array(
|
||||
"url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
|
||||
"content" => array("type" => "text", "not null" => "1"),
|
||||
"content" => array("type" => "text"),
|
||||
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("url"),
|
||||
"PRIMARY" => array("url".db_index_suffix($charset)),
|
||||
"created" => array("created"),
|
||||
)
|
||||
);
|
||||
|
@ -1016,11 +1077,11 @@ function db_definition() {
|
|||
"url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
|
||||
"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" => "text", "not null" => "1"),
|
||||
"content" => array("type" => "text"),
|
||||
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("url", "guessing", "oembed"),
|
||||
"PRIMARY" => array("url".db_index_suffix($charset), "guessing", "oembed"),
|
||||
"created" => array("created"),
|
||||
)
|
||||
);
|
||||
|
@ -1030,11 +1091,11 @@ function db_definition() {
|
|||
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"v" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"v" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
"uid_cat_k" => array("uid","cat(30)","k(30)"),
|
||||
"uid_cat_k" => array("UNIQUE", "uid","cat(30)","k(30)"),
|
||||
)
|
||||
);
|
||||
$database["photo"] = array(
|
||||
|
@ -1047,7 +1108,7 @@ function db_definition() {
|
|||
"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"),
|
||||
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"desc" => array("type" => "text", "not null" => "1"),
|
||||
"desc" => array("type" => "text"),
|
||||
"album" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"filename" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"type" => array("type" => "varchar(128)", "not null" => "1", "default" => "image/jpeg"),
|
||||
|
@ -1057,14 +1118,16 @@ function db_definition() {
|
|||
"data" => array("type" => "mediumblob", "not null" => "1"),
|
||||
"scale" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
|
||||
"profile" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"allow_cid" => array("type" => "mediumtext"),
|
||||
"allow_gid" => array("type" => "mediumtext"),
|
||||
"deny_cid" => array("type" => "mediumtext"),
|
||||
"deny_gid" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
"uid" => array("uid"),
|
||||
"uid_contactid" => array("uid", "contact-id"),
|
||||
"uid_profile" => array("uid", "profile"),
|
||||
"uid_album_created" => array("uid", "album", "created"),
|
||||
"resource-id" => array("resource-id"),
|
||||
"guid" => array("guid"),
|
||||
)
|
||||
|
@ -1073,16 +1136,16 @@ function db_definition() {
|
|||
"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"),
|
||||
"q0" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q1" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q2" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q3" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q4" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q5" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q6" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q7" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q8" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q9" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"q0" => array("type" => "mediumtext"),
|
||||
"q1" => array("type" => "mediumtext"),
|
||||
"q2" => array("type" => "mediumtext"),
|
||||
"q3" => array("type" => "mediumtext"),
|
||||
"q4" => array("type" => "mediumtext"),
|
||||
"q5" => array("type" => "mediumtext"),
|
||||
"q6" => array("type" => "mediumtext"),
|
||||
"q7" => array("type" => "mediumtext"),
|
||||
"q8" => array("type" => "mediumtext"),
|
||||
"q9" => array("type" => "mediumtext"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("id"),
|
||||
|
@ -1101,6 +1164,17 @@ function db_definition() {
|
|||
"choice" => array("choice"),
|
||||
)
|
||||
);
|
||||
$database["process"] = array(
|
||||
"fields" => array(
|
||||
"pid" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1"),
|
||||
"command" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("pid"),
|
||||
"command" => array("command"),
|
||||
)
|
||||
);
|
||||
$database["profile"] = array(
|
||||
"fields" => array(
|
||||
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
|
@ -1119,27 +1193,28 @@ function db_definition() {
|
|||
"hometown" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
|
||||
"marital" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"with" => array("type" => "text", "not null" => "1"),
|
||||
"with" => array("type" => "text"),
|
||||
"howlong" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
"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" => ""),
|
||||
"pub_keywords" => array("type" => "text", "not null" => "1"),
|
||||
"prv_keywords" => array("type" => "text", "not null" => "1"),
|
||||
"likes" => array("type" => "text", "not null" => "1"),
|
||||
"dislikes" => array("type" => "text", "not null" => "1"),
|
||||
"about" => array("type" => "text", "not null" => "1"),
|
||||
"pub_keywords" => array("type" => "text"),
|
||||
"prv_keywords" => array("type" => "text"),
|
||||
"likes" => array("type" => "text"),
|
||||
"dislikes" => array("type" => "text"),
|
||||
"about" => array("type" => "text"),
|
||||
"summary" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"music" => array("type" => "text", "not null" => "1"),
|
||||
"book" => array("type" => "text", "not null" => "1"),
|
||||
"tv" => array("type" => "text", "not null" => "1"),
|
||||
"film" => array("type" => "text", "not null" => "1"),
|
||||
"interest" => array("type" => "text", "not null" => "1"),
|
||||
"romance" => array("type" => "text", "not null" => "1"),
|
||||
"work" => array("type" => "text", "not null" => "1"),
|
||||
"education" => array("type" => "text", "not null" => "1"),
|
||||
"contact" => array("type" => "text", "not null" => "1"),
|
||||
"music" => array("type" => "text"),
|
||||
"book" => array("type" => "text"),
|
||||
"tv" => array("type" => "text"),
|
||||
"film" => array("type" => "text"),
|
||||
"interest" => array("type" => "text"),
|
||||
"romance" => array("type" => "text"),
|
||||
"work" => array("type" => "text"),
|
||||
"education" => array("type" => "text"),
|
||||
"contact" => array("type" => "text"),
|
||||
"homepage" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"xmpp" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"thumb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"publish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
|
@ -1185,7 +1260,7 @@ function db_definition() {
|
|||
"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"),
|
||||
"content" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"content" => array("type" => "mediumtext"),
|
||||
"batch" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -1226,7 +1301,7 @@ function db_definition() {
|
|||
"fields" => array(
|
||||
"id" => array("type" => "bigint(20) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"sid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"data" => array("type" => "text", "not null" => "1"),
|
||||
"data" => array("type" => "text"),
|
||||
"expire" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -1239,8 +1314,8 @@ function db_definition() {
|
|||
"fields" => array(
|
||||
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
|
||||
"signed_text" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"signature" => array("type" => "text", "not null" => "1"),
|
||||
"signed_text" => array("type" => "mediumtext"),
|
||||
"signature" => array("type" => "text"),
|
||||
"signer" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
),
|
||||
"indexes" => array(
|
||||
|
@ -1287,6 +1362,7 @@ function db_definition() {
|
|||
"type_term" => array("type","term"),
|
||||
"uid_otype_type_term_global_created" => array("uid","otype","type","term","global","created"),
|
||||
"otype_type_term_tid" => array("otype","type","term","tid"),
|
||||
"uid_otype_type_url" => array("uid","otype","type","url"),
|
||||
"guid" => array("guid"),
|
||||
)
|
||||
);
|
||||
|
@ -1296,6 +1372,8 @@ function db_definition() {
|
|||
"uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
|
||||
"contact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
|
||||
"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"),
|
||||
|
@ -1335,7 +1413,7 @@ function db_definition() {
|
|||
$database["tokens"] = array(
|
||||
"fields" => array(
|
||||
"id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
|
||||
"secret" => array("type" => "text", "not null" => "1"),
|
||||
"secret" => array("type" => "text"),
|
||||
"client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => ""),
|
||||
"expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
"scope" => array("type" => "varchar(200)", "not null" => "1", "default" => ""),
|
||||
|
@ -1361,10 +1439,10 @@ function db_definition() {
|
|||
"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" => ""),
|
||||
"pubkey" => array("type" => "text", "not null" => "1"),
|
||||
"prvkey" => array("type" => "text", "not null" => "1"),
|
||||
"spubkey" => array("type" => "text", "not null" => "1"),
|
||||
"sprvkey" => array("type" => "text", "not null" => "1"),
|
||||
"pubkey" => array("type" => "text"),
|
||||
"prvkey" => array("type" => "text"),
|
||||
"spubkey" => array("type" => "text"),
|
||||
"sprvkey" => array("type" => "text"),
|
||||
"verified" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
|
||||
"blocked" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
|
||||
"blockwall" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
|
||||
|
@ -1374,6 +1452,7 @@ function db_definition() {
|
|||
"cntunkmail" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
|
||||
"notify-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "65535"),
|
||||
"page-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
|
||||
"account-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
|
||||
"prvnets" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
|
||||
"pwdreset" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
|
||||
"maxreq" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
|
||||
|
@ -1384,11 +1463,11 @@ function db_definition() {
|
|||
"expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
|
||||
"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", "not null" => "1"),
|
||||
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
|
||||
"openidserver" => array("type" => "text", "not null" => "1"),
|
||||
"allow_cid" => array("type" => "mediumtext"),
|
||||
"allow_gid" => array("type" => "mediumtext"),
|
||||
"deny_cid" => array("type" => "mediumtext"),
|
||||
"deny_gid" => array("type" => "mediumtext"),
|
||||
"openidserver" => array("type" => "text"),
|
||||
),
|
||||
"indexes" => array(
|
||||
"PRIMARY" => array("uid"),
|
||||
|
@ -1408,7 +1487,7 @@ function db_definition() {
|
|||
$database["workerqueue"] = array(
|
||||
"fields" => array(
|
||||
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
|
||||
"parameter" => array("type" => "text", "not null" => "1"),
|
||||
"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"),
|
||||
"pid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
|
||||
|
@ -1443,11 +1522,33 @@ function dbstructure_run(&$argv, &$argc) {
|
|||
|
||||
if ($argc==2) {
|
||||
switch ($argv[1]) {
|
||||
case "dryrun":
|
||||
update_structure(true, false);
|
||||
return;
|
||||
case "update":
|
||||
update_structure(true, true);
|
||||
|
||||
$build = get_config('system','build');
|
||||
if (!x($build)) {
|
||||
set_config('system','build',DB_UPDATE_VERSION);
|
||||
$build = DB_UPDATE_VERSION;
|
||||
}
|
||||
|
||||
$stored = intval($build);
|
||||
$current = intval(DB_UPDATE_VERSION);
|
||||
|
||||
// run any left update_nnnn functions in update.php
|
||||
for($x = $stored; $x < $current; $x ++) {
|
||||
$r = run_update_function($x);
|
||||
if (!$r) break;
|
||||
}
|
||||
|
||||
set_config('system','build',DB_UPDATE_VERSION);
|
||||
return;
|
||||
case "dumpsql":
|
||||
print_structure(db_definition());
|
||||
// For the dump that is used to create the database.sql we always assume utfmb4
|
||||
$charset = "utf8mb4";
|
||||
print_structure(db_definition($charset), $charset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1456,7 +1557,8 @@ function dbstructure_run(&$argv, &$argc) {
|
|||
// print help
|
||||
echo $argv[0]." <command>\n";
|
||||
echo "\n";
|
||||
echo "commands:\n";
|
||||
echo "Commands:\n";
|
||||
echo "dryrun show database update schema queries without running them\n";
|
||||
echo "update update database schema\n";
|
||||
echo "dumpsql dump database schema\n";
|
||||
return;
|
||||
|
|
|
@ -178,7 +178,7 @@ function delivery_run(&$argv, &$argc){
|
|||
|
||||
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
|
||||
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
|
||||
`user`.`page-flags`, `user`.`prvnets`
|
||||
`user`.`page-flags`, `user`.`account-type`, `user`.`prvnets`
|
||||
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
|
||||
intval($uid)
|
||||
|
|
104
include/dfrn.php
104
include/dfrn.php
|
@ -98,9 +98,9 @@ class dfrn {
|
|||
|
||||
$sql_extra = " AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' ";
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`
|
||||
$r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
|
||||
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `contact`.`self` = 1 AND `user`.`nickname` = '%s' LIMIT 1",
|
||||
WHERE `contact`.`self` AND `user`.`nickname` = '%s' LIMIT 1",
|
||||
dbesc($owner_nick)
|
||||
);
|
||||
|
||||
|
@ -112,7 +112,6 @@ class dfrn {
|
|||
$owner_nick = $owner['nickname'];
|
||||
|
||||
$sql_post_table = "";
|
||||
$visibility = "";
|
||||
|
||||
if(! $public_feed) {
|
||||
|
||||
|
@ -171,9 +170,6 @@ class dfrn {
|
|||
else
|
||||
$sort = 'ASC';
|
||||
|
||||
$date_field = "`changed`";
|
||||
$sql_order = "`item`.`parent` ".$sort.", `item`.`created` ASC";
|
||||
|
||||
if(! strlen($last_update))
|
||||
$last_update = 'now -30 days';
|
||||
|
||||
|
@ -190,22 +186,19 @@ class dfrn {
|
|||
|
||||
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
|
||||
|
||||
// AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
|
||||
// dbesc($check_date),
|
||||
|
||||
$r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`,
|
||||
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,
|
||||
`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
|
||||
`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
|
||||
`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`
|
||||
FROM `item` $sql_post_table
|
||||
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
FROM `item` USE INDEX (`uid_wall_changed`, `uid_type_changed`) $sql_post_table
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
AND NOT `contact`.`blocked`
|
||||
LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`parent` != 0
|
||||
AND ((`item`.`wall` = 1) $visibility) AND `item`.$date_field > '%s'
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`moderated` AND `item`.`parent` != 0
|
||||
AND `item`.`wall` AND `item`.`changed` > '%s'
|
||||
$sql_extra
|
||||
ORDER BY $sql_order LIMIT 0, 300",
|
||||
ORDER BY `item`.`parent` ".$sort.", `item`.`created` ASC LIMIT 0, 300",
|
||||
intval($owner_id),
|
||||
dbesc($check_date),
|
||||
dbesc($sort)
|
||||
|
@ -369,6 +362,7 @@ class dfrn {
|
|||
xml::add_element($doc, $relocate, "dfrn:url", $owner['url']);
|
||||
xml::add_element($doc, $relocate, "dfrn:name", $owner['name']);
|
||||
xml::add_element($doc, $relocate, "dfrn:addr", $owner['addr']);
|
||||
xml::add_element($doc, $relocate, "dfrn:avatar", $owner['avatar']);
|
||||
xml::add_element($doc, $relocate, "dfrn:photo", $photos[4]);
|
||||
xml::add_element($doc, $relocate, "dfrn:thumb", $photos[5]);
|
||||
xml::add_element($doc, $relocate, "dfrn:micro", $photos[6]);
|
||||
|
@ -439,9 +433,13 @@ class dfrn {
|
|||
xml::add_element($doc, $root, "link", "", $attributes);
|
||||
}
|
||||
|
||||
// For backward compatibility we keep this element
|
||||
if ($owner['page-flags'] == PAGE_COMMUNITY)
|
||||
xml::add_element($doc, $root, "dfrn:community", 1);
|
||||
|
||||
// The former element is replaced by this one
|
||||
xml::add_element($doc, $root, "dfrn:account_type", $owner["account-type"]);
|
||||
|
||||
/// @todo We need a way to transmit the different page flags like "PAGE_PRVGROUP"
|
||||
|
||||
xml::add_element($doc, $root, "updated", datetime_convert("UTC", "UTC", "now", ATOM_TIME));
|
||||
|
@ -511,14 +509,16 @@ class dfrn {
|
|||
xml::add_element($doc, $author, "dfrn:birthday", $birthday);
|
||||
|
||||
// Only show contact details when we are allowed to
|
||||
$r = q("SELECT `profile`.`about`, `profile`.`name`, `profile`.`homepage`, `user`.`nickname`, `user`.`timezone`,
|
||||
`profile`.`locality`, `profile`.`region`, `profile`.`country-name`, `profile`.`pub_keywords`, `profile`.`dob`
|
||||
$r = q("SELECT `profile`.`about`, `profile`.`name`, `profile`.`homepage`, `user`.`nickname`,
|
||||
`user`.`timezone`, `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
|
||||
`profile`.`pub_keywords`, `profile`.`xmpp`, `profile`.`dob`
|
||||
FROM `profile`
|
||||
INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
|
||||
WHERE `profile`.`is-default` AND NOT `user`.`hidewall` AND `user`.`uid` = %d",
|
||||
intval($owner['uid']));
|
||||
if ($r) {
|
||||
$profile = $r[0];
|
||||
|
||||
xml::add_element($doc, $author, "poco:displayName", $profile["name"]);
|
||||
xml::add_element($doc, $author, "poco:updated", $namdate);
|
||||
|
||||
|
@ -549,12 +549,10 @@ class dfrn {
|
|||
|
||||
}
|
||||
|
||||
/// @todo When we are having the XMPP address in the profile we should propagate it here
|
||||
$xmpp = "";
|
||||
if (trim($xmpp) != "") {
|
||||
if (trim($profile["xmpp"]) != "") {
|
||||
$ims = $doc->createElement("poco:ims");
|
||||
xml::add_element($doc, $ims, "poco:type", "xmpp");
|
||||
xml::add_element($doc, $ims, "poco:value", $xmpp);
|
||||
xml::add_element($doc, $ims, "poco:value", $profile["xmpp"]);
|
||||
xml::add_element($doc, $ims, "poco:primary", "true");
|
||||
$author->appendChild($ims);
|
||||
}
|
||||
|
@ -1142,7 +1140,7 @@ class dfrn {
|
|||
$author["link"] = $xpath->evaluate($element."/atom:uri/text()", $context)->item(0)->nodeValue;
|
||||
|
||||
$r = q("SELECT `id`, `uid`, `url`, `network`, `avatar-date`, `name-date`, `uri-date`, `addr`,
|
||||
`name`, `nick`, `about`, `location`, `keywords`, `bdyear`, `bd`, `hidden`
|
||||
`name`, `nick`, `about`, `location`, `keywords`, `xmpp`, `bdyear`, `bd`, `hidden`, `contact-type`
|
||||
FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `network` != '%s'",
|
||||
intval($importer["uid"]), dbesc(normalise_link($author["link"])), dbesc(NETWORK_STATUSNET));
|
||||
if ($r) {
|
||||
|
@ -1218,9 +1216,13 @@ class dfrn {
|
|||
if ($value != "")
|
||||
$poco["location"] = $value;
|
||||
|
||||
/// @todo Only search for elements with "poco:type" = "xmpp"
|
||||
$value = $xpath->evaluate($element."/poco:ims/poco:value/text()", $context)->item(0)->nodeValue;
|
||||
if ($value != "")
|
||||
$poco["xmpp"] = $value;
|
||||
|
||||
/// @todo Add support for the following fields that we don't support by now in the contact table:
|
||||
/// - poco:utcOffset
|
||||
/// - poco:ims
|
||||
/// - poco:urls
|
||||
/// - poco:locality
|
||||
/// - poco:region
|
||||
|
@ -1307,12 +1309,13 @@ class dfrn {
|
|||
|
||||
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s',
|
||||
`addr` = '%s', `keywords` = '%s', `bdyear` = '%s', `bd` = '%s', `hidden` = %d,
|
||||
`name-date` = '%s', `uri-date` = '%s'
|
||||
`xmpp` = '%s', `name-date` = '%s', `uri-date` = '%s'
|
||||
WHERE `id` = %d AND `network` = '%s'",
|
||||
dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["about"]), dbesc($contact["location"]),
|
||||
dbesc($contact["addr"]), dbesc($contact["keywords"]), dbesc($contact["bdyear"]),
|
||||
dbesc($contact["bd"]), intval($contact["hidden"]), dbesc($contact["name-date"]),
|
||||
dbesc($contact["uri-date"]), intval($contact["id"]), dbesc($contact["network"]));
|
||||
dbesc($contact["bd"]), intval($contact["hidden"]), dbesc($contact["xmpp"]),
|
||||
dbesc($contact["name-date"]), dbesc($contact["uri-date"]),
|
||||
intval($contact["id"]), dbesc($contact["network"]));
|
||||
}
|
||||
|
||||
update_contact_avatar($author["avatar"], $importer["uid"], $contact["id"],
|
||||
|
@ -1326,6 +1329,7 @@ class dfrn {
|
|||
$poco["generation"] = 2;
|
||||
$poco["photo"] = $author["avatar"];
|
||||
$poco["hide"] = $hide;
|
||||
$poco["contact-type"] = $contact["contact-type"];
|
||||
update_gcontact($poco);
|
||||
}
|
||||
|
||||
|
@ -1548,6 +1552,7 @@ class dfrn {
|
|||
$relocate["url"] = $xpath->query("dfrn:url/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["addr"] = $xpath->query("dfrn:addr/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["name"] = $xpath->query("dfrn:name/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["avatar"] = $xpath->query("dfrn:avatar/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["photo"] = $xpath->query("dfrn:photo/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["thumb"] = $xpath->query("dfrn:thumb/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["micro"] = $xpath->query("dfrn:micro/text()", $relocation)->item(0)->nodeValue;
|
||||
|
@ -1557,6 +1562,9 @@ class dfrn {
|
|||
$relocate["poll"] = $xpath->query("dfrn:poll/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["sitepubkey"] = $xpath->query("dfrn:sitepubkey/text()", $relocation)->item(0)->nodeValue;
|
||||
|
||||
if (($relocate["avatar"] == "") AND ($relocate["photo"] != ""))
|
||||
$relocate["avatar"] = $relocate["photo"];
|
||||
|
||||
if ($relocate["addr"] == "")
|
||||
$relocate["addr"] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$3@$2", $relocate["url"]);
|
||||
|
||||
|
@ -1583,7 +1591,7 @@ class dfrn {
|
|||
`server_url` = '%s'
|
||||
WHERE `nurl` = '%s';",
|
||||
dbesc($relocate["name"]),
|
||||
dbesc($relocate["photo"]),
|
||||
dbesc($relocate["avatar"]),
|
||||
dbesc($relocate["url"]),
|
||||
dbesc(normalise_link($relocate["url"])),
|
||||
dbesc($relocate["addr"]),
|
||||
|
@ -1595,9 +1603,7 @@ class dfrn {
|
|||
// Update the contact table. We try to find every entry.
|
||||
$x = q("UPDATE `contact` SET
|
||||
`name` = '%s',
|
||||
`photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`avatar` = '%s',
|
||||
`url` = '%s',
|
||||
`nurl` = '%s',
|
||||
`addr` = '%s',
|
||||
|
@ -1608,9 +1614,7 @@ class dfrn {
|
|||
`site-pubkey` = '%s'
|
||||
WHERE (`id` = %d AND `uid` = %d) OR (`nurl` = '%s');",
|
||||
dbesc($relocate["name"]),
|
||||
dbesc($relocate["photo"]),
|
||||
dbesc($relocate["thumb"]),
|
||||
dbesc($relocate["micro"]),
|
||||
dbesc($relocate["avatar"]),
|
||||
dbesc($relocate["url"]),
|
||||
dbesc(normalise_link($relocate["url"])),
|
||||
dbesc($relocate["addr"]),
|
||||
|
@ -1623,6 +1627,8 @@ class dfrn {
|
|||
intval($importer["importer_uid"]),
|
||||
dbesc(normalise_link($old["url"])));
|
||||
|
||||
update_contact_avatar($relocate["avatar"], $importer["importer_uid"], $importer["id"], true);
|
||||
|
||||
if ($x === false)
|
||||
return false;
|
||||
|
||||
|
@ -1631,10 +1637,15 @@ class dfrn {
|
|||
$fields = array(
|
||||
'owner-link' => array($old["url"], $relocate["url"]),
|
||||
'author-link' => array($old["url"], $relocate["url"]),
|
||||
'owner-avatar' => array($old["photo"], $relocate["photo"]),
|
||||
'author-avatar' => array($old["photo"], $relocate["photo"]),
|
||||
//'owner-avatar' => array($old["photo"], $relocate["photo"]),
|
||||
//'author-avatar' => array($old["photo"], $relocate["photo"]),
|
||||
);
|
||||
foreach ($fields as $n=>$f) {
|
||||
$r = q("SELECT `id` FROM `item` WHERE `%s` = '%s' AND `uid` = %d LIMIT 1",
|
||||
$n, dbesc($f[0]),
|
||||
intval($importer["importer_uid"]));
|
||||
|
||||
if ($r) {
|
||||
$x = q("UPDATE `item` SET `%s` = '%s' WHERE `%s` = '%s' AND `uid` = %d",
|
||||
$n, dbesc($f[1]),
|
||||
$n, dbesc($f[0]),
|
||||
|
@ -1642,6 +1653,7 @@ class dfrn {
|
|||
if ($x === false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @TODO
|
||||
/// merge with current record, current contents have priority
|
||||
|
@ -1683,7 +1695,7 @@ class dfrn {
|
|||
$changed = true;
|
||||
|
||||
if ($entrytype == DFRN_REPLY_RC)
|
||||
proc_run("php", "include/notifier.php","comment-import", $current["id"]);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php","comment-import", $current["id"]);
|
||||
}
|
||||
|
||||
// update last-child if it changes
|
||||
|
@ -2243,7 +2255,7 @@ class dfrn {
|
|||
|
||||
if($posted_id AND $parent AND ($entrytype == DFRN_REPLY_RC)) {
|
||||
logger("Notifying followers about comment ".$posted_id, LOGGER_DEBUG);
|
||||
proc_run("php", "include/notifier.php", "comment-import", $posted_id);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $posted_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2414,7 +2426,7 @@ class dfrn {
|
|||
|
||||
if($entrytype == DFRN_REPLY_RC) {
|
||||
logger("Notifying followers about deletion of post ".$item["id"], LOGGER_DEBUG);
|
||||
proc_run("php", "include/notifier.php","drop", $item["id"]);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php","drop", $item["id"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2474,7 +2486,19 @@ class dfrn {
|
|||
|
||||
logger("Import DFRN message for user ".$importer["uid"]." from contact ".$importer["id"], LOGGER_DEBUG);
|
||||
|
||||
// is it a public forum? Private forums aren't supported by now with this method
|
||||
// The account type is new since 3.5.1
|
||||
if ($xpath->query("/atom:feed/dfrn:account_type")->length > 0) {
|
||||
$accounttype = intval($xpath->evaluate("/atom:feed/dfrn:account_type/text()", $context)->item(0)->nodeValue);
|
||||
|
||||
if ($accounttype != $importer["contact-type"])
|
||||
q("UPDATE `contact` SET `contact-type` = %d WHERE `id` = %d",
|
||||
intval($accounttype),
|
||||
intval($importer["id"])
|
||||
);
|
||||
}
|
||||
|
||||
// is it a public forum? Private forums aren't supported with this method
|
||||
// This is deprecated since 3.5.1
|
||||
$forum = intval($xpath->evaluate("/atom:feed/dfrn:community/text()", $context)->item(0)->nodeValue);
|
||||
|
||||
if ($forum != $importer["forum"])
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
/**
|
||||
* @file include/diaspora.php
|
||||
* @brief The implementation of the diaspora protocol
|
||||
*
|
||||
* The new protocol is described here: http://diaspora.github.io/diaspora_federation/index.html
|
||||
* Currently this implementation here interprets the old and the new protocol and sends the old one.
|
||||
* This will change in the future.
|
||||
*/
|
||||
|
||||
require_once("include/items.php");
|
||||
|
@ -100,6 +104,59 @@ class diaspora {
|
|||
return($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief verify the envelope and return the verified data
|
||||
*
|
||||
* @param string $envelope The magic envelope
|
||||
*
|
||||
* @return string verified data
|
||||
*/
|
||||
private function verify_magic_envelope($envelope) {
|
||||
|
||||
$basedom = parse_xml_string($envelope, false);
|
||||
|
||||
if (!is_object($basedom)) {
|
||||
logger("Envelope is no XML file");
|
||||
return false;
|
||||
}
|
||||
|
||||
$children = $basedom->children('http://salmon-protocol.org/ns/magic-env');
|
||||
|
||||
if (sizeof($children) == 0) {
|
||||
logger("XML has no children");
|
||||
return false;
|
||||
}
|
||||
|
||||
$handle = "";
|
||||
|
||||
$data = base64url_decode($children->data);
|
||||
$type = $children->data->attributes()->type[0];
|
||||
|
||||
$encoding = $children->encoding;
|
||||
|
||||
$alg = $children->alg;
|
||||
|
||||
$sig = base64url_decode($children->sig);
|
||||
$key_id = $children->sig->attributes()->key_id[0];
|
||||
if ($key_id != "")
|
||||
$handle = base64url_decode($key_id);
|
||||
|
||||
$b64url_data = base64url_encode($data);
|
||||
$msg = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data);
|
||||
|
||||
$signable_data = $msg.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg);
|
||||
|
||||
$key = self::key($handle);
|
||||
|
||||
$verify = rsa_verify($signable_data, $sig, $key);
|
||||
if (!$verify) {
|
||||
logger('Message did not verify. Discarding.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: Decodes incoming Diaspora message
|
||||
*
|
||||
|
@ -233,7 +290,6 @@ class diaspora {
|
|||
return array('message' => (string)$inner_decrypted,
|
||||
'author' => unxmlify($author_link),
|
||||
'key' => (string)$key);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -360,8 +416,10 @@ class diaspora {
|
|||
|
||||
$data = parse_xml_string($msg["message"], false);
|
||||
|
||||
if (!is_object($data))
|
||||
if (!is_object($data)) {
|
||||
logger("No valid XML ".$msg["message"], LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
$first_child = $data->getName();
|
||||
|
||||
|
@ -378,6 +436,8 @@ class diaspora {
|
|||
$type = $element->getName();
|
||||
$orig_type = $type;
|
||||
|
||||
logger("Got message type ".$type.": ".$msg["message"], LOGGER_DATA);
|
||||
|
||||
// All retractions are handled identically from now on.
|
||||
// In the new version there will only be "retraction".
|
||||
if (in_array($type, array("signed_retraction", "relayable_retraction")))
|
||||
|
@ -422,11 +482,11 @@ class diaspora {
|
|||
}
|
||||
}
|
||||
|
||||
if ($fieldname == "author_signature")
|
||||
if (($fieldname == "author_signature") AND ($entry != ""))
|
||||
$author_signature = base64_decode($entry);
|
||||
elseif ($fieldname == "parent_author_signature")
|
||||
elseif (($fieldname == "parent_author_signature") AND ($entry != ""))
|
||||
$parent_author_signature = base64_decode($entry);
|
||||
elseif ($fieldname != "target_author_signature") {
|
||||
elseif (!in_array($fieldname, array("author_signature", "parent_author_signature", "target_author_signature"))) {
|
||||
if ($signed_data != "") {
|
||||
$signed_data .= ";";
|
||||
$signed_data_parent .= ";";
|
||||
|
@ -451,19 +511,27 @@ class diaspora {
|
|||
return true;
|
||||
|
||||
// No author_signature? This is a must, so we quit.
|
||||
if (!isset($author_signature))
|
||||
if (!isset($author_signature)) {
|
||||
logger("No author signature for type ".$type." - Message: ".$msg["message"], LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($parent_author_signature)) {
|
||||
$key = self::key($msg["author"]);
|
||||
|
||||
if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256"))
|
||||
if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256")) {
|
||||
logger("No valid parent author signature for author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$key = self::key($fields->author);
|
||||
|
||||
return rsa_verify($signed_data, $author_signature, $key, "sha256");
|
||||
if (!rsa_verify($signed_data, $author_signature, $key, "sha256")) {
|
||||
logger("No valid author signature for author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -506,6 +574,9 @@ class diaspora {
|
|||
$d = strtotime($person["updated"]." +00:00");
|
||||
if ($d < strtotime("now - 14 days"))
|
||||
$update = true;
|
||||
|
||||
if ($person["guid"] == "")
|
||||
$update = true;
|
||||
}
|
||||
|
||||
if (!$person OR $update) {
|
||||
|
@ -539,6 +610,7 @@ class diaspora {
|
|||
`request` = '%s',
|
||||
`nick` = '%s',
|
||||
`addr` = '%s',
|
||||
`guid` = '%s',
|
||||
`batch` = '%s',
|
||||
`notify` = '%s',
|
||||
`poll` = '%s',
|
||||
|
@ -551,7 +623,8 @@ class diaspora {
|
|||
dbesc($arr["photo"]),
|
||||
dbesc($arr["request"]),
|
||||
dbesc($arr["nick"]),
|
||||
dbesc($arr["addr"]),
|
||||
dbesc(strtolower($arr["addr"])),
|
||||
dbesc($arr["guid"]),
|
||||
dbesc($arr["batch"]),
|
||||
dbesc($arr["notify"]),
|
||||
dbesc($arr["poll"]),
|
||||
|
@ -563,15 +636,16 @@ class diaspora {
|
|||
dbesc($arr["network"])
|
||||
);
|
||||
} else {
|
||||
$r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`,
|
||||
$r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`, `guid`,
|
||||
`batch`, `notify`,`poll`,`confirm`,`network`,`alias`,`pubkey`,`updated`)
|
||||
VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
|
||||
VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
|
||||
dbesc($arr["url"]),
|
||||
dbesc($arr["name"]),
|
||||
dbesc($arr["photo"]),
|
||||
dbesc($arr["request"]),
|
||||
dbesc($arr["nick"]),
|
||||
dbesc($arr["addr"]),
|
||||
dbesc($arr["guid"]),
|
||||
dbesc($arr["batch"]),
|
||||
dbesc($arr["notify"]),
|
||||
dbesc($arr["poll"]),
|
||||
|
@ -603,7 +677,7 @@ class diaspora {
|
|||
$r = q("SELECT `addr` FROM `gcontact` WHERE `id` = %d AND `addr` != ''",
|
||||
intval($gcontact_id));
|
||||
if ($r)
|
||||
return $r[0]["addr"];
|
||||
return strtolower($r[0]["addr"]);
|
||||
}
|
||||
|
||||
$r = q("SELECT `network`, `addr`, `self`, `url`, `nick` FROM `contact` WHERE `id` = %d",
|
||||
|
@ -623,7 +697,7 @@ class diaspora {
|
|||
}
|
||||
}
|
||||
|
||||
return $handle;
|
||||
return strtolower($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -806,11 +880,30 @@ class diaspora {
|
|||
if ($level > 5)
|
||||
return false;
|
||||
|
||||
// This will work for Diaspora and newer Friendica servers
|
||||
// This will work for new Diaspora servers and Friendica servers from 3.5
|
||||
$source_url = $server."/fetch/post/".$guid;
|
||||
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
|
||||
|
||||
$envelope = fetch_url($source_url);
|
||||
if($envelope) {
|
||||
logger("Envelope was fetched.", LOGGER_DEBUG);
|
||||
$x = self::verify_magic_envelope($envelope);
|
||||
if (!$x)
|
||||
logger("Envelope could not be verified.", LOGGER_DEBUG);
|
||||
else
|
||||
logger("Envelope was verified.", LOGGER_DEBUG);
|
||||
} else
|
||||
$x = false;
|
||||
|
||||
// This will work for older Diaspora and Friendica servers
|
||||
if (!$x) {
|
||||
$source_url = $server."/p/".$guid.".xml";
|
||||
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
|
||||
|
||||
$x = fetch_url($source_url);
|
||||
if(!$x)
|
||||
return false;
|
||||
}
|
||||
|
||||
$source_xml = parse_xml_string($x, false);
|
||||
|
||||
|
@ -819,9 +912,11 @@ class diaspora {
|
|||
|
||||
if ($source_xml->post->reshare) {
|
||||
// Reshare of a reshare - old Diaspora version
|
||||
logger("Message is a reshare", LOGGER_DEBUG);
|
||||
return self::message($source_xml->post->reshare->root_guid, $server, ++$level);
|
||||
} elseif ($source_xml->getName() == "reshare") {
|
||||
// Reshare of a reshare - new Diaspora version
|
||||
logger("Message is a new reshare", LOGGER_DEBUG);
|
||||
return self::message($source_xml->root_guid, $server, ++$level);
|
||||
}
|
||||
|
||||
|
@ -834,8 +929,10 @@ class diaspora {
|
|||
$author = (string)$source_xml->author;
|
||||
|
||||
// If this isn't a "status_message" then quit
|
||||
if (!$author)
|
||||
if (!$author) {
|
||||
logger("Message doesn't seem to be a status message", LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
$msg = array("message" => $x, "author" => $author);
|
||||
|
||||
|
@ -981,6 +1078,23 @@ class diaspora {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch the uri from our database if we already have this item (maybe from ourselves)
|
||||
*
|
||||
* @param string $author Author handle
|
||||
* @param string $guid Message guid
|
||||
*
|
||||
* @return string The constructed uri or the one from our database
|
||||
*/
|
||||
private function get_uri_from_guid($author, $guid) {
|
||||
|
||||
$r = q("SELECT `uri` FROM `item` WHERE `guid` = '%s' LIMIT 1", dbesc($guid));
|
||||
if ($r)
|
||||
return $r[0]["uri"];
|
||||
else
|
||||
return $author.":".$guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes an incoming comment
|
||||
*
|
||||
|
@ -997,6 +1111,11 @@ class diaspora {
|
|||
$text = unxmlify($data->text);
|
||||
$author = notags(unxmlify($data->author));
|
||||
|
||||
if (isset($data->created_at))
|
||||
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
|
||||
else
|
||||
$created_at = datetime_convert();
|
||||
|
||||
$contact = self::allowed_contact_by_handle($importer, $sender, true);
|
||||
if (!$contact)
|
||||
return false;
|
||||
|
@ -1033,7 +1152,7 @@ class diaspora {
|
|||
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
|
||||
|
||||
$datarray["guid"] = $guid;
|
||||
$datarray["uri"] = $author.":".$guid;
|
||||
$datarray["uri"] = self::get_uri_from_guid($author, $guid);
|
||||
|
||||
$datarray["type"] = "remote-comment";
|
||||
$datarray["verb"] = ACTIVITY_POST;
|
||||
|
@ -1043,6 +1162,8 @@ class diaspora {
|
|||
$datarray["object-type"] = ACTIVITY_OBJ_COMMENT;
|
||||
$datarray["object"] = $xml;
|
||||
|
||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
||||
|
||||
$datarray["body"] = diaspora2bb($text);
|
||||
|
||||
self::fetch_guid($datarray);
|
||||
|
@ -1063,7 +1184,7 @@ class diaspora {
|
|||
);
|
||||
|
||||
// notify others
|
||||
proc_run("php", "include/notifier.php", "comment-import", $message_id);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id);
|
||||
}
|
||||
|
||||
return $message_id;
|
||||
|
@ -1239,7 +1360,7 @@ class diaspora {
|
|||
intval($importer["uid"]),
|
||||
dbesc($guid),
|
||||
dbesc($author),
|
||||
dbesc(datetime_convert("UTC", "UTC", $created_at)),
|
||||
dbesc($created_at),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($subject),
|
||||
dbesc($participants)
|
||||
|
@ -1370,7 +1491,7 @@ class diaspora {
|
|||
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
|
||||
|
||||
$datarray["guid"] = $guid;
|
||||
$datarray["uri"] = $author.":".$guid;
|
||||
$datarray["uri"] = self::get_uri_from_guid($author, $guid);
|
||||
|
||||
$datarray["type"] = "activity";
|
||||
$datarray["verb"] = $verb;
|
||||
|
@ -1398,7 +1519,7 @@ class diaspora {
|
|||
);
|
||||
|
||||
// notify others
|
||||
proc_run("php", "include/notifier.php", "comment-import", $message_id);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id);
|
||||
}
|
||||
|
||||
return $message_id;
|
||||
|
@ -1531,7 +1652,7 @@ class diaspora {
|
|||
* @return bool Success
|
||||
*/
|
||||
private function receive_profile($importer, $data) {
|
||||
$author = notags(unxmlify($data->author));
|
||||
$author = strtolower(notags(unxmlify($data->author)));
|
||||
|
||||
$contact = self::contact_by_handle($importer["uid"], $author);
|
||||
if (!$contact)
|
||||
|
@ -1678,7 +1799,7 @@ class diaspora {
|
|||
|
||||
$i = item_store($arr);
|
||||
if($i)
|
||||
proc_run("php", "include/notifier.php", "activity", $i);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1736,11 +1857,27 @@ class diaspora {
|
|||
// That makes us friends.
|
||||
if ($contact) {
|
||||
if ($following AND $sharing) {
|
||||
logger("Author ".$author." (Contact ".$contact["id"].") wants to have a bidirectional conection.", LOGGER_DEBUG);
|
||||
self::receive_request_make_friend($importer, $contact);
|
||||
|
||||
// refetch the contact array
|
||||
$contact = self::contact_by_handle($importer["uid"],$author);
|
||||
|
||||
// If we are now friends, we are sending a share message.
|
||||
// Normally we needn't to do so, but the first message could have been vanished.
|
||||
if (in_array($contact["rel"], array(CONTACT_IS_FRIEND, CONTACT_IS_FOLLOWER))) {
|
||||
$u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"]));
|
||||
if($u) {
|
||||
logger("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"], LOGGER_DEBUG);
|
||||
$ret = self::send_share($u[0], $contact);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else /// @todo Handle all possible variations of adding and retracting of permissions
|
||||
} else { /// @todo Handle all possible variations of adding and retracting of permissions
|
||||
logger("Author ".$author." (Contact ".$contact["id"].") wants to change the relationship: Following: ".$following." - sharing: ".$sharing. "(By now unsupported)", LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$following AND $sharing AND in_array($importer["page-flags"], array(PAGE_SOAPBOX, PAGE_NORMAL))) {
|
||||
logger("Author ".$author." wants to share with us - but doesn't want to listen. Request is ignored.", LOGGER_DEBUG);
|
||||
|
@ -1748,6 +1885,12 @@ class diaspora {
|
|||
} elseif (!$following AND !$sharing) {
|
||||
logger("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored.", LOGGER_DEBUG);
|
||||
return false;
|
||||
} elseif (!$following AND $sharing) {
|
||||
logger("Author ".$author." wants to share with us.", LOGGER_DEBUG);
|
||||
} elseif ($following AND $sharing) {
|
||||
logger("Author ".$author." wants to have a bidirectional conection.", LOGGER_DEBUG);
|
||||
} elseif ($following AND !$sharing) {
|
||||
logger("Author ".$author." wants to listen to us.", LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
$ret = self::person_by_handle($author);
|
||||
|
@ -1787,13 +1930,19 @@ class diaspora {
|
|||
return;
|
||||
}
|
||||
|
||||
logger("Author ".$author." was added as contact number ".$contact_record["id"].".", LOGGER_DEBUG);
|
||||
|
||||
$def_gid = get_default_group($importer['uid'], $ret["network"]);
|
||||
|
||||
if(intval($def_gid))
|
||||
group_add_member($importer["uid"], "", $contact_record["id"], $def_gid);
|
||||
|
||||
update_contact_avatar($ret["photo"], $importer['uid'], $contact_record["id"], true);
|
||||
|
||||
if($importer["page-flags"] == PAGE_NORMAL) {
|
||||
|
||||
logger("Sending intra message for author ".$author.".", LOGGER_DEBUG);
|
||||
|
||||
$hash = random_string().(string)time(); // Generate a confirm_key
|
||||
|
||||
$ret = q("INSERT INTO `intro` (`uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
|
||||
|
@ -1810,6 +1959,8 @@ class diaspora {
|
|||
|
||||
// automatic friend approval
|
||||
|
||||
logger("Does an automatic friend approval for author ".$author.".", LOGGER_DEBUG);
|
||||
|
||||
update_contact_avatar($contact_record["photo"],$importer["uid"],$contact_record["id"]);
|
||||
|
||||
// technically they are sharing with us (CONTACT_IS_SHARING),
|
||||
|
@ -1838,8 +1989,13 @@ class diaspora {
|
|||
);
|
||||
|
||||
$u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"]));
|
||||
if($u)
|
||||
if($u) {
|
||||
logger("Sending share message (Relation: ".$new_relation.") to author ".$author." - Contact: ".$contact_record["id"]." - User: ".$importer["uid"], LOGGER_DEBUG);
|
||||
$ret = self::send_share($u[0], $contact_record);
|
||||
|
||||
// Send the profile data, maybe it weren't transmitted before
|
||||
self::send_profile($importer["uid"], array($contact_record));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1883,27 +2039,15 @@ class diaspora {
|
|||
|
||||
if (!$r) {
|
||||
$server = "https://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("1st try: reshared message ".$guid." will be fetched from original server: ".$server);
|
||||
logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server);
|
||||
$item_id = self::store_by_guid($guid, $server);
|
||||
|
||||
if (!$item_id) {
|
||||
$server = "http://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("2nd try: reshared message ".$guid." will be fetched from original server: ".$server);
|
||||
logger("2nd try: reshared message ".$guid." will be fetched without SLL from the server ".$server);
|
||||
$item_id = self::store_by_guid($guid, $server);
|
||||
}
|
||||
|
||||
// Deactivated by now since there is a risk that someone could manipulate postings through this method
|
||||
/* if (!$item_id) {
|
||||
$server = "https://".substr($author, strpos($author, "@") + 1);
|
||||
logger("3rd try: reshared message ".$guid." will be fetched from sharer's server: ".$server);
|
||||
$item_id = self::store_by_guid($guid, $server);
|
||||
}
|
||||
if (!$item_id) {
|
||||
$server = "http://".substr($author, strpos($author, "@") + 1);
|
||||
logger("4th try: reshared message ".$guid." will be fetched from sharer's server: ".$server);
|
||||
$item_id = self::store_by_guid($guid, $server);
|
||||
}
|
||||
*/
|
||||
if ($item_id) {
|
||||
$r = q("SELECT `body`, `tag`, `app`, `created`, `object-type`, `uri`, `guid`,
|
||||
`author-name`, `author-link`, `author-avatar`
|
||||
|
@ -1938,7 +2082,7 @@ class diaspora {
|
|||
$guid = notags(unxmlify($data->guid));
|
||||
$author = notags(unxmlify($data->author));
|
||||
$public = notags(unxmlify($data->public));
|
||||
$created_at = notags(unxmlify($data->created_at));
|
||||
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
|
||||
|
||||
$contact = self::allowed_contact_by_handle($importer, $author, false);
|
||||
if (!$contact)
|
||||
|
@ -1969,7 +2113,7 @@ class diaspora {
|
|||
$datarray["owner-avatar"] = $datarray["author-avatar"];
|
||||
|
||||
$datarray["guid"] = $guid;
|
||||
$datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
|
||||
$datarray["uri"] = $datarray["parent-uri"] = self::get_uri_from_guid($author, $guid);
|
||||
|
||||
$datarray["verb"] = ACTIVITY_POST;
|
||||
$datarray["gravity"] = GRAVITY_PARENT;
|
||||
|
@ -1985,7 +2129,7 @@ class diaspora {
|
|||
|
||||
$datarray["plink"] = self::plink($author, $guid);
|
||||
$datarray["private"] = (($public == "false") ? 1 : 0);
|
||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at);
|
||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
||||
|
||||
$datarray["object-type"] = $original_item["object-type"];
|
||||
|
||||
|
@ -2025,12 +2169,6 @@ class diaspora {
|
|||
if (!$r)
|
||||
return false;
|
||||
|
||||
// Only delete it if the author really fits
|
||||
if (!link_compare($r[0]["author-link"], $person["url"])) {
|
||||
logger("Item author ".$r[0]["author-link"]." doesn't fit to expected contact ".$person["url"], LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the sender is the thread owner
|
||||
$p = q("SELECT `id`, `author-link`, `origin` FROM `item` WHERE `id` = %d",
|
||||
intval($r[0]["parent"]));
|
||||
|
@ -2054,7 +2192,7 @@ class diaspora {
|
|||
// Now check if the retraction needs to be relayed by us
|
||||
if($p[0]["origin"]) {
|
||||
// notify others
|
||||
proc_run("php", "include/notifier.php", "drop", $r[0]["id"]);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $r[0]["id"]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2112,12 +2250,11 @@ class diaspora {
|
|||
* @return int The message id of the newly created item
|
||||
*/
|
||||
private function receive_status_message($importer, $data, $xml) {
|
||||
|
||||
$raw_message = unxmlify($data->raw_message);
|
||||
$guid = notags(unxmlify($data->guid));
|
||||
$author = notags(unxmlify($data->author));
|
||||
$public = notags(unxmlify($data->public));
|
||||
$created_at = notags(unxmlify($data->created_at));
|
||||
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
|
||||
$provider_display_name = notags(unxmlify($data->provider_display_name));
|
||||
|
||||
/// @todo enable support for polls
|
||||
|
@ -2171,7 +2308,7 @@ class diaspora {
|
|||
$datarray["owner-avatar"] = $datarray["author-avatar"];
|
||||
|
||||
$datarray["guid"] = $guid;
|
||||
$datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
|
||||
$datarray["uri"] = $datarray["parent-uri"] = self::get_uri_from_guid($author, $guid);
|
||||
|
||||
$datarray["verb"] = ACTIVITY_POST;
|
||||
$datarray["gravity"] = GRAVITY_PARENT;
|
||||
|
@ -2185,7 +2322,7 @@ class diaspora {
|
|||
|
||||
$datarray["plink"] = self::plink($author, $guid);
|
||||
$datarray["private"] = (($public == "false") ? 1 : 0);
|
||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at);
|
||||
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
|
||||
|
||||
if (isset($address["address"]))
|
||||
$datarray["location"] = $address["address"];
|
||||
|
@ -2227,6 +2364,40 @@ class diaspora {
|
|||
return $nick."@".substr(App::get_baseurl(), strpos(App::get_baseurl(),"://") + 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the envelope for the "fetch" endpoint
|
||||
*
|
||||
* @param string $msg The message that is to be transmitted
|
||||
* @param array $user The record of the sender
|
||||
*
|
||||
* @return string The envelope
|
||||
*/
|
||||
|
||||
public static function build_magic_envelope($msg, $user) {
|
||||
|
||||
$b64url_data = base64url_encode($msg);
|
||||
$data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data);
|
||||
|
||||
$key_id = base64url_encode(diaspora::my_handle($user));
|
||||
$type = "application/xml";
|
||||
$encoding = "base64url";
|
||||
$alg = "RSA-SHA256";
|
||||
$signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg);
|
||||
$signature = rsa_sign($signable_data, $user["prvkey"]);
|
||||
$sig = base64url_encode($signature);
|
||||
|
||||
$xmldata = array("me:env" => array("me:data" => $data,
|
||||
"@attributes" => array("type" => $type),
|
||||
"me:encoding" => $encoding,
|
||||
"me:alg" => $alg,
|
||||
"me:sig" => $sig,
|
||||
"@attributes2" => array("key_id" => $key_id)));
|
||||
|
||||
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
|
||||
|
||||
return xml::from_array($xmldata, $xml, false, $namespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the envelope for a public message
|
||||
*
|
||||
|
@ -2258,10 +2429,10 @@ class diaspora {
|
|||
$sig = base64url_encode($signature);
|
||||
|
||||
$xmldata = array("diaspora" => array("header" => array("author_id" => $handle),
|
||||
"me:env" => array("me:encoding" => "base64url",
|
||||
"me:alg" => "RSA-SHA256",
|
||||
"me:env" => array("me:encoding" => $encoding,
|
||||
"me:alg" => $alg,
|
||||
"me:data" => $data,
|
||||
"@attributes" => array("type" => "application/xml"),
|
||||
"@attributes" => array("type" => $type),
|
||||
"me:sig" => $sig)));
|
||||
|
||||
$namespaces = array("" => "https://joindiaspora.com/protocol",
|
||||
|
@ -2348,10 +2519,10 @@ class diaspora {
|
|||
$cipher_json = base64_encode($encrypted_header_json_object);
|
||||
|
||||
$xmldata = array("diaspora" => array("encrypted_header" => $cipher_json,
|
||||
"me:env" => array("me:encoding" => "base64url",
|
||||
"me:alg" => "RSA-SHA256",
|
||||
"me:env" => array("me:encoding" => $encoding,
|
||||
"me:alg" => $alg,
|
||||
"me:data" => $data,
|
||||
"@attributes" => array("type" => "application/xml"),
|
||||
"@attributes" => array("type" => $type),
|
||||
"me:sig" => $sig)));
|
||||
|
||||
$namespaces = array("" => "https://joindiaspora.com/protocol",
|
||||
|
@ -2469,6 +2640,20 @@ class diaspora {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Build the post xml
|
||||
*
|
||||
* @param string $type The message type
|
||||
* @param array $message The message data
|
||||
*
|
||||
* @return string The post XML
|
||||
*/
|
||||
public static function build_post_xml($type, $message) {
|
||||
|
||||
$data = array("XML" => array("post" => array($type => $message)));
|
||||
return xml::from_array($data, $xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds and transmit messages
|
||||
*
|
||||
|
@ -2484,13 +2669,15 @@ class diaspora {
|
|||
*/
|
||||
private function build_and_transmit($owner, $contact, $type, $message, $public_batch = false, $guid = "", $spool = false) {
|
||||
|
||||
$data = array("XML" => array("post" => array($type => $message)));
|
||||
|
||||
$msg = xml::from_array($data, $xml);
|
||||
$msg = self::build_post_xml($type, $message);
|
||||
|
||||
logger('message: '.$msg, LOGGER_DATA);
|
||||
logger('send guid '.$guid, LOGGER_DEBUG);
|
||||
|
||||
// Fallback if the private key wasn't transmitted in the expected field
|
||||
if ($owner['uprvkey'] == "")
|
||||
$owner['uprvkey'] = $owner['prvkey'];
|
||||
|
||||
$slap = self::build_message($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch);
|
||||
|
||||
if ($spool) {
|
||||
|
@ -2517,6 +2704,8 @@ class diaspora {
|
|||
$message = array("sender_handle" => self::my_handle($owner),
|
||||
"recipient_handle" => $contact["addr"]);
|
||||
|
||||
logger("Send share ".print_r($message, true), LOGGER_DEBUG);
|
||||
|
||||
return self::build_and_transmit($owner, $contact, "request", $message);
|
||||
}
|
||||
|
||||
|
@ -2534,6 +2723,8 @@ class diaspora {
|
|||
"diaspora_handle" => self::my_handle($owner),
|
||||
"type" => "Person");
|
||||
|
||||
logger("Send unshare ".print_r($message, true), LOGGER_DEBUG);
|
||||
|
||||
return self::build_and_transmit($owner, $contact, "retraction", $message);
|
||||
}
|
||||
|
||||
|
@ -2618,16 +2809,16 @@ class diaspora {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Sends a post
|
||||
* @brief Create a post (status message or reshare)
|
||||
*
|
||||
* @param array $item The item that will be exported
|
||||
* @param array $owner the array of the item owner
|
||||
* @param array $contact Target of the communication
|
||||
* @param bool $public_batch Is it a public post?
|
||||
*
|
||||
* @return int The result of the transmission
|
||||
* @return array
|
||||
* 'type' -> Message type ("status_message" or "reshare")
|
||||
* 'message' -> Array of XML elements of the status
|
||||
*/
|
||||
public static function send_status($item, $owner, $contact, $public_batch = false) {
|
||||
public static function build_status($item, $owner) {
|
||||
|
||||
$myaddr = self::my_handle($owner);
|
||||
|
||||
|
@ -2690,8 +2881,24 @@ class diaspora {
|
|||
|
||||
$type = "status_message";
|
||||
}
|
||||
return array("type" => $type, "message" => $message);
|
||||
}
|
||||
|
||||
return self::build_and_transmit($owner, $contact, $type, $message, $public_batch, $item["guid"]);
|
||||
/**
|
||||
* @brief Sends a post
|
||||
*
|
||||
* @param array $item The item that will be exported
|
||||
* @param array $owner the array of the item owner
|
||||
* @param array $contact Target of the communication
|
||||
* @param bool $public_batch Is it a public post?
|
||||
*
|
||||
* @return int The result of the transmission
|
||||
*/
|
||||
public static function send_status($item, $owner, $contact, $public_batch = false) {
|
||||
|
||||
$status = diaspora::build_status($item, $owner);
|
||||
|
||||
return self::build_and_transmit($owner, $contact, $status["type"], $status["message"], $public_batch, $item["guid"]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3004,11 +3211,12 @@ class diaspora {
|
|||
*
|
||||
* @param int $uid The user id
|
||||
*/
|
||||
public static function send_profile($uid) {
|
||||
public static function send_profile($uid, $recips = false) {
|
||||
|
||||
if (!$uid)
|
||||
return;
|
||||
|
||||
if (!$recips)
|
||||
$recips = q("SELECT `id`,`name`,`network`,`pubkey`,`notify` FROM `contact` WHERE `network` = '%s'
|
||||
AND `uid` = %d AND `rel` != %d",
|
||||
dbesc(NETWORK_DIASPORA),
|
||||
|
@ -3078,9 +3286,11 @@ class diaspora {
|
|||
"searchable" => $searchable,
|
||||
"tag_string" => $tags);
|
||||
|
||||
foreach($recips as $recip)
|
||||
foreach($recips as $recip) {
|
||||
logger("Send updated profile data for user ".$uid." to contact ".$recip["id"], LOGGER_DEBUG);
|
||||
self::build_and_transmit($profile, $recip, "profile", $message, false, "", true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the signature for likes that are created on our system
|
||||
|
|
|
@ -49,7 +49,7 @@ function notification($params) {
|
|||
// with $params['show_in_notification_page'] == false, the notification isn't inserted into
|
||||
// the database, and an email is sent if applicable.
|
||||
// default, if not specified: true
|
||||
$show_in_notification_page = ((x($params, 'show_in_notification_page')) ? $params['show_in_notification_page']:True);
|
||||
$show_in_notification_page = ((x($params, 'show_in_notification_page')) ? $params['show_in_notification_page']:true);
|
||||
|
||||
$additional_mail_header = "";
|
||||
$additional_mail_header .= "Precedence: list\n";
|
||||
|
@ -418,6 +418,7 @@ function notification($params) {
|
|||
$datarray = array();
|
||||
$datarray['hash'] = $hash;
|
||||
$datarray['name'] = $params['source_name'];
|
||||
$datarray['name_cache'] = strip_tags(bbcode($params['source_name']));
|
||||
$datarray['url'] = $params['source_link'];
|
||||
$datarray['photo'] = $params['source_photo'];
|
||||
$datarray['date'] = datetime_convert();
|
||||
|
@ -439,8 +440,8 @@ function notification($params) {
|
|||
|
||||
// create notification entry in DB
|
||||
|
||||
$r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`)
|
||||
values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s')",
|
||||
$r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`, `name_cache`)
|
||||
values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s')",
|
||||
dbesc($datarray['hash']),
|
||||
dbesc($datarray['name']),
|
||||
dbesc($datarray['url']),
|
||||
|
@ -452,7 +453,8 @@ function notification($params) {
|
|||
intval($datarray['parent']),
|
||||
intval($datarray['type']),
|
||||
dbesc($datarray['verb']),
|
||||
dbesc($datarray['otype'])
|
||||
dbesc($datarray['otype']),
|
||||
dbesc($datarray["name_cache"])
|
||||
);
|
||||
|
||||
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' AND `uid` = %d LIMIT 1",
|
||||
|
@ -494,8 +496,10 @@ function notification($params) {
|
|||
|
||||
$itemlink = $a->get_baseurl().'/notify/view/'.$notify_id;
|
||||
$msg = replace_macros($epreamble, array('$itemlink' => $itemlink));
|
||||
$r = q("UPDATE `notify` SET `msg` = '%s' WHERE `id` = %d AND `uid` = %d",
|
||||
$msg_cache = format_notification_message($datarray['name_cache'], strip_tags(bbcode($msg)));
|
||||
$r = q("UPDATE `notify` SET `msg` = '%s', `msg_cache` = '%s' WHERE `id` = %d AND `uid` = %d",
|
||||
dbesc($msg),
|
||||
dbesc($msg_cache),
|
||||
intval($notify_id),
|
||||
intval($params['uid'])
|
||||
);
|
||||
|
@ -778,4 +782,27 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
if (isset($params["type"]))
|
||||
notification($params);
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* @brief Formats a notification message with the notification author
|
||||
*
|
||||
* Replace the name with {0} but ensure to make that only once. The {0} is used
|
||||
* later and prints the name in bold.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $message
|
||||
* @return string Formatted message
|
||||
*/
|
||||
function format_notification_message($name, $message) {
|
||||
if ($name != '') {
|
||||
$pos = strpos($message, $name);
|
||||
} else {
|
||||
$pos = false;
|
||||
}
|
||||
|
||||
if ($pos !== false) {
|
||||
$message = substr_replace($message, '{0}', $pos, strlen($name));
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* @file include/event.php
|
||||
* @brief functions specific to event handling
|
||||
*/
|
||||
|
||||
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)))
|
||||
return '';
|
||||
|
||||
|
@ -290,7 +293,7 @@ function event_store($arr) {
|
|||
`location` = '%s',
|
||||
`type` = '%s',
|
||||
`adjust` = %d,
|
||||
`nofinish` = %d,
|
||||
`nofinish` = %d
|
||||
WHERE `id` = %d AND `uid` = %d",
|
||||
|
||||
dbesc($arr['edited']),
|
||||
|
@ -427,3 +430,427 @@ function event_store($arr) {
|
|||
return $item_id;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
$i18n = array(
|
||||
"firstDay" => $firstDay,
|
||||
"Sun" => t("Sun"),
|
||||
"Mon" => t("Mon"),
|
||||
"Tue" => t("Tue"),
|
||||
"Wed" => t("Wed"),
|
||||
"Thu" => t("Thu"),
|
||||
"Fri" => t("Fri"),
|
||||
"Sat" => t("Sat"),
|
||||
"Sunday" => t("Sunday"),
|
||||
"Monday" => t("Monday"),
|
||||
"Tuesday" => t("Tuesday"),
|
||||
"Wednesday" => t("Wednesday"),
|
||||
"Thursday" => t("Thursday"),
|
||||
"Friday" => t("Friday"),
|
||||
"Saturday" => t("Saturday"),
|
||||
"Jan" => t("Jan"),
|
||||
"Feb" => t("Feb"),
|
||||
"Mar" => t("Mar"),
|
||||
"Apr" => t("Apr"),
|
||||
"May" => t("May"),
|
||||
"Jun" => t("Jun"),
|
||||
"Jul" => t("Jul"),
|
||||
"Aug" => t("Aug"),
|
||||
"Sep" => t("Sept"),
|
||||
"Oct" => t("Oct"),
|
||||
"Nov" => t("Nov"),
|
||||
"Dec" => t("Dec"),
|
||||
"January" => t("January"),
|
||||
"February" => t("February"),
|
||||
"March" => t("March"),
|
||||
"April" => t("April"),
|
||||
"May" => t("May"),
|
||||
"June" => t("June"),
|
||||
"July" => t("July"),
|
||||
"August" => t("August"),
|
||||
"September" => t("September"),
|
||||
"October" => t("October"),
|
||||
"November" => t("November"),
|
||||
"December" => t("December"),
|
||||
"today" => t("today"),
|
||||
"month" => t("month"),
|
||||
"week" => t("week"),
|
||||
"day" => t("day"),
|
||||
"allday" => t("all-day"),
|
||||
|
||||
"noevent" => t("No events to display"),
|
||||
|
||||
"dtstart_label" => t("Starts:"),
|
||||
"dtend_label" => t("Finishes:"),
|
||||
"location_label" => t("Location:")
|
||||
);
|
||||
|
||||
return $i18n;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an event by its event ID
|
||||
*
|
||||
* @param type $owner_uid The User ID of the owner of the event
|
||||
* @param type $event_params An assoziative array with
|
||||
* int 'event_id' => The ID of the event in the event table
|
||||
* @param type $sql_extra
|
||||
* @return array Query result
|
||||
*/
|
||||
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)
|
||||
return;
|
||||
|
||||
// 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`
|
||||
STRAIGHT_JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid`
|
||||
WHERE `event`.`uid` = %d AND `event`.`id` = %d $sql_extra",
|
||||
intval($owner_uid),
|
||||
intval($event_params["event_id"])
|
||||
);
|
||||
|
||||
if(count($r))
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get all events in a specific timeframe
|
||||
*
|
||||
* @param int $owner_uid The User ID of the owner of the events
|
||||
* @param array $event_params An assoziative array with
|
||||
* int 'ignored' =>
|
||||
* string 'start' => Start time of the timeframe
|
||||
* string 'finish' => Finish time of the timeframe
|
||||
* string 'adjust_start' =>
|
||||
* string 'adjust_start' =>
|
||||
*
|
||||
* @param string $sql_extra Additional sql conditions (e.g. permission request)
|
||||
* @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)
|
||||
return;
|
||||
|
||||
// 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`
|
||||
STRAIGHT_JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid`
|
||||
WHERE `event`.`uid` = %d AND event.ignore = %d
|
||||
AND ((`adjust` = 0 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s')
|
||||
OR (`adjust` = 1 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s'))
|
||||
$sql_extra ",
|
||||
intval($owner_uid),
|
||||
intval($event_params["ignored"]),
|
||||
dbesc($event_params["start"]),
|
||||
dbesc($event_params["start"]),
|
||||
dbesc($event_params["finish"]),
|
||||
dbesc($event_params["adjust_start"]),
|
||||
dbesc($event_params["adjust_start"]),
|
||||
dbesc($event_params["adjust_finish"])
|
||||
);
|
||||
|
||||
if(count($r))
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert an array query results in an arry which could be used by the events template
|
||||
*
|
||||
* @param array $arr Event query array
|
||||
* @return array Event array for the template
|
||||
*/
|
||||
function process_events ($arr) {
|
||||
$events=array();
|
||||
|
||||
$last_date = '';
|
||||
$fmt = t('l, F j');
|
||||
if (count($arr)) {
|
||||
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));
|
||||
$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']){
|
||||
$end = null;
|
||||
} else {
|
||||
$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("<br",bbcode($rr['desc']),2);
|
||||
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
|
||||
}
|
||||
|
||||
$html = format_event_html($rr);
|
||||
$rr['desc'] = bbcode($rr['desc']);
|
||||
$rr['location'] = bbcode($rr['location']);
|
||||
$events[] = array(
|
||||
'id'=>$rr['id'],
|
||||
'start'=> $start,
|
||||
'end' => $end,
|
||||
'allDay' => false,
|
||||
'title' => $title,
|
||||
|
||||
'j' => $j,
|
||||
'd' => $d,
|
||||
'is_first'=>$is_first,
|
||||
'item'=>$rr,
|
||||
'html'=>$html,
|
||||
'plink' => array($rr['plink'],t('link to source'),'',''),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format event to export format (ical/csv)
|
||||
*
|
||||
* @param array $events Query result for events
|
||||
* @param string $format The output format (ical/csv)
|
||||
* @param string $timezone The timezone of the user (not implemented yet)
|
||||
*
|
||||
* @return string Content according to selected export format
|
||||
*/
|
||||
function event_format_export ($events, $format = 'ical', $timezone) {
|
||||
if(! ((is_array($events)) && count($events)))
|
||||
return;
|
||||
|
||||
switch ($format) {
|
||||
// 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 :-/
|
||||
$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;
|
||||
}
|
||||
break;
|
||||
|
||||
// format the exported data as a ics file
|
||||
case "ical":
|
||||
header("Content-type: text/ics");
|
||||
$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
|
||||
// see http://tools.ietf.org/html/rfc2445#section-4.8.3
|
||||
// . 'BEGIN:VTIMEZONE' . PHP_EOL
|
||||
// . 'TZID:' . $timezone . PHP_EOL
|
||||
// . 'END:VTIMEZONE' . PHP_EOL;
|
||||
// TODO instead of PHP_EOL CRLF should be used for long entries
|
||||
// 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]) {
|
||||
$tmp = strtotime($event['start']);
|
||||
$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;
|
||||
}
|
||||
if ($event['summary'])
|
||||
$tmp = $event['summary'];
|
||||
$tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp);
|
||||
$tmp = addcslashes($tmp, ',;');
|
||||
$o .= 'SUMMARY:' . $tmp . PHP_EOL;
|
||||
if ($event['desc'])
|
||||
$tmp = $event['desc'];
|
||||
$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 = addcslashes($tmp, ',;');
|
||||
$o .= 'LOCATION:' . $tmp . PHP_EOL;
|
||||
}
|
||||
|
||||
$o .= 'END:VEVENT' . PHP_EOL;
|
||||
$o .= PHP_EOL;
|
||||
}
|
||||
|
||||
$o .= 'END:VCALENDAR' . PHP_EOL;
|
||||
break;
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get all events for a user ID
|
||||
*
|
||||
* The query for events is done permission sensitive
|
||||
* If the user is the owner of the calendar he/she
|
||||
* will get all of his/her available events.
|
||||
* If the user is only a visitor only the public events will
|
||||
* be available
|
||||
*
|
||||
* @param int $uid The user ID
|
||||
* @param int $sql_extra Additional sql conditions for permission
|
||||
*
|
||||
* @return array Query results
|
||||
*/
|
||||
function events_by_uid($uid = 0, $sql_extra = '') {
|
||||
if($uid == 0)
|
||||
return;
|
||||
|
||||
// The permission condition if no condition was transmitted
|
||||
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
|
||||
if (local_user() == $uid) {
|
||||
$r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish`
|
||||
FROM `event` WHERE `uid`= %d AND `cid` = 0 ",
|
||||
intval($uid)
|
||||
);
|
||||
} else {
|
||||
$r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish`
|
||||
FROM `event` WHERE `uid`= %d AND `cid` = 0 $sql_extra ",
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
|
||||
if(count($r))
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param int $uid The user ID
|
||||
* @param string $format Output format (ical/csv)
|
||||
* @return array With the results
|
||||
* bool 'success' => True if the processing was successful
|
||||
* string 'format' => The output format
|
||||
* string 'extension' => The file extension of the output format
|
||||
* string 'content' => The formatted output content
|
||||
*
|
||||
* @todo Respect authenticated users with events_by_uid()
|
||||
*/
|
||||
function event_export($uid, $format = 'ical') {
|
||||
|
||||
$process = false;
|
||||
|
||||
// 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 (count($r))
|
||||
$timezone = $r[0]['timezone'];
|
||||
|
||||
// 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))
|
||||
$res = event_format_export($events, $format, $timezone);
|
||||
|
||||
// If there are results the precess was successfull
|
||||
if(x($res))
|
||||
$process = true;
|
||||
|
||||
// get the file extension for the format
|
||||
switch ($format) {
|
||||
case "ical":
|
||||
$file_ext = "ics";
|
||||
break;
|
||||
|
||||
case "csv":
|
||||
$file_ext = "csv";
|
||||
break;
|
||||
|
||||
default:
|
||||
$file_ext = "";
|
||||
}
|
||||
|
||||
$arr = array(
|
||||
'success' => $process,
|
||||
'format' => $format,
|
||||
'extension' => $file_ext,
|
||||
'content' => $res,
|
||||
);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the events widget
|
||||
*
|
||||
* @return string Formated html of the evens widget
|
||||
*/
|
||||
function widget_events() {
|
||||
$a = get_app();
|
||||
|
||||
$owner_uid = $a->data['user']['uid'];
|
||||
// $a->data is only available if the profile page is visited. If the visited page is not part
|
||||
// of the profile page it should be the personal /events page. So we can use $a->user
|
||||
$user = ($a->data['user']['nickname'] ? $a->data['user']['nickname'] : $a->user['nickname']);
|
||||
|
||||
|
||||
// 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)
|
||||
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)
|
||||
// So we have to test if if it's the own profile page of the logged in user
|
||||
// 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"))
|
||||
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"))
|
||||
return;
|
||||
|
||||
return replace_macros(get_markup_template("events_aside.tpl"), array(
|
||||
'$etitle' => t("Export"),
|
||||
'$export_ical' => t("Export calendar as ical"),
|
||||
'$export_csv' => t("Export calendar as csv"),
|
||||
'$user' => $user
|
||||
));
|
||||
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ function get_features($filtered = true) {
|
|||
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
|
||||
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, get_config('feature_lock','multi_profiles')),
|
||||
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, get_config('feature_lock','photo_location')),
|
||||
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, get_config('feature_lock','export_calendar')),
|
||||
),
|
||||
|
||||
// Post composition
|
||||
|
@ -71,7 +72,7 @@ function get_features($filtered = true) {
|
|||
t('Post Composition Features'),
|
||||
array('richtext', t('Richtext Editor'), t('Enable richtext editor'), false, get_config('feature_lock','richtext')),
|
||||
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'), false, get_config('feature_lock','preview')),
|
||||
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a fourm page is selected/deselected in ACL window.'), false, get_config('feature_lock','aclautomention')),
|
||||
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a forum page is selected/deselected in ACL window.'), false, get_config('feature_lock','aclautomention')),
|
||||
),
|
||||
|
||||
// Network sidebar widgets
|
||||
|
|
|
@ -17,10 +17,15 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
|
|||
|
||||
$a = get_app();
|
||||
|
||||
logger("Import Atom/RSS feed", LOGGER_DEBUG);
|
||||
if (!$simulate)
|
||||
logger("Import Atom/RSS feed '".$contact["name"]."' (Contact ".$contact["id"].") for user ".$importer["uid"], LOGGER_DEBUG);
|
||||
else
|
||||
logger("Test Atom/RSS feed", LOGGER_DEBUG);
|
||||
|
||||
if ($xml == "")
|
||||
if ($xml == "") {
|
||||
logger('XML is empty.', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadXML($xml);
|
||||
|
@ -54,8 +59,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
|
|||
if ($attributes->name == "href")
|
||||
$author["author-link"] = $attributes->textContent;
|
||||
|
||||
$author["author-id"] = $xpath->evaluate('/atom:feed/atom:author/atom:uri/text()')->item(0)->nodeValue;
|
||||
|
||||
if ($author["author-link"] == "")
|
||||
$author["author-link"] = $author["author-id"];
|
||||
|
||||
|
@ -84,10 +87,23 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
|
|||
if ($value != "")
|
||||
$author["author-name"] = $value;
|
||||
|
||||
if ($simulate) {
|
||||
$author["author-id"] = $xpath->evaluate('/atom:feed/atom:author/atom:uri/text()')->item(0)->nodeValue;
|
||||
|
||||
$value = $xpath->evaluate('atom:author/poco:preferredUsername/text()')->item(0)->nodeValue;
|
||||
if ($value != "")
|
||||
$author["author-nick"] = $value;
|
||||
|
||||
$value = $xpath->evaluate('atom:author/poco:address/poco:formatted/text()', $context)->item(0)->nodeValue;
|
||||
if ($value != "")
|
||||
$author["author-location"] = $value;
|
||||
|
||||
$value = $xpath->evaluate('atom:author/poco:note/text()')->item(0)->nodeValue;
|
||||
if ($value != "")
|
||||
$author["author-about"] = $value;
|
||||
|
||||
}
|
||||
|
||||
$author["edited"] = $author["created"] = $xpath->query('/atom:feed/atom:updated/text()')->item(0)->nodeValue;
|
||||
|
||||
$author["app"] = $xpath->evaluate('/atom:feed/atom:generator/text()')->item(0)->nodeValue;
|
||||
|
@ -126,10 +142,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
|
|||
$author["owner-link"] = $contact["url"];
|
||||
$author["owner-name"] = $contact["name"];
|
||||
$author["owner-avatar"] = $contact["thumb"];
|
||||
|
||||
// This is no field in the item table. So we have to unset it.
|
||||
unset($author["author-nick"]);
|
||||
unset($author["author-id"]);
|
||||
}
|
||||
|
||||
$header = array();
|
||||
|
@ -150,8 +162,10 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
|
|||
$header["last-child"] = 0;
|
||||
}
|
||||
|
||||
if (!is_object($entries))
|
||||
if (!is_object($entries)) {
|
||||
logger("There are no entries in this feed.", LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$items = array();
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ function new_contact($uid,$url,$interactive = false) {
|
|||
|
||||
// pull feed and consume it, which should subscribe to the hub.
|
||||
|
||||
proc_run('php',"include/onepoll.php","$contact_id", "force");
|
||||
proc_run(PRIORITY_HIGH, "include/onepoll.php", $contact_id, "force");
|
||||
|
||||
// create a follow slap
|
||||
|
||||
|
|
|
@ -39,14 +39,13 @@ function gprobe_run(&$argv, &$argc){
|
|||
|
||||
logger("gprobe start for ".normalise_link($url), LOGGER_DEBUG);
|
||||
|
||||
if (!count($r)) {
|
||||
if (!dbm::is_result($r)) {
|
||||
|
||||
// Is it a DDoS attempt?
|
||||
$urlparts = parse_url($url);
|
||||
|
||||
$result = Cache::get("gprobe:".$urlparts["host"]);
|
||||
if (!is_null($result)) {
|
||||
$result = unserialize($result);
|
||||
if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
|
||||
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
|
||||
return;
|
||||
|
@ -56,7 +55,7 @@ function gprobe_run(&$argv, &$argc){
|
|||
$arr = probe_url($url);
|
||||
|
||||
if (is_null($result))
|
||||
Cache::set("gprobe:".$urlparts["host"],serialize($arr));
|
||||
Cache::set("gprobe:".$urlparts["host"], $arr);
|
||||
|
||||
if (!in_array($arr["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))
|
||||
update_gcontact($arr);
|
||||
|
@ -65,7 +64,7 @@ function gprobe_run(&$argv, &$argc){
|
|||
dbesc(normalise_link($url))
|
||||
);
|
||||
}
|
||||
if(count($r)) {
|
||||
if(dbm::is_result($r)) {
|
||||
// Check for accessibility and do a poco discovery
|
||||
if (poco_last_updated($r[0]['url'], true) AND ($r[0]["network"] == NETWORK_DFRN))
|
||||
poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));
|
||||
|
|
|
@ -71,8 +71,8 @@ function profile_load(&$a, $nickname, $profile = 0, $profiledata = array()) {
|
|||
|
||||
$a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename'];
|
||||
|
||||
// if (!$profiledata)
|
||||
// $_SESSION['theme'] = $a->profile['theme'];
|
||||
if (!$profiledata && !get_pconfig(local_user(),'system','always_my_theme'))
|
||||
$_SESSION['theme'] = $a->profile['theme'];
|
||||
|
||||
$_SESSION['mobile-theme'] = $a->profile['mobile-theme'];
|
||||
|
||||
|
@ -149,17 +149,23 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
|
|||
|
||||
if($profile) {
|
||||
$profile_int = intval($profile);
|
||||
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
|
||||
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d AND `contact`.`self` = 1 LIMIT 1",
|
||||
$r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
|
||||
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
|
||||
FROM `profile`
|
||||
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
|
||||
INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d LIMIT 1",
|
||||
dbesc($nickname),
|
||||
intval($profile_int)
|
||||
);
|
||||
}
|
||||
if((!$r) && (!count($r))) {
|
||||
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
|
||||
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 AND `contact`.`self` = 1 LIMIT 1",
|
||||
$r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
|
||||
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
|
||||
FROM `profile`
|
||||
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
|
||||
INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
}
|
||||
|
@ -310,15 +316,8 @@ function profile_sidebar($profile, $block = 0) {
|
|||
);
|
||||
}
|
||||
|
||||
// check if profile is a forum
|
||||
if((intval($profile['page-flags']) == PAGE_COMMUNITY)
|
||||
|| (intval($profile['page-flags']) == PAGE_PRVGROUP)
|
||||
|| (isset($profile['forum']) && intval($profile['forum']))
|
||||
|| (isset($profile['prv']) && intval($profile['prv']))
|
||||
|| (isset($profile['community']) && intval($profile['community'])))
|
||||
$account_type = t('Forum');
|
||||
else
|
||||
$account_type = "";
|
||||
// Fetch the account type
|
||||
$account_type = account_type($profile);
|
||||
|
||||
if((x($profile,'address') == 1)
|
||||
|| (x($profile,'location') == 1)
|
||||
|
@ -337,6 +336,8 @@ function profile_sidebar($profile, $block = 0) {
|
|||
|
||||
$about = ((x($profile,'about') == 1) ? t('About:') : False);
|
||||
|
||||
$xmpp = ((x($profile,'xmpp') == 1) ? t('XMPP:') : False);
|
||||
|
||||
if(($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) {
|
||||
$location = $pdesc = $gender = $marital = $homepage = $about = False;
|
||||
}
|
||||
|
@ -405,6 +406,7 @@ function profile_sidebar($profile, $block = 0) {
|
|||
$tpl = get_markup_template('profile_vcard.tpl');
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$profile' => $p,
|
||||
'$xmpp' => $xmpp,
|
||||
'$connect' => $connect,
|
||||
'$remoteconnect' => $remoteconnect,
|
||||
'$subscribe_feed' => $subscribe_feed,
|
||||
|
@ -687,6 +689,8 @@ function advanced_profile(&$a) {
|
|||
|
||||
return replace_macros($tpl, array(
|
||||
'$title' => t('Profile'),
|
||||
'$basic' => t('Basic'),
|
||||
'$advanced' => t('Advanced'),
|
||||
'$profile' => $profile
|
||||
));
|
||||
}
|
||||
|
@ -740,8 +744,8 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){
|
|||
),
|
||||
);
|
||||
|
||||
if ($is_owner){
|
||||
if ($a->theme_events_in_profile)
|
||||
// the calendar link for the full featured events calendar
|
||||
if ($is_owner && $a->theme_events_in_profile) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Events'),
|
||||
'url' => $a->get_baseurl() . '/events',
|
||||
|
@ -750,6 +754,20 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){
|
|||
'id' => 'events-tab',
|
||||
'accesskey' => 'e',
|
||||
);
|
||||
// if the user is not the owner of the calendar we only show a calendar
|
||||
// with the public events of the calendar owner
|
||||
} elseif (! $is_owner) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Events'),
|
||||
'url' => $a->get_baseurl() . '/cal/' . $nickname,
|
||||
'sel' =>((!isset($tab)&&$a->argv[0]=='cal')?'active':''),
|
||||
'title' => t('Events and Calendar'),
|
||||
'id' => 'events-tab',
|
||||
'accesskey' => 'e',
|
||||
);
|
||||
}
|
||||
|
||||
if ($is_owner){
|
||||
$tabs[] = array(
|
||||
'label' => t('Personal Notes'),
|
||||
'url' => $a->get_baseurl() . '/notes',
|
||||
|
@ -802,7 +820,7 @@ function zrl_init(&$a) {
|
|||
}
|
||||
}
|
||||
|
||||
proc_run('php','include/gprobe.php',bin2hex($tmp_str));
|
||||
proc_run(PRIORITY_LOW, 'include/gprobe.php',bin2hex($tmp_str));
|
||||
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
|
||||
call_hooks('zrl_init',$arr);
|
||||
}
|
||||
|
|
|
@ -69,15 +69,13 @@ function limit_body_size($body) {
|
|||
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
|
||||
$textlen = $maxlen;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$new_body = $new_body . substr($orig_body, 0, $img_start);
|
||||
$textlen += $img_start;
|
||||
}
|
||||
|
||||
$new_body = $new_body . substr($orig_body, $img_start, $img_end - $img_start);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
if ( ($textlen + $img_end) > $maxlen ) {
|
||||
if ($textlen < $maxlen) {
|
||||
|
@ -85,8 +83,7 @@ function limit_body_size($body) {
|
|||
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
|
||||
$textlen = $maxlen;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$new_body = $new_body . substr($orig_body, 0, $img_end);
|
||||
$textlen += $img_end;
|
||||
}
|
||||
|
@ -107,16 +104,14 @@ function limit_body_size($body) {
|
|||
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
|
||||
$textlen = $maxlen;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
logger('limit_body_size: the text size with embedded images extracted did not violate the limit', LOGGER_DEBUG);
|
||||
$new_body = $new_body . $orig_body;
|
||||
$textlen += strlen($orig_body);
|
||||
}
|
||||
|
||||
return $new_body;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return $body;
|
||||
}}
|
||||
|
||||
|
@ -319,9 +314,7 @@ function item_add_language_opt(&$arr) {
|
|||
return;
|
||||
}
|
||||
$postopts = $arr['postopts'];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$postopts = "";
|
||||
}
|
||||
|
||||
|
@ -584,6 +577,12 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
"photo" => $arr['author-avatar'], "name" => $arr['author-name']));
|
||||
}
|
||||
|
||||
if ($arr["author-id"] == 0)
|
||||
$arr["author-id"] = get_contact($arr["author-link"], 0);
|
||||
|
||||
if ($arr["owner-id"] == 0)
|
||||
$arr["owner-id"] = get_contact($arr["owner-link"], 0);
|
||||
|
||||
if ($arr['guid'] != "") {
|
||||
// Checking if there is already an item with the same guid
|
||||
logger('checking for an item for user '.$arr['uid'].' on network '.$arr['network'].' with the guid '.$arr['guid'], LOGGER_DEBUG);
|
||||
|
@ -608,8 +607,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
$deny_cid = $arr['deny_cid'];
|
||||
$deny_gid = $arr['deny_gid'];
|
||||
$notify_type = 'wall-new';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
// find the parent and snarf the item id and ACLs
|
||||
// and anything else we need to inherit
|
||||
|
@ -663,7 +661,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
|
||||
// If its a post from myself then tag the thread as "mention"
|
||||
logger("item_store: Checking if parent ".$parent_id." has to be tagged as mention for user ".$arr['uid'], LOGGER_DEBUG);
|
||||
$u = q("select * from user where uid = %d limit 1", intval($arr['uid']));
|
||||
$u = q("SELECT `nickname` FROM `user` WHERE `uid` = %d", intval($arr['uid']));
|
||||
if (count($u)) {
|
||||
$a = get_app();
|
||||
$self = normalise_link($a->get_baseurl() . '/profile/' . $u[0]['nickname']);
|
||||
|
@ -673,8 +671,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
logger("item_store: tagged thread ".$parent_id." as mention for user ".$self, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
// Allow one to see reply tweets from status.net even when
|
||||
// we don't have or can't see the original post.
|
||||
|
@ -684,8 +681,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
$parent_id = 0;
|
||||
$arr['parent-uri'] = $arr['uri'];
|
||||
$arr['gravity'] = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
logger('item_store: item parent '.$arr['parent-uri'].' for '.$arr['uid'].' was not found - ignoring item');
|
||||
return 0;
|
||||
}
|
||||
|
@ -700,11 +696,22 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
dbesc(NETWORK_DFRN),
|
||||
intval($arr['uid'])
|
||||
);
|
||||
if($r && count($r)) {
|
||||
if (dbm::is_result($r)) {
|
||||
logger('duplicated item with the same uri found. '.print_r($arr,true));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On Friendica and Diaspora the GUID is unique
|
||||
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
|
||||
$r = q("SELECT `id` FROM `item` WHERE `guid` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($arr['guid']),
|
||||
intval($arr['uid'])
|
||||
);
|
||||
if (dbm::is_result($r)) {
|
||||
logger('duplicated item with the same guid found. '.print_r($arr,true));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Check for an existing post with the same content. There seems to be a problem with OStatus.
|
||||
$r = q("SELECT `id` FROM `item` WHERE `body` = '%s' AND `network` = '%s' AND `created` = '%s' AND `contact-id` = %d AND `uid` = %d LIMIT 1",
|
||||
dbesc($arr['body']),
|
||||
|
@ -713,15 +720,17 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
intval($arr['contact-id']),
|
||||
intval($arr['uid'])
|
||||
);
|
||||
if($r && count($r)) {
|
||||
if (dbm::is_result($r)) {
|
||||
logger('duplicated item with the same body found. '.print_r($arr,true));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Is this item available in the global items (with uid=0)?
|
||||
if ($arr["uid"] == 0) {
|
||||
$arr["global"] = true;
|
||||
|
||||
// Set the global flag on all items if this was a global item entry
|
||||
q("UPDATE `item` SET `global` = 1 WHERE `uri` = '%s'", dbesc($arr["uri"]));
|
||||
} else {
|
||||
$isglobal = q("SELECT `global` FROM `item` WHERE `uid` = 0 AND `uri` = '%s'", dbesc($arr["uri"]));
|
||||
|
@ -729,6 +738,19 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
$arr["global"] = (count($isglobal) > 0);
|
||||
}
|
||||
|
||||
// ACL settings
|
||||
if (strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
|
||||
$private = 1;
|
||||
else
|
||||
$private = $arr['private'];
|
||||
|
||||
$arr["allow_cid"] = $allow_cid;
|
||||
$arr["allow_gid"] = $allow_gid;
|
||||
$arr["deny_cid"] = $deny_cid;
|
||||
$arr["deny_gid"] = $deny_gid;
|
||||
$arr["private"] = $private;
|
||||
$arr["deleted"] = $parent_deleted;
|
||||
|
||||
// Fill the cache field
|
||||
put_item_in_cache($arr);
|
||||
|
||||
|
@ -742,6 +764,17 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Check for already added items.
|
||||
// There is a timing issue here that sometimes creates double postings.
|
||||
// An unique index would help - but the limitations of MySQL (maximum size of index values) prevent this.
|
||||
if ($arr["uid"] == 0) {
|
||||
$r = qu("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc(trim($arr['uri'])));
|
||||
if (dbm::is_result($r)) {
|
||||
logger('Global item already stored. URI: '.$arr['uri'].' on network '.$arr['network'], LOGGER_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the unescaped version
|
||||
$unescaped = $arr;
|
||||
|
||||
|
@ -749,6 +782,9 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
|
||||
logger('item_store: ' . print_r($arr,true), LOGGER_DATA);
|
||||
|
||||
q("COMMIT");
|
||||
q("START TRANSACTION;");
|
||||
|
||||
$r = dbq("INSERT INTO `item` (`"
|
||||
. implode("`, `", array_keys($arr))
|
||||
. "`) VALUES ('"
|
||||
|
@ -758,84 +794,73 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
// And restore it
|
||||
$arr = $unescaped;
|
||||
|
||||
// find the item that we just created
|
||||
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' ORDER BY `id` ASC",
|
||||
// When the item was successfully stored we fetch the ID of the item.
|
||||
if (dbm::is_result($r)) {
|
||||
$r = q("SELECT LAST_INSERT_ID() AS `item-id`");
|
||||
if (dbm::is_result($r)) {
|
||||
$current_post = $r[0]['item-id'];
|
||||
} else {
|
||||
// This shouldn't happen
|
||||
$current_post = 0;
|
||||
}
|
||||
} else {
|
||||
// This can happen - for example - if there are locking timeouts.
|
||||
logger("Item wasn't stored - we quit here.");
|
||||
q("COMMIT");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($current_post == 0) {
|
||||
// This is one of these error messages that never should occur.
|
||||
logger("couldn't find created item - we better quit now.");
|
||||
q("COMMIT");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// How much entries have we created?
|
||||
// We wouldn't need this query when we could use an unique index - but MySQL has length problems with them.
|
||||
$r = q("SELECT COUNT(*) AS `entries` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s'",
|
||||
dbesc($arr['uri']),
|
||||
intval($arr['uid']),
|
||||
dbesc($arr['network'])
|
||||
);
|
||||
|
||||
if(count($r) > 1) {
|
||||
// There are duplicates. Keep the oldest one, delete the others
|
||||
logger('item_store: duplicated post occurred. Removing newer duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
|
||||
q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' AND `id` > %d",
|
||||
dbesc($arr['uri']),
|
||||
intval($arr['uid']),
|
||||
dbesc($arr['network']),
|
||||
intval($r[0]["id"])
|
||||
);
|
||||
if (!dbm::is_result($r)) {
|
||||
// This shouldn't happen, since COUNT always works when the database connection is there.
|
||||
logger("We couldn't count the stored entries. Very strange ...");
|
||||
q("COMMIT");
|
||||
return 0;
|
||||
} elseif(count($r)) {
|
||||
}
|
||||
|
||||
if ($r[0]["entries"] > 1) {
|
||||
// There are duplicates. We delete our just created entry.
|
||||
logger('Duplicated post occurred. uri = '.$arr['uri'].' uid = '.$arr['uid']);
|
||||
|
||||
// Yes, we could do a rollback here - but we are having many users with MyISAM.
|
||||
q("DELETE FROM `item` WHERE `id` = %d", intval($current_post));
|
||||
q("COMMIT");
|
||||
return 0;
|
||||
} elseif ($r[0]["entries"] == 0) {
|
||||
// This really should never happen since we quit earlier if there were problems.
|
||||
logger("Something is terribly wrong. We haven't found our created entry.");
|
||||
q("COMMIT");
|
||||
return 0;
|
||||
}
|
||||
|
||||
$current_post = $r[0]['id'];
|
||||
logger('item_store: created item '.$current_post);
|
||||
item_set_last_item($arr);
|
||||
|
||||
// Set "success_update" and "last-item" to the date of the last time we heard from this contact
|
||||
// This can be used to filter for inactive contacts.
|
||||
// Only do this for public postings to avoid privacy problems, since poco data is public.
|
||||
// Don't set this value if it isn't from the owner (could be an author that we don't know)
|
||||
|
||||
$update = (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"])));
|
||||
|
||||
// Is it a forum? Then we don't care about the rules from above
|
||||
if (!$update AND ($arr["network"] == NETWORK_DFRN) AND ($arr["parent-uri"] === $arr["uri"])) {
|
||||
$isforum = q("SELECT `forum` FROM `contact` WHERE `id` = %d AND `forum`",
|
||||
intval($arr['contact-id']));
|
||||
if ($isforum)
|
||||
$update = true;
|
||||
}
|
||||
|
||||
if ($update)
|
||||
q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
|
||||
dbesc($arr['received']),
|
||||
dbesc($arr['received']),
|
||||
intval($arr['contact-id'])
|
||||
);
|
||||
} else {
|
||||
logger('item_store: could not locate created item');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
|
||||
if (!$parent_id || ($arr['parent-uri'] === $arr['uri']))
|
||||
$parent_id = $current_post;
|
||||
|
||||
if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
|
||||
$private = 1;
|
||||
else
|
||||
$private = $arr['private'];
|
||||
|
||||
// Set parent id - and also make sure to inherit the parent's ACLs.
|
||||
|
||||
$r = q("UPDATE `item` SET `parent` = %d, `allow_cid` = '%s', `allow_gid` = '%s',
|
||||
`deny_cid` = '%s', `deny_gid` = '%s', `private` = %d, `deleted` = %d WHERE `id` = %d",
|
||||
// Set parent id
|
||||
$r = q("UPDATE `item` SET `parent` = %d WHERE `id` = %d",
|
||||
intval($parent_id),
|
||||
dbesc($allow_cid),
|
||||
dbesc($allow_gid),
|
||||
dbesc($deny_cid),
|
||||
dbesc($deny_gid),
|
||||
intval($private),
|
||||
intval($parent_deleted),
|
||||
intval($current_post)
|
||||
);
|
||||
|
||||
$arr['id'] = $current_post;
|
||||
$arr['parent'] = $parent_id;
|
||||
$arr['allow_cid'] = $allow_cid;
|
||||
$arr['allow_gid'] = $allow_gid;
|
||||
$arr['deny_cid'] = $deny_cid;
|
||||
$arr['deny_gid'] = $deny_gid;
|
||||
$arr['private'] = $private;
|
||||
$arr['deleted'] = $parent_deleted;
|
||||
|
||||
// update the commented timestamp on the parent
|
||||
// Only update "commented" if it is really a comment
|
||||
|
@ -868,19 +893,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this is now the last-child, force all _other_ children of this parent to *not* be last-child
|
||||
*/
|
||||
|
||||
if($arr['last-child']) {
|
||||
$r = q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d AND `id` != %d",
|
||||
dbesc($arr['uri']),
|
||||
intval($arr['uid']),
|
||||
intval($current_post)
|
||||
);
|
||||
}
|
||||
|
||||
$deleted = tag_deliver($arr['uid'],$current_post);
|
||||
|
||||
// current post can be deleted if is for a community page and no mention are
|
||||
|
@ -897,25 +909,90 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
|||
logger('item_store: new item not found in DB, id ' . $current_post);
|
||||
}
|
||||
|
||||
if ($arr['parent-uri'] === $arr['uri']) {
|
||||
add_thread($current_post);
|
||||
} else {
|
||||
update_thread($parent_id);
|
||||
}
|
||||
|
||||
q("COMMIT");
|
||||
|
||||
// Due to deadlock issues with the "term" table we are doing these steps after the commit.
|
||||
// This is not perfect - but a workable solution until we found the reason for the problem.
|
||||
create_tags_from_item($current_post);
|
||||
create_files_from_item($current_post);
|
||||
|
||||
// Only check for notifications on start posts
|
||||
if ($arr['parent-uri'] === $arr['uri'])
|
||||
add_thread($current_post);
|
||||
else {
|
||||
update_thread($parent_id);
|
||||
add_shadow_entry($arr);
|
||||
// If this is now the last-child, force all _other_ children of this parent to *not* be last-child
|
||||
// It is done after the transaction to avoid dead locks.
|
||||
if ($arr['last-child']) {
|
||||
$r = q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d AND `id` != %d",
|
||||
dbesc($arr['uri']),
|
||||
intval($arr['uid']),
|
||||
intval($current_post)
|
||||
);
|
||||
}
|
||||
|
||||
if ($arr['parent-uri'] === $arr['uri']) {
|
||||
add_shadow_thread($current_post);
|
||||
} else {
|
||||
add_shadow_entry($current_post);
|
||||
}
|
||||
|
||||
check_item_notification($current_post, $uid);
|
||||
|
||||
if ($notify)
|
||||
proc_run('php', "include/notifier.php", $notify_type, $current_post);
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", $notify_type, $current_post);
|
||||
|
||||
return $current_post;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set "success_update" and "last-item" to the date of the last time we heard from this contact
|
||||
*
|
||||
* This can be used to filter for inactive contacts.
|
||||
* Only do this for public postings to avoid privacy problems, since poco data is public.
|
||||
* Don't set this value if it isn't from the owner (could be an author that we don't know)
|
||||
*
|
||||
* @param array $arr Contains the just posted item record
|
||||
*/
|
||||
function item_set_last_item($arr) {
|
||||
|
||||
$update = (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"])));
|
||||
|
||||
// Is it a forum? Then we don't care about the rules from above
|
||||
if (!$update AND ($arr["network"] == NETWORK_DFRN) AND ($arr["parent-uri"] === $arr["uri"])) {
|
||||
$isforum = q("SELECT `forum` FROM `contact` WHERE `id` = %d AND `forum`",
|
||||
intval($arr['contact-id']));
|
||||
if ($isforum) {
|
||||
$update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($update) {
|
||||
q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
|
||||
dbesc($arr['received']),
|
||||
dbesc($arr['received']),
|
||||
intval($arr['contact-id'])
|
||||
);
|
||||
}
|
||||
// Now do the same for the system wide contacts with uid=0
|
||||
if (!$arr['private']) {
|
||||
q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
|
||||
dbesc($arr['received']),
|
||||
dbesc($arr['received']),
|
||||
intval($arr['owner-id'])
|
||||
);
|
||||
|
||||
if ($arr['owner-id'] != $arr['author-id']) {
|
||||
q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
|
||||
dbesc($arr['received']),
|
||||
dbesc($arr['received']),
|
||||
intval($arr['author-id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function item_body_set_hashtags(&$item) {
|
||||
|
||||
$tags = get_tags($item["body"]);
|
||||
|
@ -1150,7 +1227,7 @@ function tag_deliver($uid,$item_id) {
|
|||
);
|
||||
update_thread($item_id);
|
||||
|
||||
proc_run('php','include/notifier.php','tgroup',$item_id);
|
||||
proc_run(PRIORITY_HIGH,'include/notifier.php', 'tgroup', $item_id);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1399,15 +1476,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
|
|||
);
|
||||
if (count($r)) {
|
||||
$contact_record = $r[0];
|
||||
|
||||
$photos = import_profile_photo($photo,$importer["uid"],$contact_record["id"]);
|
||||
|
||||
q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `id` = %d",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
intval($contact_record["id"])
|
||||
);
|
||||
update_contact_avatar($photo, $importer["uid"], $contact_record["id"], true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1471,8 +1540,7 @@ function lose_follower($importer,$contact,$datarray = array(),$item = "") {
|
|||
intval(CONTACT_IS_SHARING),
|
||||
intval($contact['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
contact_remove($contact['id']);
|
||||
}
|
||||
}
|
||||
|
@ -1484,8 +1552,7 @@ function lose_sharer($importer,$contact,$datarray = array(),$item = "") {
|
|||
intval(CONTACT_IS_FOLLOWER),
|
||||
intval($contact['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
contact_remove($contact['id']);
|
||||
}
|
||||
}
|
||||
|
@ -1587,8 +1654,7 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) {
|
|||
if (in_array($cid, $recips)) {
|
||||
$replace = true;
|
||||
}
|
||||
}
|
||||
elseif($item) {
|
||||
} elseif ($item) {
|
||||
if (compare_permissions($item,$r[0]))
|
||||
$replace = true;
|
||||
}
|
||||
|
@ -1714,7 +1780,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
|
|||
} else
|
||||
$range = "AND `created` < UTC_TIMESTAMP() - INTERVAL %d DAY ";
|
||||
|
||||
$r = q("SELECT * FROM `item`
|
||||
$r = q("SELECT `file`, `resource-id`, `starred`, `type`, `id` FROM `item`
|
||||
WHERE `uid` = %d $range
|
||||
AND `id` = `parent`
|
||||
$sql_extra
|
||||
|
@ -1765,7 +1831,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
|
|||
drop_item($item['id'],false);
|
||||
}
|
||||
|
||||
proc_run('php',"include/notifier.php","expire","$uid");
|
||||
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1787,7 +1853,7 @@ function drop_items($items) {
|
|||
// multiple threads may have been deleted, send an expire notification
|
||||
|
||||
if ($uid)
|
||||
proc_run('php',"include/notifier.php","expire","$uid");
|
||||
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1976,8 +2042,7 @@ function drop_item($id,$interactive = true) {
|
|||
create_files_from_itemuri($item['parent-uri'], $item['uid']);
|
||||
delete_thread_uri($item['parent-uri'], $item['uid']);
|
||||
// ignore the result
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// ensure that last-child is set in case the comment that had it just got wiped.
|
||||
q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
|
||||
dbesc(datetime_convert()),
|
||||
|
@ -2000,14 +2065,13 @@ function drop_item($id,$interactive = true) {
|
|||
|
||||
// send the notification upstream/downstream as the case may be
|
||||
|
||||
proc_run('php',"include/notifier.php","drop","$drop_id");
|
||||
proc_run(PRIORITY_HIGH,"include/notifier.php", "drop", $drop_id);
|
||||
|
||||
if (! $interactive)
|
||||
return $owner;
|
||||
goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
|
||||
//NOTREACHED
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (! $interactive)
|
||||
return 0;
|
||||
notice( t('Permission denied.') . EOL);
|
||||
|
|
|
@ -153,7 +153,7 @@ function do_like($item_id, $verb) {
|
|||
);
|
||||
|
||||
$like_item_id = $like_item['id'];
|
||||
proc_run('php',"include/notifier.php","like","$like_item_id");
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $like_item_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ EOT;
|
|||
|
||||
call_hooks('post_local_end', $arr);
|
||||
|
||||
proc_run('php',"include/notifier.php","like","$post_id");
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
|
|||
}
|
||||
|
||||
if($post_id) {
|
||||
proc_run('php',"include/notifier.php","mail","$post_id");
|
||||
proc_run(PRIORITY_HIGH, "include/notifier.php", "mail", $post_id);
|
||||
return intval($post_id);
|
||||
} else {
|
||||
return -3;
|
||||
|
|
192
include/nav.php
192
include/nav.php
|
@ -43,181 +43,170 @@ function nav(&$a) {
|
|||
call_hooks('page_header', $a->page['nav']);
|
||||
}
|
||||
|
||||
|
||||
function nav_info(&$a) {
|
||||
|
||||
/**
|
||||
* @brief Prepares a list of navigation links
|
||||
*
|
||||
* @param App $a
|
||||
* @return array Navigation links
|
||||
* string 'sitelocation' => The webbie (username@site.com)
|
||||
* array 'nav' => Array of links used in the nav menu
|
||||
* string 'banner' => Formatted html link with banner image
|
||||
* array 'userinfo' => Array of user information (name, icon)
|
||||
*/
|
||||
function nav_info(App $a)
|
||||
{
|
||||
$ssl_state = ((local_user()) ? true : false);
|
||||
|
||||
/*
|
||||
*
|
||||
* Our network is distributed, and as you visit friends some of the
|
||||
* sites look exactly the same - it isn't always easy to know where you are.
|
||||
* Display the current site location as a navigation aid.
|
||||
*
|
||||
*/
|
||||
|
||||
$myident = ((is_array($a->user) && isset($a->user['nickname'])) ? $a->user['nickname'] . '@' : '');
|
||||
|
||||
$sitelocation = $myident . substr($a->get_baseurl($ssl_state), strpos($a->get_baseurl($ssl_state), '//') + 2 );
|
||||
|
||||
|
||||
// nav links: array of array('href', 'text', 'extra css classes', 'title')
|
||||
$nav = Array();
|
||||
|
||||
/*
|
||||
* Display login or logout
|
||||
*/
|
||||
$nav = array();
|
||||
|
||||
// Display login or logout
|
||||
$nav['usermenu'] = array();
|
||||
$userinfo = null;
|
||||
|
||||
if (local_user()) {
|
||||
$nav['logout'] = Array('logout',t('Logout'), "", t('End this session'));
|
||||
$nav['logout'] = array('logout', t('Logout'), '', t('End this session'));
|
||||
|
||||
// user menu
|
||||
$nav['usermenu'][] = Array('profile/' . $a->user['nickname'], t('Status'), "", t('Your posts and conversations'));
|
||||
$nav['usermenu'][] = Array('profile/' . $a->user['nickname']. '?tab=profile', t('Profile'), "", t('Your profile page'));
|
||||
$nav['usermenu'][] = Array('photos/' . $a->user['nickname'], t('Photos'), "", t('Your photos'));
|
||||
$nav['usermenu'][] = Array('videos/' . $a->user['nickname'], t('Videos'), "", t('Your videos'));
|
||||
$nav['usermenu'][] = Array('events/', t('Events'), "", t('Your events'));
|
||||
$nav['usermenu'][] = Array('notes/', t('Personal notes'), "", t('Your personal notes'));
|
||||
$nav['usermenu'][] = array('profile/' . $a->user['nickname'], t('Status'), '', t('Your posts and conversations'));
|
||||
$nav['usermenu'][] = array('profile/' . $a->user['nickname'] . '?tab=profile', t('Profile'), '', t('Your profile page'));
|
||||
$nav['usermenu'][] = array('photos/' . $a->user['nickname'], t('Photos'), '', t('Your photos'));
|
||||
$nav['usermenu'][] = array('videos/' . $a->user['nickname'], t('Videos'), '', t('Your videos'));
|
||||
$nav['usermenu'][] = array('events/', t('Events'), '', t('Your events'));
|
||||
$nav['usermenu'][] = array('notes/', t('Personal notes'), '', t('Your personal notes'));
|
||||
|
||||
// user info
|
||||
$r = q("SELECT micro FROM contact WHERE uid=%d AND self=1", intval($a->user['uid']));
|
||||
$r = q("SELECT `micro` FROM `contact` WHERE `uid` = %d AND `self` = 1", intval($a->user['uid']));
|
||||
$userinfo = array(
|
||||
'icon' => (count($r) ? $a->remove_baseurl($r[0]['micro']) : "images/person-48.jpg"),
|
||||
'icon' => (count($r) ? $a->remove_baseurl($r[0]['micro']) : 'images/person-48.jpg'),
|
||||
'name' => $a->user['username'],
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
$nav['login'] = Array('login',t('Login'), ($a->module == 'login'?'selected':''), t('Sign in'));
|
||||
} else {
|
||||
$nav['login'] = array('login', t('Login'), ($a->module == 'login' ? 'selected' : ''), t('Sign in'));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Home" should also take you home from an authenticated remote profile connection
|
||||
*/
|
||||
|
||||
// "Home" should also take you home from an authenticated remote profile connection
|
||||
$homelink = get_my_url();
|
||||
if(! $homelink)
|
||||
if (! $homelink) {
|
||||
$homelink = ((x($_SESSION,'visitor_home')) ? $_SESSION['visitor_home'] : '');
|
||||
}
|
||||
|
||||
if(($a->module != 'home') && (! (local_user())))
|
||||
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'));
|
||||
if (($a->module != 'home') && (! (local_user()))) {
|
||||
$nav['home'] = array($homelink, t('Home'), '', t('Home Page'));
|
||||
}
|
||||
|
||||
|
||||
if(($a->config['register_policy'] == REGISTER_OPEN) && (! local_user()) && (! remote_user()))
|
||||
$nav['register'] = array('register',t('Register'), "", t('Create an account'));
|
||||
if (($a->config['register_policy'] == REGISTER_OPEN) && (! local_user()) && (! remote_user())) {
|
||||
$nav['register'] = array('register', t('Register'), '', t('Create an account'));
|
||||
}
|
||||
|
||||
$help_url = 'help';
|
||||
|
||||
if(! get_config('system','hide_help'))
|
||||
$nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'));
|
||||
if (! get_config('system', 'hide_help')) {
|
||||
$nav['help'] = array($help_url, t('Help'), '', t('Help and documentation'));
|
||||
}
|
||||
|
||||
if(count($a->apps)>0)
|
||||
$nav['apps'] = array('apps', t('Apps'), "", t('Addon applications, utilities, games'));
|
||||
if (count($a->apps) > 0) {
|
||||
$nav['apps'] = array('apps', t('Apps'), '', t('Addon applications, utilities, games'));
|
||||
}
|
||||
|
||||
if (local_user() OR !get_config('system', 'local_search')) {
|
||||
$nav['search'] = array('search', t('Search'), "", t('Search site content'));
|
||||
$nav['search'] = array('search', t('Search'), '', t('Search site content'));
|
||||
|
||||
$nav['searchoption'] = array(
|
||||
t("Full Text"),
|
||||
t("Tags"),
|
||||
t("Contacts"));
|
||||
t('Full Text'),
|
||||
t('Tags'),
|
||||
t('Contacts'));
|
||||
|
||||
if (get_config('system','poco_local_search'))
|
||||
$nav['searchoption'][] = t("Forums");
|
||||
if (get_config('system', 'poco_local_search')) {
|
||||
$nav['searchoption'][] = t('Forums');
|
||||
}
|
||||
}
|
||||
|
||||
$gdirpath = 'directory';
|
||||
|
||||
if (strlen(get_config('system', 'singleuser'))) {
|
||||
$gdir = get_config('system', 'directory');
|
||||
if(strlen($gdir))
|
||||
$gdirpath = $gdir;
|
||||
if(strlen($gdir)) {
|
||||
$gdirpath = zrl($gdir, true);
|
||||
}
|
||||
} elseif (get_config('system', 'community_page_style') == CP_USERS_ON_SERVER) {
|
||||
$nav['community'] = array('community', t('Community'), '', t('Conversations on this site'));
|
||||
} elseif (get_config('system', 'community_page_style') == CP_GLOBAL_COMMUNITY) {
|
||||
$nav['community'] = array('community', t('Community'), '', t('Conversations on the network'));
|
||||
}
|
||||
elseif(get_config('system','community_page_style') == CP_USERS_ON_SERVER)
|
||||
$nav['community'] = array('community', t('Community'), "", t('Conversations on this site'));
|
||||
elseif(get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
|
||||
$nav['community'] = array('community', t('Community'), "", t('Conversations on the network'));
|
||||
|
||||
if(local_user())
|
||||
$nav['events'] = Array('events', t('Events'), "", t('Events and Calendar'));
|
||||
|
||||
$nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory'));
|
||||
|
||||
$nav['about'] = Array('friendica', t('Information'), "", t('Information about this friendica instance'));
|
||||
|
||||
/*
|
||||
*
|
||||
* The following nav links are only show to logged in users
|
||||
*
|
||||
*/
|
||||
|
||||
if (local_user()) {
|
||||
$nav['events'] = array('events', t('Events'), '', t('Events and Calendar'));
|
||||
}
|
||||
|
||||
$nav['network'] = array('network', t('Network'), "", t('Conversations from your friends'));
|
||||
$nav['net_reset'] = array('network/0?f=&order=comment&nets=all', t('Network Reset'), "", t('Load Network page with no filters'));
|
||||
$nav['directory'] = array($gdirpath, t('Directory'), '', t('People directory'));
|
||||
|
||||
$nav['home'] = array('profile/' . $a->user['nickname'], t('Home'), "", t('Your posts and conversations'));
|
||||
$nav['about'] = array('friendica', t('Information'), '', t('Information about this friendica instance'));
|
||||
|
||||
// The following nav links are only show to logged in users
|
||||
if (local_user()) {
|
||||
$nav['network'] = array('network', t('Network'), '', t('Conversations from your friends'));
|
||||
$nav['net_reset'] = array('network/0?f=&order=comment&nets=all', t('Network Reset'), '', t('Load Network page with no filters'));
|
||||
|
||||
$nav['home'] = array('profile/' . $a->user['nickname'], t('Home'), '', t('Your posts and conversations'));
|
||||
|
||||
if (in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE, PAGE_PRVGROUP))) {
|
||||
/* only show friend requests for normal pages. Other page types have automatic friendship. */
|
||||
if(in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_PRVGROUP)))
|
||||
$nav['introductions'] = array('notifications/intros', t('Introductions'), "", t('Friend Requests'));
|
||||
|
||||
// only show friend requests for normal pages. Other page types have automatic friendship.
|
||||
if (in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_PRVGROUP))) {
|
||||
$nav['introductions'] = array('notifications/intros', t('Introductions'), '', t('Friend Requests'));
|
||||
}
|
||||
if (in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) {
|
||||
$nav['notifications'] = array('notifications', t('Notifications'), "", t('Notifications'));
|
||||
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
|
||||
$nav['notifications'] = array('notifications', t('Notifications'), '', t('Notifications'));
|
||||
$nav['notifications']['all'] = array('notifications/system', t('See all notifications'), '', '');
|
||||
$nav['notifications']['mark'] = array('', t('Mark as seen'), '', t('Mark all system notifications seen'));
|
||||
}
|
||||
}
|
||||
|
||||
$nav['messages'] = array('message', t('Messages'), "", t('Private mail'));
|
||||
$nav['messages']['inbox'] = array('message', t('Inbox'), "", t('Inbox'));
|
||||
$nav['messages']['outbox']= array('message/sent', t('Outbox'), "", t('Outbox'));
|
||||
$nav['messages']['new'] = array('message/new', t('New Message'), "", t('New Message'));
|
||||
$nav['messages'] = array('message', t('Messages'), '', t('Private mail'));
|
||||
$nav['messages']['inbox'] = array('message', t('Inbox'), '', t('Inbox'));
|
||||
$nav['messages']['outbox'] = array('message/sent', t('Outbox'), '', t('Outbox'));
|
||||
$nav['messages']['new'] = array('message/new', t('New Message'), '', t('New Message'));
|
||||
|
||||
if (is_array($a->identities) && count($a->identities) > 1) {
|
||||
$nav['manage'] = array('manage', t('Manage'), "", t('Manage other pages'));
|
||||
$nav['manage'] = array('manage', t('Manage'), '', t('Manage other pages'));
|
||||
}
|
||||
|
||||
$nav['delegations'] = Array('delegate', t('Delegations'), "", t('Delegate Page Management'));
|
||||
$nav['delegations'] = array('delegate', t('Delegations'), '', t('Delegate Page Management'));
|
||||
|
||||
$nav['settings'] = array('settings', t('Settings'),"", t('Account settings'));
|
||||
$nav['settings'] = array('settings', t('Settings'), '', t('Account settings'));
|
||||
|
||||
if(feature_enabled(local_user(),'multi_profiles'))
|
||||
$nav['profiles'] = array('profiles', t('Profiles'),"", t('Manage/Edit Profiles'));
|
||||
|
||||
$nav['contacts'] = array('contacts', t('Contacts'),"", t('Manage/edit friends and contacts'));
|
||||
if (feature_enabled(local_user(), 'multi_profiles')) {
|
||||
$nav['profiles'] = array('profiles', t('Profiles'), '', t('Manage/Edit Profiles'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Admin page
|
||||
*/
|
||||
$nav['contacts'] = array('contacts', t('Contacts'), '', t('Manage/edit friends and contacts'));
|
||||
}
|
||||
|
||||
// Show the link to the admin configuration page if user is admin
|
||||
if (is_site_admin()) {
|
||||
$nav['admin'] = array('admin/', t('Admin'), "", t('Site setup and configuration'));
|
||||
$nav['admin'] = array('admin/', t('Admin'), '', t('Site setup and configuration'));
|
||||
}
|
||||
|
||||
$nav['navigation'] = array('navigation/', t('Navigation'), '', t('Site map'));
|
||||
|
||||
$nav['navigation'] = array('navigation/', t('Navigation'), "", t('Site map'));
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Provide a banner/logo/whatever
|
||||
*
|
||||
*/
|
||||
|
||||
// Provide a banner/logo/whatever
|
||||
$banner = get_config('system', 'banner');
|
||||
|
||||
if($banner === false)
|
||||
$banner .= '<a href="http://friendica.com"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="http://friendica.com">Friendica</a></span>';
|
||||
if ($banner === false) {
|
||||
$banner = '<a href="http://friendica.com"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="http://friendica.com">Friendica</a></span>';
|
||||
}
|
||||
|
||||
call_hooks('nav_info', $nav);
|
||||
|
||||
|
||||
return array(
|
||||
'sitelocation' => $sitelocation,
|
||||
'nav' => $nav,
|
||||
|
@ -226,7 +215,6 @@ function nav_info(&$a) {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a menu item in navbar as selected
|
||||
*
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
require_once("include/xml.php");
|
||||
|
||||
require_once('include/Probe.php');
|
||||
|
||||
/**
|
||||
* @brief Curl wrapper
|
||||
|
@ -371,324 +371,6 @@ function http_status_exit($val, $description = array()) {
|
|||
|
||||
}
|
||||
|
||||
// Given an email style address, perform webfinger lookup and
|
||||
// return the resulting DFRN profile URL, or if no DFRN profile URL
|
||||
// is located, returns an OStatus subscription template (prefixed
|
||||
// with the string 'stat:' to identify it as on OStatus template).
|
||||
// If this isn't an email style address just return $webbie.
|
||||
// Return an empty string if email-style addresses but webfinger fails,
|
||||
// or if the resultant personal XRD doesn't contain a supported
|
||||
// subscription/friend-request attribute.
|
||||
|
||||
// amended 7/9/2011 to return an hcard which could save potentially loading
|
||||
// a lengthy content page to scrape dfrn attributes
|
||||
|
||||
function webfinger_dfrn($webbie,&$hcard) {
|
||||
if(! strstr($webbie,'@')) {
|
||||
return $webbie;
|
||||
}
|
||||
$profile_link = '';
|
||||
|
||||
$links = webfinger($webbie);
|
||||
logger('webfinger_dfrn: ' . $webbie . ':' . print_r($links,true), LOGGER_DATA);
|
||||
if(count($links)) {
|
||||
foreach($links as $link) {
|
||||
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
|
||||
$profile_link = $link['@attributes']['href'];
|
||||
if($link['@attributes']['rel'] === NAMESPACE_OSTATUSSUB)
|
||||
$profile_link = 'stat:' . $link['@attributes']['template'];
|
||||
if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
|
||||
$hcard = $link['@attributes']['href'];
|
||||
}
|
||||
}
|
||||
return $profile_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform webfinger lookup on an email style address
|
||||
*
|
||||
* @param string $webbi An email style address
|
||||
* @param boolean $debug
|
||||
*
|
||||
* @return array of link attributes from the personal XRD file
|
||||
* empty array on error/failure
|
||||
*/
|
||||
function webfinger($webbie, $debug = false) {
|
||||
$host = '';
|
||||
if(strstr($webbie,'@')) {
|
||||
$host = substr($webbie,strpos($webbie,'@') + 1);
|
||||
}
|
||||
if(strlen($host)) {
|
||||
$tpl = fetch_lrdd_template($host);
|
||||
logger('webfinger: lrdd template: ' . $tpl);
|
||||
if(strlen($tpl)) {
|
||||
$pxrd = str_replace('{uri}', urlencode('acct:' . $webbie), $tpl);
|
||||
logger('webfinger: pxrd: ' . $pxrd);
|
||||
$links = fetch_xrd_links($pxrd);
|
||||
if(! count($links)) {
|
||||
// try with double slashes
|
||||
$pxrd = str_replace('{uri}', urlencode('acct://' . $webbie), $tpl);
|
||||
logger('webfinger: pxrd: ' . $pxrd);
|
||||
$links = fetch_xrd_links($pxrd);
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
function lrdd($uri, $debug = false) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
// default priority is host priority, host-meta first
|
||||
|
||||
$priority = 'host';
|
||||
|
||||
// All we have is an email address. Resource-priority is irrelevant
|
||||
// because our URI isn't directly resolvable.
|
||||
|
||||
if(strstr($uri,'@')) {
|
||||
return(webfinger($uri));
|
||||
}
|
||||
|
||||
// get the host meta file
|
||||
|
||||
$host = @parse_url($uri);
|
||||
|
||||
if($host) {
|
||||
$url = ((x($host,'scheme')) ? $host['scheme'] : 'http') . '://';
|
||||
$url .= $host['host'] . '/.well-known/host-meta' ;
|
||||
}
|
||||
else
|
||||
return array();
|
||||
|
||||
logger('lrdd: constructed url: ' . $url);
|
||||
|
||||
$xml = fetch_url($url);
|
||||
|
||||
$headers = $a->get_curl_headers();
|
||||
|
||||
if (! $xml)
|
||||
return array();
|
||||
|
||||
logger('lrdd: host_meta: ' . $xml, LOGGER_DATA);
|
||||
|
||||
if(! stristr($xml,'<xrd'))
|
||||
return array();
|
||||
|
||||
$h = parse_xml_string($xml);
|
||||
if(! $h)
|
||||
return array();
|
||||
|
||||
$arr = xml::element_to_array($h);
|
||||
|
||||
if(isset($arr['xrd']['property'])) {
|
||||
$property = $arr['crd']['property'];
|
||||
if(! isset($property[0]))
|
||||
$properties = array($property);
|
||||
else
|
||||
$properties = $property;
|
||||
foreach($properties as $prop)
|
||||
if((string) $prop['@attributes'] === 'http://lrdd.net/priority/resource')
|
||||
$priority = 'resource';
|
||||
}
|
||||
|
||||
// save the links in case we need them
|
||||
|
||||
$links = array();
|
||||
|
||||
if(isset($arr['xrd']['link'])) {
|
||||
$link = $arr['xrd']['link'];
|
||||
if(! isset($link[0]))
|
||||
$links = array($link);
|
||||
else
|
||||
$links = $link;
|
||||
}
|
||||
|
||||
// do we have a template or href?
|
||||
|
||||
if(count($links)) {
|
||||
foreach($links as $link) {
|
||||
if($link['@attributes']['rel'] && attribute_contains($link['@attributes']['rel'],'lrdd')) {
|
||||
if(x($link['@attributes'],'template'))
|
||||
$tpl = $link['@attributes']['template'];
|
||||
elseif(x($link['@attributes'],'href'))
|
||||
$href = $link['@attributes']['href'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((! isset($tpl)) || (! strpos($tpl,'{uri}')))
|
||||
$tpl = '';
|
||||
|
||||
if($priority === 'host') {
|
||||
if(strlen($tpl))
|
||||
$pxrd = str_replace('{uri}', urlencode($uri), $tpl);
|
||||
elseif(isset($href))
|
||||
$pxrd = $href;
|
||||
if(isset($pxrd)) {
|
||||
logger('lrdd: (host priority) pxrd: ' . $pxrd);
|
||||
$links = fetch_xrd_links($pxrd);
|
||||
return $links;
|
||||
}
|
||||
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
if((stristr($line,'link:')) && preg_match('/<([^>].*)>.*rel\=[\'\"]lrdd[\'\"]/',$line,$matches)) {
|
||||
return(fetch_xrd_links($matches[1]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// priority 'resource'
|
||||
|
||||
|
||||
$html = fetch_url($uri);
|
||||
$headers = $a->get_curl_headers();
|
||||
logger('lrdd: headers=' . $headers, LOGGER_DEBUG);
|
||||
|
||||
// don't try and parse raw xml as html
|
||||
if(! strstr($html,'<?xml')) {
|
||||
require_once('library/HTML5/Parser.php');
|
||||
|
||||
try {
|
||||
$dom = HTML5_Parser::parse($html);
|
||||
} catch (DOMException $e) {
|
||||
logger('lrdd: parse error: ' . $e);
|
||||
}
|
||||
|
||||
if(isset($dom) && $dom) {
|
||||
$items = $dom->getElementsByTagName('link');
|
||||
foreach($items as $item) {
|
||||
$x = $item->getAttribute('rel');
|
||||
if($x == "lrdd") {
|
||||
$pagelink = $item->getAttribute('href');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($pagelink))
|
||||
return(fetch_xrd_links($pagelink));
|
||||
|
||||
// next look in HTTP headers
|
||||
|
||||
$lines = explode("\n",$headers);
|
||||
if(count($lines)) {
|
||||
foreach($lines as $line) {
|
||||
/// @TODO Alter the following regex to support multiple relations (space separated)
|
||||
if((stristr($line,'link:')) && preg_match('/<([^>].*)>.*rel\=[\'\"]lrdd[\'\"]/',$line,$matches)) {
|
||||
$pagelink = $matches[1];
|
||||
break;
|
||||
}
|
||||
// don't try and run feeds through the html5 parser
|
||||
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
|
||||
return array();
|
||||
if(stristr($html,'<rss') || stristr($html,'<feed'))
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($pagelink))
|
||||
return(fetch_xrd_links($pagelink));
|
||||
|
||||
// If we haven't found any links, return the host xrd links (which we have already fetched)
|
||||
|
||||
if(isset($links))
|
||||
return $links;
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
// Given a host name, locate the LRDD template from that
|
||||
// host. Returns the LRDD template or an empty string on
|
||||
// error/failure.
|
||||
|
||||
function fetch_lrdd_template($host) {
|
||||
$tpl = '';
|
||||
|
||||
$url1 = 'https://' . $host . '/.well-known/host-meta' ;
|
||||
$url2 = 'http://' . $host . '/.well-known/host-meta' ;
|
||||
$links = fetch_xrd_links($url1);
|
||||
logger('fetch_lrdd_template from: ' . $url1);
|
||||
logger('template (https): ' . print_r($links,true));
|
||||
if(! count($links)) {
|
||||
logger('fetch_lrdd_template from: ' . $url2);
|
||||
$links = fetch_xrd_links($url2);
|
||||
logger('template (http): ' . print_r($links,true));
|
||||
}
|
||||
if(count($links)) {
|
||||
foreach($links as $link)
|
||||
if($link['@attributes']['rel'] && $link['@attributes']['rel'] === 'lrdd' && (!$link['@attributes']['type'] || $link['@attributes']['type'] === 'application/xrd+xml'))
|
||||
$tpl = $link['@attributes']['template'];
|
||||
}
|
||||
if(! strpos($tpl,'{uri}'))
|
||||
$tpl = '';
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given a URL, retrieve the page as an XRD document.
|
||||
*
|
||||
* @param string $url An url
|
||||
* @return array of links
|
||||
* return empty array on error/failure
|
||||
*/
|
||||
function fetch_xrd_links($url) {
|
||||
|
||||
$xrd_timeout = intval(get_config('system','xrd_timeout'));
|
||||
$redirects = 0;
|
||||
$xml = fetch_url($url,false,$redirects,(($xrd_timeout) ? $xrd_timeout : 20), "application/xrd+xml");
|
||||
|
||||
logger('fetch_xrd_links: ' . $xml, LOGGER_DATA);
|
||||
|
||||
if ((! $xml) || (! stristr($xml,'<xrd')))
|
||||
return array();
|
||||
|
||||
// fix diaspora's bad xml
|
||||
$xml = str_replace(array('href="','"/>'),array('href="','"/>'),$xml);
|
||||
|
||||
$h = parse_xml_string($xml);
|
||||
if(! $h)
|
||||
return array();
|
||||
|
||||
$arr = xml::element_to_array($h);
|
||||
|
||||
$links = array();
|
||||
|
||||
if(isset($arr['xrd']['link'])) {
|
||||
$link = $arr['xrd']['link'];
|
||||
if(! isset($link[0]))
|
||||
$links = array($link);
|
||||
else
|
||||
$links = $link;
|
||||
}
|
||||
if(isset($arr['xrd']['alias'])) {
|
||||
$alias = $arr['xrd']['alias'];
|
||||
if(! isset($alias[0]))
|
||||
$aliases = array($alias);
|
||||
else
|
||||
$aliases = $alias;
|
||||
if(is_array($aliases) && count($aliases)) {
|
||||
foreach($aliases as $alias) {
|
||||
$links[]['@attributes'] = array('rel' => 'alias' , 'href' => $alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger('fetch_xrd_links: ' . print_r($links,true), LOGGER_DATA);
|
||||
|
||||
return $links;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check URL to se if ts's real
|
||||
*
|
||||
|
@ -1131,3 +813,57 @@ function json_return_and_die($x) {
|
|||
echo json_encode($x);
|
||||
killme();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the matching part between two url
|
||||
*
|
||||
* @param string $url1
|
||||
* @param string $url2
|
||||
* @return string The matching part
|
||||
*/
|
||||
function matching_url($url1, $url2) {
|
||||
|
||||
if (($url1 == "") OR ($url2 == ""))
|
||||
return "";
|
||||
|
||||
$url1 = normalise_link($url1);
|
||||
$url2 = normalise_link($url2);
|
||||
|
||||
$parts1 = parse_url($url1);
|
||||
$parts2 = parse_url($url2);
|
||||
|
||||
if (!isset($parts1["host"]) OR !isset($parts2["host"]))
|
||||
return "";
|
||||
|
||||
if ($parts1["scheme"] != $parts2["scheme"])
|
||||
return "";
|
||||
|
||||
if ($parts1["host"] != $parts2["host"])
|
||||
return "";
|
||||
|
||||
if ($parts1["port"] != $parts2["port"])
|
||||
return "";
|
||||
|
||||
$match = $parts1["scheme"]."://".$parts1["host"];
|
||||
|
||||
if ($parts1["port"])
|
||||
$match .= ":".$parts1["port"];
|
||||
|
||||
$pathparts1 = explode("/", $parts1["path"]);
|
||||
$pathparts2 = explode("/", $parts2["path"]);
|
||||
|
||||
$i = 0;
|
||||
$path = "";
|
||||
do {
|
||||
$path1 = $pathparts1[$i];
|
||||
$path2 = $pathparts2[$i];
|
||||
|
||||
if ($path1 == $path2)
|
||||
$path .= $path1."/";
|
||||
|
||||
} while (($path1 == $path2) AND ($i++ <= count($pathparts1)));
|
||||
|
||||
$match .= $path;
|
||||
|
||||
return normalise_link($match);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ require_once('include/salmon.php');
|
|||
/*
|
||||
* The notifier is typically called with:
|
||||
*
|
||||
* proc_run('php', "include/notifier.php", COMMAND, ITEM_ID);
|
||||
* proc_run(PRIORITY_HIGH, "include/notifier.php", COMMAND, ITEM_ID);
|
||||
*
|
||||
* where COMMAND is one of the following:
|
||||
*
|
||||
|
@ -132,17 +132,24 @@ function notifier_run(&$argv, &$argc){
|
|||
$recipients[] = $suggest[0]['cid'];
|
||||
$item = $suggest[0];
|
||||
} elseif($cmd === 'removeme') {
|
||||
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($item_id));
|
||||
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
|
||||
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
|
||||
`user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`, `user`.`guid`
|
||||
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `contact`.`uid` = %d AND `contact`.`self` LIMIT 1",
|
||||
intval($item_id));
|
||||
if (!$r)
|
||||
return;
|
||||
|
||||
$user = $r[0];
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($item_id));
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($item_id));
|
||||
if (!$r)
|
||||
return;
|
||||
|
||||
$self = $r[0];
|
||||
$r = q("SELECT * FROM `contact` WHERE `self` = 0 AND `uid` = %d", intval($item_id));
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE NOT `self` AND `uid` = %d", intval($item_id));
|
||||
if(!$r)
|
||||
return;
|
||||
|
||||
|
@ -197,7 +204,7 @@ function notifier_run(&$argv, &$argc){
|
|||
|
||||
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
|
||||
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
|
||||
`user`.`page-flags`, `user`.`prvnets`
|
||||
`user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`
|
||||
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
|
||||
intval($uid)
|
||||
|
@ -348,7 +355,7 @@ function notifier_run(&$argv, &$argc){
|
|||
// a delivery fork. private groups (forum_mode == 2) do not uplink
|
||||
|
||||
if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
|
||||
proc_run('php','include/notifier.php','uplink',$item_id);
|
||||
proc_run(PRIORITY_HIGH,'include/notifier.php','uplink',$item_id);
|
||||
}
|
||||
|
||||
$conversants = array();
|
||||
|
@ -388,16 +395,29 @@ function notifier_run(&$argv, &$argc){
|
|||
// We have not only to look at the parent, since it could be a Friendica thread.
|
||||
if (($thr_parent AND ($thr_parent[0]['network'] == NETWORK_OSTATUS)) OR ($parent['network'] == NETWORK_OSTATUS)) {
|
||||
|
||||
logger('Some parent is OStatus for '.$target_item["guid"], LOGGER_DEBUG);
|
||||
logger('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent[0]['author-link']." - Owner: ".$thr_parent[0]['owner-link'], LOGGER_DEBUG);
|
||||
|
||||
// Send a salmon to the parent author
|
||||
$r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
|
||||
dbesc(normalise_link($thr_parent[0]['author-link'])),
|
||||
intval($uid));
|
||||
if ($r)
|
||||
$probed_contact = $r[0];
|
||||
else
|
||||
$probed_contact = probe_url($thr_parent[0]['author-link']);
|
||||
|
||||
if ($probed_contact["notify"] != "") {
|
||||
logger('Notify parent author '.$probed_contact["url"].': '.$probed_contact["notify"]);
|
||||
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
|
||||
}
|
||||
|
||||
// Send a salmon to the parent owner
|
||||
$r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
|
||||
dbesc(normalise_link($thr_parent[0]['owner-link'])),
|
||||
intval($uid));
|
||||
if ($r)
|
||||
$probed_contact = $r[0];
|
||||
else
|
||||
$probed_contact = probe_url($thr_parent[0]['owner-link']);
|
||||
if ($probed_contact["notify"] != "") {
|
||||
logger('Notify parent owner '.$probed_contact["url"].': '.$probed_contact["notify"]);
|
||||
|
@ -518,7 +538,7 @@ function notifier_run(&$argv, &$argc){
|
|||
$this_batch[] = $contact['id'];
|
||||
|
||||
if(count($this_batch) >= $deliveries_per_process) {
|
||||
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
|
||||
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
|
||||
$this_batch = array();
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
|
@ -528,7 +548,7 @@ function notifier_run(&$argv, &$argc){
|
|||
|
||||
// be sure to pick up any stragglers
|
||||
if(count($this_batch))
|
||||
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
|
||||
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
|
||||
}
|
||||
|
||||
// send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
|
||||
|
@ -579,10 +599,10 @@ function notifier_run(&$argv, &$argc){
|
|||
|
||||
foreach($r as $rr) {
|
||||
if((! $mail) && (! $fsuggest) && (! $followup)) {
|
||||
q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )",
|
||||
dbesc($cmd),
|
||||
intval($item_id),
|
||||
intval($rr['id'])
|
||||
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'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -599,7 +619,7 @@ function notifier_run(&$argv, &$argc){
|
|||
|
||||
if((! $mail) && (! $fsuggest) && (! $followup)) {
|
||||
logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
|
||||
proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']);
|
||||
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$rr['id']);
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
|
@ -623,7 +643,7 @@ function notifier_run(&$argv, &$argc){
|
|||
// Set push flag for PuSH subscribers to this topic,
|
||||
// they will be notified in queue.php
|
||||
q("UPDATE `push_subscriber` SET `push` = 1 ".
|
||||
"WHERE `nickname` = '%s'", dbesc($owner['nickname']));
|
||||
"WHERE `nickname` = '%s' AND `push` = 0", dbesc($owner['nickname']));
|
||||
|
||||
logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
|
||||
|
||||
|
@ -639,7 +659,7 @@ function notifier_run(&$argv, &$argc){
|
|||
}
|
||||
|
||||
// Handling the pubsubhubbub requests
|
||||
proc_run('php','include/pubsubpublish.php');
|
||||
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
|
||||
}
|
||||
|
||||
logger('notifier: calling hooks', LOGGER_DEBUG);
|
||||
|
|
|
@ -6,7 +6,15 @@ function oembed_replacecb($matches){
|
|||
return $s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
function oembed_fetch_url($embedurl, $no_rich_type = false){
|
||||
$embedurl = trim($embedurl, "'");
|
||||
$embedurl = trim($embedurl, '"');
|
||||
|
@ -16,11 +24,11 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
|
|||
$r = q("SELECT * FROM `oembed` WHERE `url` = '%s'",
|
||||
dbesc(normalise_link($embedurl)));
|
||||
|
||||
if ($r)
|
||||
if (dbm::is_result($r)) {
|
||||
$txt = $r[0]["content"];
|
||||
else
|
||||
} else {
|
||||
$txt = Cache::get($a->videowidth . $embedurl);
|
||||
|
||||
}
|
||||
// These media files should now be caught in bbcode.php
|
||||
// left here as a fallback in case this is called from another source
|
||||
|
||||
|
@ -34,7 +42,7 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
|
|||
if (!in_array($ext, $noexts)){
|
||||
// try oembed autodiscovery
|
||||
$redirects = 0;
|
||||
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*"); /**/
|
||||
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*");
|
||||
if ($html_text) {
|
||||
$dom = @DOMDocument::loadHTML($html_text);
|
||||
if ($dom) {
|
||||
|
@ -70,16 +78,17 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
|
|||
|
||||
$txt=trim($txt);
|
||||
|
||||
if ($txt[0]!="{")
|
||||
if ($txt[0]!="{") {
|
||||
$txt='{"type":"error"}';
|
||||
else { //save in cache
|
||||
} else { //save in cache
|
||||
$j = json_decode($txt);
|
||||
if ($j->type != "error")
|
||||
if ($j->type != "error") {
|
||||
q("INSERT INTO `oembed` (`url`, `content`, `created`) VALUES ('%s', '%s', '%s')
|
||||
ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'",
|
||||
dbesc(normalise_link($embedurl)),
|
||||
dbesc($txt), dbesc(datetime_convert()),
|
||||
dbesc($txt), dbesc(datetime_convert()));
|
||||
}
|
||||
|
||||
Cache::set($a->videowidth.$embedurl, $txt, CACHE_DAY);
|
||||
}
|
||||
|
@ -87,13 +96,15 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
|
|||
|
||||
$j = json_decode($txt);
|
||||
|
||||
if (!is_object($j))
|
||||
if (!is_object($j)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always embed the SSL version
|
||||
if (isset($j->html))
|
||||
if (isset($j->html)) {
|
||||
$j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
|
||||
array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html);
|
||||
}
|
||||
|
||||
$j->embedurl = $embedurl;
|
||||
|
||||
|
@ -109,11 +120,13 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
|
|||
//$j->height = $data["images"][0]["height"];
|
||||
}
|
||||
|
||||
if (isset($data["title"]))
|
||||
if (isset($data["title"])) {
|
||||
$j->title = $data["title"];
|
||||
}
|
||||
|
||||
if (isset($data["text"]))
|
||||
if (isset($data["text"])) {
|
||||
$j->description = $data["text"];
|
||||
}
|
||||
|
||||
if (is_array($data["images"])) {
|
||||
$j->thumbnail_url = $data["images"][0]["src"];
|
||||
|
@ -209,25 +222,34 @@ function oembed_format_object($j){
|
|||
return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generates the iframe HTML for an oembed attachment.
|
||||
*
|
||||
* Width and height are given by the remote, and are regularly too small for
|
||||
* the generated iframe.
|
||||
*
|
||||
* The width is entirely discarded for the actual width of the post, while fixed
|
||||
* height is used as a starting point before the inevitable resizing.
|
||||
*
|
||||
* Since the iframe is automatically resized on load, there are no need for ugly
|
||||
* and impractical scrollbars.
|
||||
*
|
||||
* @param string $src Original remote URL to embed
|
||||
* @param string $width
|
||||
* @param string $height
|
||||
* @return string formatted HTML
|
||||
*
|
||||
* @see oembed_format_object()
|
||||
*/
|
||||
function oembed_iframe($src, $width, $height) {
|
||||
|
||||
if(! $width || strstr($width,'%'))
|
||||
$width = '640';
|
||||
if (!$height || strstr($height,'%')) {
|
||||
$height = '300';
|
||||
$resize = 'onload="resizeIframe(this);"';
|
||||
} else
|
||||
$resize = '';
|
||||
|
||||
// try and leave some room for the description line.
|
||||
$height = intval($height) + 80;
|
||||
$width = intval($width) + 40;
|
||||
$height = '200';
|
||||
}
|
||||
$width = '100%';
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$s = $a->get_baseurl()."/oembed/".base64url_encode($src);
|
||||
return '<iframe '.$resize.' class="embed_rich" height="'.$height.'" width="'.$width.'" src="'.$s.'" frameborder="no">'.t('Embedded content').'</iframe>';
|
||||
|
||||
$s = $a->get_baseurl() . '/oembed/'.base64url_encode($src);
|
||||
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $s . '" scrolling="no" frameborder="no">' . t('Embedded content') . '</iframe>';
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ function onepoll_run(&$argv, &$argc){
|
|||
unset($db_host, $db_user, $db_pass, $db_data);
|
||||
};
|
||||
|
||||
|
||||
require_once('include/session.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/items.php');
|
||||
|
@ -444,7 +443,7 @@ function onepoll_run(&$argv, &$argc){
|
|||
$refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
|
||||
}
|
||||
$qstr = implode(',',$refs_arr);
|
||||
$r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
|
||||
$r = q("SELECT `uri` , `parent-uri` FROM `item` USE INDEX (`uid_uri`) WHERE `uri` IN ($qstr) AND `uid` = %d LIMIT 1",
|
||||
intval($importer_uid)
|
||||
);
|
||||
if(count($r))
|
||||
|
|
|
@ -806,11 +806,20 @@ class ostatus {
|
|||
}
|
||||
|
||||
// Get the parent
|
||||
$parents = q("SELECT `item`.`id`, `item`.`parent`, `item`.`uri`, `item`.`contact-id`, `item`.`type`,
|
||||
`item`.`verb`, `item`.`visible` FROM `term`
|
||||
STRAIGHT_JOIN `item` AS `thritem` ON `thritem`.`parent` = `term`.`oid`
|
||||
STRAIGHT_JOIN `item` ON `item`.`parent` = `thritem`.`parent`
|
||||
WHERE `term`.`uid` = %d AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`url` = '%s'",
|
||||
intval($uid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION), dbesc($conversation_url));
|
||||
|
||||
/* 2016-10-23: The old query will be kept until we are sure that the query above is a good and fast replacement
|
||||
|
||||
$parents = q("SELECT `id`, `parent`, `uri`, `contact-id`, `type`, `verb`, `visible` FROM `item` WHERE `id` IN
|
||||
(SELECT `parent` FROM `item` WHERE `id` IN
|
||||
(SELECT `oid` FROM `term` WHERE `uid` = %d AND `otype` = %d AND `type` = %d AND `url` = '%s'))",
|
||||
intval($uid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION), dbesc($conversation_url));
|
||||
|
||||
*/
|
||||
if ($parents)
|
||||
$parent = $parents[0];
|
||||
elseif (count($item) > 0) {
|
||||
|
@ -1961,9 +1970,23 @@ class ostatus {
|
|||
$last_update = 'now -30 days';
|
||||
|
||||
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
|
||||
$authorid = get_contact($owner["url"], 0);
|
||||
|
||||
$items = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id` FROM `item`
|
||||
INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item` USE INDEX (`uid_contactid_created`)
|
||||
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||
WHERE `item`.`uid` = %d AND `item`.`contact-id` = %d AND
|
||||
`item`.`author-id` = %d AND `item`.`created` > '%s' AND
|
||||
NOT `item`.`deleted` AND NOT `item`.`private` AND
|
||||
`thread`.`network` IN ('%s', '%s')
|
||||
ORDER BY `item`.`created` DESC LIMIT 300",
|
||||
intval($owner["uid"]), intval($owner["id"]),
|
||||
intval($authorid), dbesc($check_date),
|
||||
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DFRN));
|
||||
|
||||
/* 2016-10-23: The old query will be kept until we are sure that the query above is a good and fast replacement
|
||||
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
|
||||
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||
LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`
|
||||
WHERE `item`.`uid` = %d AND `item`.`received` > '%s' AND NOT `item`.`private` AND NOT `item`.`deleted`
|
||||
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
|
||||
|
@ -1971,7 +1994,7 @@ class ostatus {
|
|||
OR (`item`.`network` = '%s' AND ((`thread`.`network` IN ('%s', '%s')) OR (`thritem`.`network` IN ('%s', '%s')))) AND `thread`.`mention`)
|
||||
AND ((`item`.`owner-link` IN ('%s', '%s') AND (`item`.`parent` = `item`.`id`))
|
||||
OR (`item`.`author-link` IN ('%s', '%s')))
|
||||
ORDER BY `item`.`received` DESC
|
||||
ORDER BY `item`.`id` DESC
|
||||
LIMIT 0, 300",
|
||||
intval($owner["uid"]), dbesc($check_date), dbesc(NETWORK_DFRN),
|
||||
//dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),
|
||||
|
@ -1981,7 +2004,7 @@ class ostatus {
|
|||
dbesc($owner["nurl"]), dbesc(str_replace("http://", "https://", $owner["nurl"])),
|
||||
dbesc($owner["nurl"]), dbesc(str_replace("http://", "https://", $owner["nurl"]))
|
||||
);
|
||||
|
||||
*/
|
||||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
<?php
|
||||
|
||||
require_once("include/dba.php");
|
||||
|
||||
/**
|
||||
* translation support
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief translation support
|
||||
*
|
||||
* Get the language setting directly from system variables, bypassing get_config()
|
||||
* as database may not yet be configured.
|
||||
|
@ -16,8 +10,12 @@ require_once("include/dba.php");
|
|||
*
|
||||
*/
|
||||
|
||||
require_once("include/dba.php");
|
||||
|
||||
if(! function_exists('get_browser_language')) {
|
||||
/**
|
||||
* @brief get the prefered language from the HTTP_ACCEPT_LANGUAGE header
|
||||
*/
|
||||
function get_browser_language() {
|
||||
|
||||
if (x($_SERVER,'HTTP_ACCEPT_LANGUAGE')) {
|
||||
|
@ -25,32 +23,34 @@ function get_browser_language() {
|
|||
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
|
||||
|
||||
$lang_list = [];
|
||||
if (count($lang_parse[1])) {
|
||||
// create a list like "en" => 0.8
|
||||
$langs = array_combine($lang_parse[1], $lang_parse[4]);
|
||||
|
||||
// set default to 1 for any without q factor
|
||||
foreach ($langs as $lang => $val) {
|
||||
if ($val === '') $langs[$lang] = 1;
|
||||
// go through the list of prefered languages and add a generic language
|
||||
// for sub-linguas (e.g. de-ch will add de) if not already in array
|
||||
for ($i=0; $i<count($lang_parse[1]); $i++) {
|
||||
$lang_list[] = strtolower($lang_parse[1][$i]);
|
||||
if ( strlen($lang_parse[1][$i])>3 ) {
|
||||
$dashpos = strpos($lang_parse[1][$i], '-');
|
||||
if (! in_array(substr($lang_parse[1][$i], 0, $dashpos), $lang_list ) ) {
|
||||
$lang_list[] = strtolower(substr($lang_parse[1][$i], 0, $dashpos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort list based on value
|
||||
arsort($langs, SORT_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($langs) && count($langs)) {
|
||||
foreach ($langs as $lang => $v) {
|
||||
if(file_exists("view/$lang") && is_dir("view/$lang")) {
|
||||
// check if we have translations for the preferred languages and pick the 1st that has
|
||||
for ($i=0; $i<count($lang_list); $i++) {
|
||||
$lang = $lang_list[$i];
|
||||
if(file_exists("view/lang/$lang") && is_dir("view/lang/$lang")) {
|
||||
$preferred = $lang;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($preferred))
|
||||
return $preferred;
|
||||
|
||||
// in case none matches, get the system wide configured language, or fall back to English
|
||||
$a = get_app();
|
||||
return ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en');
|
||||
}}
|
||||
|
@ -112,8 +112,8 @@ function load_translation_table($lang) {
|
|||
}
|
||||
}
|
||||
|
||||
if(file_exists("view/$lang/strings.php")) {
|
||||
include("view/$lang/strings.php");
|
||||
if(file_exists("view/lang/$lang/strings.php")) {
|
||||
include("view/lang/$lang/strings.php");
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -162,25 +162,31 @@ function string_plural_select_default($n) {
|
|||
}}
|
||||
|
||||
|
||||
/**
|
||||
* Return installed languages as associative array
|
||||
* [
|
||||
* lang => lang,
|
||||
* ...
|
||||
* ]
|
||||
*/
|
||||
function get_avaiable_languages() {
|
||||
$lang_choices = array();
|
||||
$langs = glob('view/*/strings.php'); /**/
|
||||
|
||||
if(is_array($langs) && count($langs)) {
|
||||
if(! in_array('view/en/strings.php',$langs))
|
||||
$langs[] = 'view/en/';
|
||||
asort($langs);
|
||||
foreach($langs as $l) {
|
||||
$t = explode("/",$l);
|
||||
$lang_choices[$t[1]] = $t[1];
|
||||
/**
|
||||
* @brief Return installed languages codes as associative array
|
||||
*
|
||||
* Scans the view/lang directory for the existence of "strings.php" files, and
|
||||
* returns an alphabetical list of their folder names (@-char language codes).
|
||||
* Adds the english language if it's missing from the list.
|
||||
*
|
||||
* Ex: array('de' => 'de', 'en' => 'en', 'fr' => 'fr', ...)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_available_languages() {
|
||||
$langs = array();
|
||||
$strings_file_paths = glob('view/lang/*/strings.php');
|
||||
|
||||
if (is_array($strings_file_paths) && count($strings_file_paths)) {
|
||||
if (!in_array('view/lang/en/strings.php', $strings_file_paths)) {
|
||||
$strings_file_paths[] = 'view/lang/en/strings.php';
|
||||
}
|
||||
asort($strings_file_paths);
|
||||
foreach($strings_file_paths as $strings_file_path) {
|
||||
$path_array = explode('/', $strings_file_path);
|
||||
$langs[$path_array[2]] = $path_array[2];
|
||||
}
|
||||
}
|
||||
return $lang_choices;
|
||||
return $langs;
|
||||
}
|
||||
|
|
|
@ -25,3 +25,34 @@ function gps2Num($coordPart) {
|
|||
|
||||
return floatval($parts[0]) / floatval($parts[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch the photo albums that are available for a viewer
|
||||
*
|
||||
* The query in this function is cost intensive, so it is cached.
|
||||
*
|
||||
* @param int $uid User id of the photos
|
||||
* @param bool $update Update the cache
|
||||
*
|
||||
* @return array Returns array of the photo albums
|
||||
*/
|
||||
function photo_albums($uid, $update = false) {
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$key = "photo_albums:".$uid.":".local_user().":".remote_user();
|
||||
$albums = Cache::get($key);
|
||||
if (is_null($albums) OR $update) {
|
||||
/// @todo This query needs to be renewed. It is really slow
|
||||
// At this time we just store the data in the cache
|
||||
$albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`
|
||||
FROM `photo` USE INDEX (`uid_album_created`)
|
||||
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
|
||||
GROUP BY `album` ORDER BY `created` DESC",
|
||||
intval($uid),
|
||||
dbesc('Contact Photos'),
|
||||
dbesc(t('Contact Photos'))
|
||||
);
|
||||
Cache::set($key, $albums, CACHE_DAY);
|
||||
}
|
||||
return $albums;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ function get_attachment_data($body) {
|
|||
|
||||
$data = array();
|
||||
|
||||
if (!preg_match("/(.*)\[attachment(.*)\](.*?)\[\/attachment\](.*)/ism", $body, $match))
|
||||
if (!preg_match("/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism", $body, $match))
|
||||
return get_old_attachment_data($body);
|
||||
|
||||
$attributes = $match[2];
|
||||
|
|
|
@ -205,27 +205,33 @@ function load_hooks() {
|
|||
* @param string $name of the hook to call
|
||||
* @param string|array &$data to transmit to the callback handler
|
||||
*/
|
||||
if(! function_exists('call_hooks')) {
|
||||
function call_hooks($name, &$data = null) {
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
$a = get_app();
|
||||
|
||||
#logger($name, LOGGER_ALL);
|
||||
if (is_array($a->hooks) && array_key_exists($name, $a->hooks))
|
||||
foreach ($a->hooks[$name] as $hook)
|
||||
call_single_hook($a, $name, $hook, $data);
|
||||
}
|
||||
|
||||
if((is_array($a->hooks)) && (array_key_exists($name,$a->hooks))) {
|
||||
foreach($a->hooks[$name] as $hook) {
|
||||
/**
|
||||
* @brief Calls a single hook.
|
||||
*
|
||||
* @param string $name of the hook to call
|
||||
* @param array $hook Hook data
|
||||
* @param string|array &$data to transmit to the callback handler
|
||||
*/
|
||||
function call_single_hook($a, $name, $hook, &$data = null) {
|
||||
// Don't run a theme's hook if the user isn't using the theme
|
||||
if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false)
|
||||
continue;
|
||||
return;
|
||||
|
||||
@include_once($hook[0]);
|
||||
if (function_exists($hook[1])) {
|
||||
$func = $hook[1];
|
||||
//logger($name." => ".$hook[0].":".$func."()", LOGGER_DEBUG);
|
||||
$func($a, $data);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// remove orphan hooks
|
||||
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
|
||||
dbesc($name),
|
||||
|
@ -234,8 +240,6 @@ function call_hooks($name, &$data = null) {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
//check if an app_menu hook exist for plugin $name.
|
||||
//Return true if the plugin is an app
|
||||
|
@ -534,3 +538,41 @@ function upgrade_bool_message($bbcode = false) {
|
|||
$x = upgrade_link($bbcode);
|
||||
return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the full path to relevant theme files by filename
|
||||
*
|
||||
* This function search in the theme directory (and if not present in global theme directory)
|
||||
* if there is a directory with the file extension and for a file with the given
|
||||
* filename.
|
||||
*
|
||||
* @param string $file Filename
|
||||
* @param string $root Full root path
|
||||
* @return string Path to the file or empty string if the file isn't found
|
||||
*/
|
||||
function theme_include($file, $root = '') {
|
||||
// Make sure $root ends with a slash / if it's not blank
|
||||
if($root !== '' && $root[strlen($root)-1] !== '/')
|
||||
$root = $root . '/';
|
||||
$theme_info = $a->theme_info;
|
||||
if(is_array($theme_info) AND array_key_exists('extends',$theme_info))
|
||||
$parent = $theme_info['extends'];
|
||||
else
|
||||
$parent = 'NOPATH';
|
||||
$theme = current_theme();
|
||||
$thname = $theme;
|
||||
$ext = substr($file,strrpos($file,'.')+1);
|
||||
$paths = array(
|
||||
"{$root}view/theme/$thname/$ext/$file",
|
||||
"{$root}view/theme/$parent/$ext/$file",
|
||||
"{$root}view/$ext/$file",
|
||||
);
|
||||
foreach($paths as $p) {
|
||||
// strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php)
|
||||
if(strpos($p,'NOPATH') !== false)
|
||||
continue;
|
||||
if(file_exists($p))
|
||||
return $p;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -10,8 +10,10 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
|
|||
chdir($directory);
|
||||
}
|
||||
|
||||
use \Friendica\Core\Config;
|
||||
use \Friendica\Core\PConfig;
|
||||
|
||||
require_once("boot.php");
|
||||
require_once("dbm.php");
|
||||
|
||||
function poller_run(&$argv, &$argc){
|
||||
global $a, $db;
|
||||
|
@ -27,19 +29,16 @@ function poller_run(&$argv, &$argc){
|
|||
unset($db_host, $db_user, $db_pass, $db_data);
|
||||
};
|
||||
|
||||
$max_processes = get_config('system', 'max_processes_backend');
|
||||
if (intval($max_processes) == 0)
|
||||
$max_processes = 5;
|
||||
|
||||
$processlist = dbm::processlist();
|
||||
if ($processlist["list"] != "") {
|
||||
logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
|
||||
|
||||
if ($processlist["amount"] > $max_processes) {
|
||||
logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
|
||||
// Quit when in maintenance
|
||||
if (get_config('system', 'maintenance', true))
|
||||
return;
|
||||
|
||||
$a->start_process();
|
||||
|
||||
$mypid = getmypid();
|
||||
|
||||
if ($a->max_processes_reached())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (poller_max_connections_reached())
|
||||
return;
|
||||
|
@ -48,17 +47,17 @@ function poller_run(&$argv, &$argc){
|
|||
return;
|
||||
|
||||
// Checking the number of workers
|
||||
if (poller_too_much_workers(1)) {
|
||||
if (poller_too_much_workers()) {
|
||||
poller_kill_stale_workers();
|
||||
return;
|
||||
}
|
||||
|
||||
if(($argc <= 1) OR ($argv[1] != "no_cron")) {
|
||||
// Run the cron job that calls all other jobs
|
||||
proc_run("php","include/cron.php");
|
||||
proc_run(PRIORITY_MEDIUM, "include/cron.php");
|
||||
|
||||
// Run the cronhooks job separately from cron for being able to use a different timing
|
||||
proc_run("php","include/cronhooks.php");
|
||||
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php");
|
||||
|
||||
// Cleaning dead processes
|
||||
poller_kill_stale_workers();
|
||||
|
@ -67,46 +66,59 @@ function poller_run(&$argv, &$argc){
|
|||
sleep(4);
|
||||
|
||||
// Checking number of workers
|
||||
if (poller_too_much_workers(2))
|
||||
if (poller_too_much_workers())
|
||||
return;
|
||||
|
||||
$cooldown = Config::get("system", "worker_cooldown", 0);
|
||||
|
||||
$starttime = time();
|
||||
|
||||
while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `created` LIMIT 1")) {
|
||||
while ($r = poller_worker_process()) {
|
||||
|
||||
// Log the type of database processes
|
||||
$processlist = dbm::processlist();
|
||||
if ($processlist["amount"] != "") {
|
||||
logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
|
||||
|
||||
if ($processlist["amount"] > $max_processes) {
|
||||
logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
|
||||
// Quit when in maintenance
|
||||
if (get_config('system', 'maintenance', true))
|
||||
return;
|
||||
|
||||
// Constantly check the number of parallel database processes
|
||||
if ($a->max_processes_reached())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Constantly check the number of available database connections to let the frontend be accessible at any time
|
||||
if (poller_max_connections_reached())
|
||||
return;
|
||||
|
||||
// Count active workers and compare them with a maximum value that depends on the load
|
||||
if (poller_too_much_workers(3))
|
||||
if (poller_too_much_workers())
|
||||
return;
|
||||
|
||||
q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `executed` = '0000-00-00 00:00:00'",
|
||||
$upd = q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `pid` = 0",
|
||||
dbesc(datetime_convert()),
|
||||
intval(getmypid()),
|
||||
intval($mypid),
|
||||
intval($r[0]["id"]));
|
||||
|
||||
// Assure that there are no tasks executed twice
|
||||
$id = q("SELECT `id` FROM `workerqueue` WHERE `id` = %d AND `pid` = %d",
|
||||
intval($r[0]["id"]),
|
||||
intval(getmypid()));
|
||||
if (!$id) {
|
||||
logger("Queue item ".$r[0]["id"]." was executed multiple times - skip this execution", LOGGER_DEBUG);
|
||||
if (!$upd) {
|
||||
logger("Couldn't update queue entry ".$r[0]["id"]." - skip this execution", LOGGER_DEBUG);
|
||||
q("COMMIT");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assure that there are no tasks executed twice
|
||||
$id = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
|
||||
if (!$id) {
|
||||
logger("Queue item ".$r[0]["id"]." vanished - skip this execution", LOGGER_DEBUG);
|
||||
q("COMMIT");
|
||||
continue;
|
||||
} elseif ((strtotime($id[0]["executed"]) <= 0) OR ($id[0]["pid"] == 0)) {
|
||||
logger("Entry for queue item ".$r[0]["id"]." wasn't stored - skip this execution", LOGGER_DEBUG);
|
||||
q("COMMIT");
|
||||
continue;
|
||||
} elseif ($id[0]["pid"] != $mypid) {
|
||||
logger("Queue item ".$r[0]["id"]." is to be executed by process ".$id[0]["pid"]." and not by me (".$mypid.") - skip this execution", LOGGER_DEBUG);
|
||||
q("COMMIT");
|
||||
continue;
|
||||
}
|
||||
q("COMMIT");
|
||||
|
||||
$argv = json_decode($r[0]["parameter"]);
|
||||
|
||||
$argc = count($argv);
|
||||
|
@ -125,10 +137,23 @@ function poller_run(&$argv, &$argc){
|
|||
$funcname = str_replace(".php", "", basename($argv[0]))."_run";
|
||||
|
||||
if (function_exists($funcname)) {
|
||||
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
|
||||
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
|
||||
|
||||
// For better logging create a new process id for every worker call
|
||||
// But preserve the old one for the worker
|
||||
$old_process_id = $a->process_id;
|
||||
$a->process_id = uniqid("wrk", true);
|
||||
|
||||
$funcname($argv, $argc);
|
||||
|
||||
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." - done");
|
||||
$a->process_id = $old_process_id;
|
||||
|
||||
if ($cooldown > 0) {
|
||||
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - in cooldown for ".$cooldown." seconds");
|
||||
sleep($cooldown);
|
||||
}
|
||||
|
||||
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - done");
|
||||
|
||||
q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
|
||||
} else
|
||||
|
@ -226,9 +251,9 @@ function poller_max_connections_reached() {
|
|||
*
|
||||
*/
|
||||
function poller_kill_stale_workers() {
|
||||
$r = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
|
||||
$r = q("SELECT `pid`, `executed`, `priority`, `parameter` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
|
||||
|
||||
if (!is_array($r) || count($r) == 0) {
|
||||
if (!dbm::is_result($r)) {
|
||||
// No processing here needed
|
||||
return;
|
||||
}
|
||||
|
@ -239,27 +264,47 @@ function poller_kill_stale_workers() {
|
|||
intval($pid["pid"]));
|
||||
else {
|
||||
// Kill long running processes
|
||||
|
||||
// Check if the priority is in a valid range
|
||||
if (!in_array($pid["priority"], array(PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW, PRIORITY_NEGLIGIBLE)))
|
||||
$pid["priority"] = PRIORITY_MEDIUM;
|
||||
|
||||
// Define the maximum durations
|
||||
$max_duration_defaults = array(PRIORITY_CRITICAL => 360, PRIORITY_HIGH => 10, PRIORITY_MEDIUM => 60, PRIORITY_LOW => 180, PRIORITY_NEGLIGIBLE => 360);
|
||||
$max_duration = $max_duration_defaults[$pid["priority"]];
|
||||
|
||||
$argv = json_decode($pid["parameter"]);
|
||||
$argv[0] = basename($argv[0]);
|
||||
|
||||
// How long is the process already running?
|
||||
$duration = (time() - strtotime($pid["executed"])) / 60;
|
||||
if ($duration > 180) {
|
||||
logger("Worker process ".$pid["pid"]." took more than 3 hours. It will be killed now.");
|
||||
if ($duration > $max_duration) {
|
||||
logger("Worker process ".$pid["pid"]." (".implode(" ", $argv).") took more than ".$max_duration." minutes. It will be killed now.");
|
||||
posix_kill($pid["pid"], SIGTERM);
|
||||
|
||||
// Question: If a process is stale: Should we remove it or should we reschedule it?
|
||||
// By now we rescheduling it. It's maybe not the wisest decision?
|
||||
q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `pid` = 0 WHERE `pid` = %d",
|
||||
// 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',
|
||||
`priority` = %d, `pid` = 0 WHERE `pid` = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval(PRIORITY_NEGLIGIBLE),
|
||||
intval($pid["pid"]));
|
||||
} else
|
||||
logger("Worker process ".$pid["pid"]." now runs for ".round($duration)." minutes. That's okay.", LOGGER_DEBUG);
|
||||
logger("Worker process ".$pid["pid"]." (".implode(" ", $argv).") now runs for ".round($duration)." of ".$max_duration." allowed minutes. That's okay.", LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
function poller_too_much_workers($stage) {
|
||||
function poller_too_much_workers() {
|
||||
|
||||
|
||||
$queues = get_config("system", "worker_queues");
|
||||
|
||||
if ($queues == 0)
|
||||
$queues = 4;
|
||||
|
||||
$maxqueues = $queues;
|
||||
|
||||
$active = poller_active_workers();
|
||||
|
||||
// Decrease the number of workers at higher load
|
||||
|
@ -276,21 +321,154 @@ function poller_too_much_workers($stage) {
|
|||
$slope = $maxworkers / pow($maxsysload, $exponent);
|
||||
$queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent));
|
||||
|
||||
logger("Current load stage ".$stage.": ".$load." - maximum: ".$maxsysload." - current queues: ".$active." - maximum: ".$queues, LOGGER_DEBUG);
|
||||
$s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00'");
|
||||
$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");
|
||||
$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));
|
||||
$high_running = dbm::is_result($s);
|
||||
|
||||
if (!$high_running AND ($top_priority > PRIORITY_UNDEFINED) AND ($top_priority < PRIORITY_NEGLIGIBLE)) {
|
||||
logger("There are jobs with priority ".$top_priority." waiting but none is executed. Open a fastlane.", LOGGER_DEBUG);
|
||||
$queues = $active + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a list of queue entries grouped by their priority
|
||||
$running = array(PRIORITY_CRITICAL => 0,
|
||||
PRIORITY_HIGH => 0,
|
||||
PRIORITY_MEDIUM => 0,
|
||||
PRIORITY_LOW => 0,
|
||||
PRIORITY_NEGLIGIBLE => 0);
|
||||
|
||||
$r = q("SELECT COUNT(*) AS `running`, `priority` FROM `process` INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid` GROUP BY `priority`");
|
||||
if (dbm::is_result($r))
|
||||
foreach ($r AS $process)
|
||||
$running[$process["priority"]] = $process["running"];
|
||||
|
||||
$processlist = "";
|
||||
$r = q("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` GROUP BY `priority`");
|
||||
if (dbm::is_result($r))
|
||||
foreach ($r as $entry) {
|
||||
if ($processlist != "")
|
||||
$processlist .= ", ";
|
||||
$processlist .= $entry["priority"].":".$running[$entry["priority"]]."/".$entry["entries"];
|
||||
}
|
||||
|
||||
logger("Load: ".$load."/".$maxsysload." - processes: ".$active."/".$entries." (".$processlist.") - maximum: ".$queues."/".$maxqueues, LOGGER_DEBUG);
|
||||
|
||||
// Are there fewer workers running as possible? Then fork a new one.
|
||||
if (!get_config("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");
|
||||
$a = get_app();
|
||||
$a->proc_run($args);
|
||||
}
|
||||
}
|
||||
|
||||
return($active >= $queues);
|
||||
}
|
||||
|
||||
function poller_active_workers() {
|
||||
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
|
||||
$workers = q("SELECT COUNT(*) AS `processes` FROM `process` WHERE `command` = 'poller.php'");
|
||||
|
||||
return($workers[0]["workers"]);
|
||||
return($workers[0]["processes"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if we should pass some slow processes
|
||||
*
|
||||
* When the active processes of the highest priority are using more than 2/3
|
||||
* of all processes, we let pass slower processes.
|
||||
*
|
||||
* @param string $highest_priority Returns the currently highest priority
|
||||
* @return bool We let pass a slower process than $highest_priority
|
||||
*/
|
||||
function poller_passing_slow(&$highest_priority) {
|
||||
|
||||
$highest_priority = 0;
|
||||
|
||||
$r = q("SELECT `priority`
|
||||
FROM `process`
|
||||
INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid`
|
||||
WHERE `process`.`command` = 'poller.php'");
|
||||
|
||||
// No active processes at all? Fine
|
||||
if (!dbm::is_result($r))
|
||||
return(false);
|
||||
|
||||
$priorities = array();
|
||||
foreach ($r AS $line)
|
||||
$priorities[] = $line["priority"];
|
||||
|
||||
// Should not happen
|
||||
if (count($priorities) == 0)
|
||||
return(false);
|
||||
|
||||
$highest_priority = min($priorities);
|
||||
|
||||
// The highest process is already the slowest one?
|
||||
// Then we quit
|
||||
if ($highest_priority == PRIORITY_NEGLIGIBLE)
|
||||
return(false);
|
||||
|
||||
$high = 0;
|
||||
foreach ($priorities AS $priority)
|
||||
if ($priority == $highest_priority)
|
||||
++$high;
|
||||
|
||||
logger("Highest priority: ".$highest_priority." Total processes: ".count($priorities)." Count high priority processes: ".$high, LOGGER_DEBUG);
|
||||
$passing_slow = (($high/count($priorities)) > (2/3));
|
||||
|
||||
if ($passing_slow)
|
||||
logger("Passing slower processes than priority ".$highest_priority, LOGGER_DEBUG);
|
||||
|
||||
return($passing_slow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the next worker process
|
||||
*
|
||||
* @return string SQL statement
|
||||
*/
|
||||
|
||||
function poller_worker_process() {
|
||||
|
||||
q("START TRANSACTION;");
|
||||
|
||||
// Check if we should pass some low priority process
|
||||
$highest_priority = 0;
|
||||
|
||||
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))
|
||||
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));
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
if (array_search(__file__,get_included_files())===0){
|
||||
poller_run($_SERVER["argv"],$_SERVER["argc"]);
|
||||
|
||||
get_app()->end_process();
|
||||
|
||||
killme();
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -8,12 +8,19 @@
|
|||
*/
|
||||
function post_update() {
|
||||
|
||||
if (!post_update_1192())
|
||||
if (!post_update_1192()) {
|
||||
return;
|
||||
|
||||
if (!post_update_1194())
|
||||
}
|
||||
if (!post_update_1194()) {
|
||||
return;
|
||||
}
|
||||
if (!post_update_1198()) {
|
||||
return;
|
||||
}
|
||||
if (!post_update_1206()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the gcontact-id in all item entries
|
||||
|
@ -138,4 +145,118 @@ function post_update_1194() {
|
|||
|
||||
logger("Done", LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the author-id and owner-id in all item entries
|
||||
*
|
||||
* This job has to be started multiple times until all entries are set.
|
||||
* It isn't started in the update function since it would consume too much time and can be done in the background.
|
||||
*
|
||||
* @return bool "true" when the job is done
|
||||
*/
|
||||
function post_update_1198() {
|
||||
|
||||
// Was the script completed?
|
||||
if (get_config("system", "post_update_version") >= 1198)
|
||||
return true;
|
||||
|
||||
logger("Start", LOGGER_DEBUG);
|
||||
|
||||
// Check if the first step is done (Setting "author-id" and "owner-id" in the item table)
|
||||
$r = q("SELECT `author-link`, `owner-link`, `uid` FROM `item` WHERE `author-id` = 0 AND `owner-id` = 0 LIMIT 100");
|
||||
if (!$r) {
|
||||
// Are there unfinished entries in the thread table?
|
||||
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
|
||||
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
|
||||
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
|
||||
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
|
||||
|
||||
if ($r AND ($r[0]["total"] == 0)) {
|
||||
set_config("system", "post_update_version", 1198);
|
||||
logger("Done", LOGGER_DEBUG);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update the thread table from the item table
|
||||
$r = q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
|
||||
SET `thread`.`author-id` = `item`.`author-id`,
|
||||
`thread`.`owner-id` = `item`.`owner-id`
|
||||
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
|
||||
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
|
||||
|
||||
logger("Updated threads", LOGGER_DEBUG);
|
||||
if (dbm::is_result($r)) {
|
||||
set_config("system", "post_update_version", 1198);
|
||||
logger("Done", LOGGER_DEBUG);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
logger("Query done", LOGGER_DEBUG);
|
||||
|
||||
$item_arr = array();
|
||||
foreach ($r AS $item) {
|
||||
$index = $item["author-link"]."-".$item["owner-link"]."-".$item["uid"];
|
||||
$item_arr[$index] = array("author-link" => $item["author-link"],
|
||||
"owner-link" => $item["owner-link"],
|
||||
"uid" => $item["uid"]);
|
||||
}
|
||||
|
||||
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
|
||||
foreach($item_arr AS $item) {
|
||||
$author_id = get_contact($item["author-link"], 0);
|
||||
$owner_id = get_contact($item["owner-link"], 0);
|
||||
|
||||
if ($author_id == 0)
|
||||
$author_id = -1;
|
||||
|
||||
if ($owner_id == 0)
|
||||
$owner_id = -1;
|
||||
|
||||
q("UPDATE `item` SET `author-id` = %d, `owner-id` = %d
|
||||
WHERE `uid` = %d AND `author-link` = '%s' AND `owner-link` = '%s'
|
||||
AND `author-id` = 0 AND `owner-id` = 0",
|
||||
intval($author_id), intval($owner_id), intval($item["uid"]),
|
||||
dbesc($item["author-link"]), dbesc($item["owner-link"]));
|
||||
}
|
||||
|
||||
logger("Updated items", LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief update the "last-item" field in the "self" contact
|
||||
*
|
||||
* This field avoids cost intensive calls in the admin panel and in "nodeinfo"
|
||||
*
|
||||
* @return bool "true" when the job is done
|
||||
*/
|
||||
function post_update_1206() {
|
||||
// Was the script completed?
|
||||
if (get_config("system", "post_update_version") >= 1206)
|
||||
return true;
|
||||
|
||||
logger("Start", LOGGER_DEBUG);
|
||||
$r = q("SELECT `contact`.`id`, `contact`.`last-item`,
|
||||
(SELECT MAX(`changed`) FROM `item` FORCE INDEX (`uid_wall_changed`) WHERE `wall` AND `uid` = `user`.`uid`) AS `lastitem_date`
|
||||
FROM `user`
|
||||
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`");
|
||||
|
||||
if (!dbm::is_result($r)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($r AS $user) {
|
||||
if (!empty($user["lastitem_date"]) AND ($user["lastitem_date"] > $user["last-item"])) {
|
||||
q("UPDATE `contact` SET `last-item` = '%s' WHERE `id` = %d",
|
||||
dbesc($user["lastitem_date"]),
|
||||
intval($user["id"]));
|
||||
}
|
||||
}
|
||||
|
||||
set_config("system", "post_update_version", 1206);
|
||||
logger("Done", LOGGER_DEBUG);
|
||||
return true;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
require_once("boot.php");
|
||||
require_once("include/ostatus.php");
|
||||
|
||||
function handle_pubsubhubbub() {
|
||||
use \Friendica\Core\Config;
|
||||
use \Friendica\Core\PConfig;
|
||||
|
||||
function handle_pubsubhubbub($id) {
|
||||
global $a, $db;
|
||||
|
||||
logger('start');
|
||||
$r = q("SELECT * FROM `push_subscriber` WHERE `id` = %d", intval($id));
|
||||
if (!$r)
|
||||
return;
|
||||
else
|
||||
$rr = $r[0];
|
||||
|
||||
// We'll push to each subscriber that has push > 0,
|
||||
// i.e. there has been an update (set in notifier.php).
|
||||
|
||||
$r = q("SELECT * FROM `push_subscriber` WHERE `push` > 0");
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
logger("Generate feed for user ".$rr['nickname']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
|
||||
logger("Generate feed of user ".$rr['nickname']." to ".$rr['callback_url']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
|
||||
|
||||
$params = ostatus::feed($a, $rr['nickname'], $rr['last_update']);
|
||||
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
|
||||
|
@ -55,9 +55,6 @@ function handle_pubsubhubbub() {
|
|||
}
|
||||
}
|
||||
|
||||
logger('done');
|
||||
}
|
||||
|
||||
|
||||
function pubsubpublish_run(&$argv, &$argc){
|
||||
global $a, $db;
|
||||
|
@ -89,10 +86,28 @@ function pubsubpublish_run(&$argv, &$argc){
|
|||
|
||||
if($argc > 1)
|
||||
$pubsubpublish_id = intval($argv[1]);
|
||||
else
|
||||
$pubsubpublish_id = 0;
|
||||
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");
|
||||
|
||||
handle_pubsubhubbub();
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ function queue_run(&$argv, &$argc){
|
|||
unset($db_host, $db_user, $db_pass, $db_data);
|
||||
};
|
||||
|
||||
|
||||
require_once("include/session.php");
|
||||
require_once("include/datetime.php");
|
||||
require_once('include/items.php');
|
||||
|
@ -45,10 +44,12 @@ function queue_run(&$argv, &$argc){
|
|||
$deadservers = array();
|
||||
$serverlist = array();
|
||||
|
||||
if (!$queue_id) {
|
||||
|
||||
logger('queue: start');
|
||||
|
||||
// Handling the pubsubhubbub requests
|
||||
proc_run('php','include/pubsubpublish.php');
|
||||
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
|
||||
|
||||
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
|
||||
|
||||
|
@ -60,7 +61,7 @@ function queue_run(&$argv, &$argc){
|
|||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
logger('queue: deliverq');
|
||||
proc_run('php','include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
|
||||
proc_run(PRIORITY_HIGH,'include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
|
@ -77,18 +78,18 @@ function queue_run(&$argv, &$argc){
|
|||
q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
|
||||
}
|
||||
|
||||
if($queue_id) {
|
||||
$r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1",
|
||||
intval($queue_id)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
// For the first 12 hours we'll try to deliver every 15 minutes
|
||||
// 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)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$r){
|
||||
return;
|
||||
}
|
||||
|
@ -107,16 +108,17 @@ function queue_run(&$argv, &$argc){
|
|||
// queue_predeliver hooks may have changed the queue db details,
|
||||
// so check again if this entry still needs processing
|
||||
|
||||
if($queue_id) {
|
||||
if($queue_id)
|
||||
$qi = q("SELECT * FROM `queue` WHERE `id` = %d LIMIT 1",
|
||||
intval($queue_id)
|
||||
);
|
||||
}
|
||||
else {
|
||||
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'])
|
||||
);
|
||||
}
|
||||
intval($q_item['id']));
|
||||
|
||||
if(! count($qi))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
<?php
|
||||
|
||||
require_once('include/crypto.php');
|
||||
|
||||
|
||||
require_once('include/Probe.php');
|
||||
|
||||
function get_salmon_key($uri,$keyhash) {
|
||||
$ret = array();
|
||||
|
||||
logger('Fetching salmon key for '.$uri);
|
||||
|
||||
$arr = lrdd($uri);
|
||||
$arr = Probe::lrdd($uri);
|
||||
|
||||
if(is_array($arr)) {
|
||||
foreach($arr as $a) {
|
||||
|
@ -32,8 +31,7 @@ function get_salmon_key($uri,$keyhash) {
|
|||
$ret[$x] = substr($ret[$x],strpos($ret[$x],',')+1);
|
||||
else
|
||||
$ret[$x] = substr($ret[$x],5);
|
||||
}
|
||||
else
|
||||
} elseif (normalise_link($ret[$x]) == 'http://')
|
||||
$ret[$x] = fetch_url($ret[$x]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,11 +79,9 @@ function authenticate_success($user_record, $login_initial = false, $interactive
|
|||
header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] .'"');
|
||||
|
||||
if($login_initial || $login_refresh) {
|
||||
$l = get_browser_language();
|
||||
|
||||
q("UPDATE `user` SET `login_date` = '%s', `language` = '%s' WHERE `uid` = %d",
|
||||
q("UPDATE `user` SET `login_date` = '%s' WHERE `uid` = %d",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($l),
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
|
||||
|
|
|
@ -1,32 +1,58 @@
|
|||
<?php
|
||||
|
||||
// Session management functions. These provide database storage of PHP
|
||||
// session info.
|
||||
|
||||
require_once('include/cache.php');
|
||||
|
||||
$session_exists = 0;
|
||||
$session_expire = 180000;
|
||||
|
||||
if(! function_exists('ref_session_open')) {
|
||||
function ref_session_open($s, $n) {
|
||||
return true;
|
||||
}}
|
||||
}
|
||||
|
||||
if(! function_exists('ref_session_read')) {
|
||||
function ref_session_read($id) {
|
||||
global $session_exists;
|
||||
if(x($id))
|
||||
|
||||
if (!x($id)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$memcache = cache::memcache();
|
||||
if (is_object($memcache)) {
|
||||
$data = $memcache->get(get_app()->get_hostname().":session:".$id);
|
||||
if (!is_bool($data)) {
|
||||
return $data;
|
||||
}
|
||||
logger("no data for session $id", LOGGER_TRACE);
|
||||
return '';
|
||||
}
|
||||
|
||||
$r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
|
||||
|
||||
if(count($r)) {
|
||||
if (dbm::is_result($r)) {
|
||||
$session_exists = true;
|
||||
return $r[0]['data'];
|
||||
} else {
|
||||
logger("no data for session $id", LOGGER_TRACE);
|
||||
}
|
||||
return '';
|
||||
}}
|
||||
|
||||
if(! function_exists('ref_session_write')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Standard PHP session write callback
|
||||
*
|
||||
* This callback updates the DB-stored session data and/or the expiration depending
|
||||
* on the case. Uses the $session_expire global for existing session, 5 minutes
|
||||
* for newly created session.
|
||||
*
|
||||
* @global bool $session_exists Whether a session with the given id already exists
|
||||
* @global int $session_expire Session expiration delay in seconds
|
||||
* @param string $id Session ID with format: [a-z0-9]{26}
|
||||
* @param string $data Serialized session data
|
||||
* @return boolean Returns false if parameters are missing, true otherwise
|
||||
*/
|
||||
function ref_session_write($id, $data) {
|
||||
global $session_exists, $session_expire;
|
||||
|
||||
|
@ -37,40 +63,49 @@ function ref_session_write ($id,$data) {
|
|||
$expire = time() + $session_expire;
|
||||
$default_expire = time() + 300;
|
||||
|
||||
$memcache = cache::memcache();
|
||||
if (is_object($memcache)) {
|
||||
$memcache->set(get_app()->get_hostname().":session:".$id, $data, MEMCACHE_COMPRESSED, $expire);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($session_exists) {
|
||||
$r = q("UPDATE `session`
|
||||
SET `data` = '%s'
|
||||
WHERE `data` != '%s' AND `sid` = '%s'",
|
||||
dbesc($data), dbesc($data), dbesc($id));
|
||||
|
||||
$r = q("UPDATE `session`
|
||||
SET `expire` = '%s'
|
||||
WHERE `expire` != '%s' AND `sid` = '%s'",
|
||||
dbesc($expire), dbesc($expire), dbesc($id));
|
||||
} else
|
||||
SET `data` = '%s', `expire` = '%s'
|
||||
WHERE `sid` = '%s'
|
||||
AND (`data` != '%s' OR `expire` != '%s')",
|
||||
dbesc($data), dbesc($expire), dbesc($id), dbesc($data), dbesc($expire));
|
||||
} else {
|
||||
$r = q("INSERT INTO `session`
|
||||
SET `sid` = '%s', `expire` = '%s', `data` = '%s'",
|
||||
dbesc($id), dbesc($default_expire), dbesc($data));
|
||||
}
|
||||
|
||||
return true;
|
||||
}}
|
||||
}
|
||||
|
||||
if(! function_exists('ref_session_close')) {
|
||||
function ref_session_close() {
|
||||
return true;
|
||||
}}
|
||||
}
|
||||
|
||||
if(! function_exists('ref_session_destroy')) {
|
||||
function ref_session_destroy($id) {
|
||||
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
|
||||
return true;
|
||||
}}
|
||||
$memcache = cache::memcache();
|
||||
|
||||
if (is_object($memcache)) {
|
||||
$memcache->delete(get_app()->get_hostname().":session:".$id);
|
||||
return true;
|
||||
}
|
||||
|
||||
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(! function_exists('ref_session_gc')) {
|
||||
function ref_session_gc($expire) {
|
||||
q("DELETE FROM `session` WHERE `expire` < %d", dbesc(time()));
|
||||
|
||||
return true;
|
||||
}}
|
||||
}
|
||||
|
||||
$gc_probability = 50;
|
||||
|
||||
|
@ -78,7 +113,8 @@ ini_set('session.gc_probability', $gc_probability);
|
|||
ini_set('session.use_only_cookies', 1);
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
|
||||
if (!get_config('system', 'disable_database_session'))
|
||||
if (!get_config('system', 'disable_database_session')) {
|
||||
session_set_save_handler('ref_session_open', 'ref_session_close',
|
||||
'ref_session_read', 'ref_session_write',
|
||||
'ref_session_destroy', 'ref_session_gc');
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
require_once('include/datetime.php');
|
||||
require_once("include/Scrape.php");
|
||||
require_once("include/network.php");
|
||||
require_once("include/html2bbcode.php");
|
||||
require_once("include/Contact.php");
|
||||
require_once("include/Photo.php");
|
||||
|
@ -51,7 +52,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
if(! $url)
|
||||
return;
|
||||
|
||||
$url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation') ;
|
||||
$url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation') ;
|
||||
|
||||
logger('poco_load: ' . $url, LOGGER_DEBUG);
|
||||
|
||||
|
@ -85,6 +86,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
$about = '';
|
||||
$keywords = '';
|
||||
$gender = '';
|
||||
$contact_type = -1;
|
||||
$generation = 0;
|
||||
|
||||
$name = $entry->displayName;
|
||||
|
@ -132,6 +134,9 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
foreach($entry->tags as $tag)
|
||||
$keywords = implode(", ", $tag);
|
||||
|
||||
if(isset($entry->contactType) AND ($entry->contactType >= 0))
|
||||
$contact_type = $entry->contactType;
|
||||
|
||||
// If you query a Friendica server for its profiles, the network has to be Friendica
|
||||
/// TODO It could also be a Redmatrix server
|
||||
//if ($uid == 0)
|
||||
|
@ -139,6 +144,9 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
|
||||
poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid, $uid, $zcid);
|
||||
|
||||
$gcontact = array("url" => $profile_url, "contact-type" => $contact_type, "generation" => $generation);
|
||||
update_gcontact($gcontact);
|
||||
|
||||
// Update the Friendica contacts. Diaspora is doing it via a message. (See include/diaspora.php)
|
||||
// Deactivated because we now update Friendica contacts in dfrn.php
|
||||
//if (($location != "") OR ($about != "") OR ($keywords != "") OR ($gender != ""))
|
||||
|
@ -1067,8 +1075,14 @@ function all_friends($uid,$cid,$start = 0, $limit = 80) {
|
|||
|
||||
function suggestion_query($uid, $start = 0, $limit = 80) {
|
||||
|
||||
if(! $uid)
|
||||
if (!$uid) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
|
||||
if (!is_null($list)) {
|
||||
return $list;
|
||||
}
|
||||
|
||||
$network = array(NETWORK_DFRN);
|
||||
|
||||
|
@ -1079,9 +1093,10 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
|
|||
$network[] = NETWORK_OSTATUS;
|
||||
|
||||
$sql_network = implode("', '", $network);
|
||||
//$sql_network = "'".$sql_network."', ''";
|
||||
$sql_network = "'".$sql_network."'";
|
||||
|
||||
/// @todo This query is really slow
|
||||
// By now we cache the data for five minutes
|
||||
$r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
|
||||
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
||||
where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d )
|
||||
|
@ -1100,8 +1115,10 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
|
|||
intval($limit)
|
||||
);
|
||||
|
||||
if(count($r) && count($r) >= ($limit -1))
|
||||
if (count($r) && count($r) >= ($limit -1)) {
|
||||
Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $r, CACHE_FIVE_MINUTES);
|
||||
return $r;
|
||||
}
|
||||
|
||||
$r2 = q("SELECT gcontact.* FROM gcontact
|
||||
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
||||
|
@ -1130,6 +1147,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
|
|||
while (sizeof($list) > ($limit))
|
||||
array_pop($list);
|
||||
|
||||
Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, CACHE_FIVE_MINUTES);
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
@ -1235,7 +1253,7 @@ function poco_discover($complete = false) {
|
|||
}
|
||||
|
||||
// Fetch all users from the other server
|
||||
$url = $server["poco"]."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation";
|
||||
$url = $server["poco"]."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation";
|
||||
|
||||
logger("Fetch all users from the server ".$server["nurl"], LOGGER_DEBUG);
|
||||
|
||||
|
@ -1254,7 +1272,7 @@ function poco_discover($complete = false) {
|
|||
$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,generation";
|
||||
$url = $server["poco"]."/@global?updatedSince=".$updatedSince."&fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation";
|
||||
|
||||
$success = false;
|
||||
|
||||
|
@ -1302,7 +1320,7 @@ function poco_discover_server_users($data, $server) {
|
|||
logger("Fetch contacts for the user ".$username." from the server ".$server["nurl"], LOGGER_DEBUG);
|
||||
|
||||
// Fetch all contacts from a given user from the other server
|
||||
$url = $server["poco"]."/".$username."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation";
|
||||
$url = $server["poco"]."/".$username."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation";
|
||||
|
||||
$retdata = z_fetch_url($url);
|
||||
if ($retdata["success"])
|
||||
|
@ -1329,6 +1347,7 @@ function poco_discover_server($data, $default_generation = 0) {
|
|||
$about = '';
|
||||
$keywords = '';
|
||||
$gender = '';
|
||||
$contact_type = -1;
|
||||
$generation = $default_generation;
|
||||
|
||||
$name = $entry->displayName;
|
||||
|
@ -1373,6 +1392,9 @@ function poco_discover_server($data, $default_generation = 0) {
|
|||
if(isset($entry->generation) AND ($entry->generation > 0))
|
||||
$generation = ++$entry->generation;
|
||||
|
||||
if(isset($entry->contactType) AND ($entry->contactType >= 0))
|
||||
$contact_type = $entry->contactType;
|
||||
|
||||
if(isset($entry->tags))
|
||||
foreach($entry->tags as $tag)
|
||||
$keywords = implode(", ", $tag);
|
||||
|
@ -1382,6 +1404,10 @@ function poco_discover_server($data, $default_generation = 0) {
|
|||
|
||||
logger("Store profile ".$profile_url, LOGGER_DEBUG);
|
||||
poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, 0, 0, 0);
|
||||
|
||||
$gcontact = array("url" => $profile_url, "contact-type" => $contact_type, "generation" => $generation);
|
||||
update_gcontact($gcontact);
|
||||
|
||||
logger("Done for profile ".$profile_url, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
@ -1506,7 +1532,7 @@ function get_gcontact_id($contact) {
|
|||
|
||||
if ($doprobing) {
|
||||
logger("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], LOGGER_DEBUG);
|
||||
proc_run('php', 'include/gprobe.php', bin2hex($contact["url"]));
|
||||
proc_run(PRIORITY_LOW, 'include/gprobe.php', bin2hex($contact["url"]));
|
||||
}
|
||||
|
||||
if ((count($r) > 1) AND ($gcontact_id > 0) AND ($contact["url"] != ""))
|
||||
|
@ -1533,7 +1559,7 @@ function update_gcontact($contact) {
|
|||
return false;
|
||||
|
||||
$r = q("SELECT `name`, `nick`, `photo`, `location`, `about`, `addr`, `generation`, `birthday`, `gender`, `keywords`,
|
||||
`hide`, `nsfw`, `network`, `alias`, `notify`, `server_url`, `connect`, `updated`, `url`
|
||||
`contact-type`, `hide`, `nsfw`, `network`, `alias`, `notify`, `server_url`, `connect`, `updated`, `url`
|
||||
FROM `gcontact` WHERE `id` = %d LIMIT 1",
|
||||
intval($gcontact_id));
|
||||
|
||||
|
@ -1613,20 +1639,20 @@ function update_gcontact($contact) {
|
|||
}
|
||||
|
||||
if ($update) {
|
||||
logger("Update gcontact for ".$contact["url"]." Callstack: ".App::callstack(), LOGGER_DEBUG);
|
||||
logger("Update gcontact for ".$contact["url"], LOGGER_DEBUG);
|
||||
|
||||
q("UPDATE `gcontact` SET `photo` = '%s', `name` = '%s', `nick` = '%s', `addr` = '%s', `network` = '%s',
|
||||
`birthday` = '%s', `gender` = '%s', `keywords` = '%s', `hide` = %d, `nsfw` = %d,
|
||||
`alias` = '%s', `notify` = '%s', `url` = '%s',
|
||||
`contact-type` = %d, `alias` = '%s', `notify` = '%s', `url` = '%s',
|
||||
`location` = '%s', `about` = '%s', `generation` = %d, `updated` = '%s',
|
||||
`server_url` = '%s', `connect` = '%s'
|
||||
WHERE `nurl` = '%s' AND (`generation` = 0 OR `generation` >= %d)",
|
||||
dbesc($contact["photo"]), dbesc($contact["name"]), dbesc($contact["nick"]),
|
||||
dbesc($contact["addr"]), dbesc($contact["network"]), dbesc($contact["birthday"]),
|
||||
dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]),
|
||||
intval($contact["nsfw"]), dbesc($contact["alias"]), dbesc($contact["notify"]),
|
||||
dbesc($contact["url"]), dbesc($contact["location"]), dbesc($contact["about"]),
|
||||
intval($contact["generation"]), dbesc($contact["updated"]),
|
||||
intval($contact["nsfw"]), intval($contact["contact-type"]), dbesc($contact["alias"]),
|
||||
dbesc($contact["notify"]), dbesc($contact["url"]), dbesc($contact["location"]),
|
||||
dbesc($contact["about"]), intval($contact["generation"]), dbesc($contact["updated"]),
|
||||
dbesc($contact["server_url"]), dbesc($contact["connect"]),
|
||||
dbesc(normalise_link($contact["url"])), intval($contact["generation"]));
|
||||
|
||||
|
@ -1643,13 +1669,14 @@ function update_gcontact($contact) {
|
|||
|
||||
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s',
|
||||
`network` = '%s', `bd` = '%s', `gender` = '%s',
|
||||
`keywords` = '%s', `alias` = '%s', `url` = '%s',
|
||||
`location` = '%s', `about` = '%s'
|
||||
`keywords` = '%s', `alias` = '%s', `contact-type` = %d,
|
||||
`url` = '%s', `location` = '%s', `about` = '%s'
|
||||
WHERE `id` = %d",
|
||||
dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["addr"]),
|
||||
dbesc($contact["network"]), dbesc($contact["birthday"]), dbesc($contact["gender"]),
|
||||
dbesc($contact["keywords"]), dbesc($contact["alias"]), dbesc($contact["url"]),
|
||||
dbesc($contact["location"]), dbesc($contact["about"]), intval($r[0]["id"]));
|
||||
dbesc($contact["keywords"]), dbesc($contact["alias"]), intval($contact["contact-type"]),
|
||||
dbesc($contact["url"]), dbesc($contact["location"]), dbesc($contact["about"]),
|
||||
intval($r[0]["id"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
228
include/text.php
228
include/text.php
|
@ -581,14 +581,14 @@ function get_intltext_template($s) {
|
|||
if(! isset($lang))
|
||||
$lang = 'en';
|
||||
|
||||
if(file_exists("view/$lang$engine/$s")) {
|
||||
if(file_exists("view/lang/$lang$engine/$s")) {
|
||||
$stamp1 = microtime(true);
|
||||
$content = file_get_contents("view/$lang$engine/$s");
|
||||
$content = file_get_contents("view/lang/$lang$engine/$s");
|
||||
$a->save_timestamp($stamp1, "file");
|
||||
return $content;
|
||||
} elseif(file_exists("view/en$engine/$s")) {
|
||||
} elseif(file_exists("view/lang/en$engine/$s")) {
|
||||
$stamp1 = microtime(true);
|
||||
$content = file_get_contents("view/en$engine/$s");
|
||||
$content = file_get_contents("view/lang/en$engine/$s");
|
||||
$a->save_timestamp($stamp1, "file");
|
||||
return $content;
|
||||
} else {
|
||||
|
@ -683,6 +683,8 @@ if(! function_exists('logger')) {
|
|||
$LOGGER_LEVELS = array();
|
||||
|
||||
/**
|
||||
* @brief Logs the given message at the given log level
|
||||
*
|
||||
* log levels:
|
||||
* LOGGER_NORMAL (default)
|
||||
* LOGGER_TRACE
|
||||
|
@ -692,35 +694,53 @@ $LOGGER_LEVELS = array();
|
|||
*
|
||||
* @global App $a
|
||||
* @global dba $db
|
||||
* @global array $LOGGER_LEVELS
|
||||
* @param string $msg
|
||||
* @param int $level
|
||||
*/
|
||||
function logger($msg, $level = 0) {
|
||||
// turn off logger in install mode
|
||||
global $a;
|
||||
global $db;
|
||||
global $LOGGER_LEVELS;
|
||||
|
||||
if(($a->module == 'install') || (! ($db && $db->connected))) return;
|
||||
|
||||
if (count($LOGGER_LEVELS)==0){
|
||||
foreach (get_defined_constants() as $k=>$v){
|
||||
if (substr($k,0,7)=="LOGGER_")
|
||||
$LOGGER_LEVELS[$v] = substr($k,7,7);
|
||||
}
|
||||
// turn off logger in install mode
|
||||
if (
|
||||
$a->module == 'install'
|
||||
|| ! ($db && $db->connected)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$debugging = get_config('system','debugging');
|
||||
$loglevel = intval(get_config('system','loglevel'));
|
||||
$logfile = get_config('system','logfile');
|
||||
$loglevel = intval(get_config('system','loglevel'));
|
||||
|
||||
if((! $debugging) || (! $logfile) || ($level > $loglevel))
|
||||
if (
|
||||
! $debugging
|
||||
|| ! $logfile
|
||||
|| $level > $loglevel
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count($LOGGER_LEVELS) == 0) {
|
||||
foreach (get_defined_constants() as $k => $v) {
|
||||
if (substr($k, 0, 7) == "LOGGER_") {
|
||||
$LOGGER_LEVELS[$v] = substr($k, 7, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$process_id = session_id();
|
||||
|
||||
if ($process_id == '') {
|
||||
$process_id = get_app()->process_id;
|
||||
}
|
||||
|
||||
$callers = debug_backtrace();
|
||||
$logline = sprintf("%s@%s\t[%s]:%s:%s:%s\t%s\n",
|
||||
datetime_convert(),
|
||||
session_id(),
|
||||
$process_id,
|
||||
$LOGGER_LEVELS[$level],
|
||||
basename($callers[0]['file']),
|
||||
$callers[0]['line'],
|
||||
|
@ -731,7 +751,6 @@ function logger($msg,$level = 0) {
|
|||
$stamp1 = microtime(true);
|
||||
@file_put_contents($logfile, $logline, FILE_APPEND);
|
||||
$a->save_timestamp($stamp1, "file");
|
||||
return;
|
||||
}}
|
||||
|
||||
|
||||
|
@ -750,71 +769,75 @@ function activity_match($haystack,$needle) {
|
|||
}}
|
||||
|
||||
|
||||
if(! function_exists('get_tags')) {
|
||||
/**
|
||||
* Pull out all #hashtags and @person tags from $s;
|
||||
* @brief Pull out all #hashtags and @person tags from $string.
|
||||
*
|
||||
* We also get @person@domain.com - which would make
|
||||
* the regex quite complicated as tags can also
|
||||
* end a sentence. So we'll run through our results
|
||||
* and strip the period from any tags which end with one.
|
||||
* Returns array of tags found, or empty array.
|
||||
*
|
||||
* @param string $s
|
||||
* @return array
|
||||
* @param string $string Post content
|
||||
* @return array List of tag and person names
|
||||
*/
|
||||
function get_tags($s) {
|
||||
function get_tags($string) {
|
||||
$ret = array();
|
||||
|
||||
// Convert hashtag links to hashtags
|
||||
$s = preg_replace("/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism", "#$2", $s);
|
||||
$string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string);
|
||||
|
||||
// ignore anything in a code block
|
||||
$s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
|
||||
$string = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $string);
|
||||
|
||||
// Force line feeds at bbtags
|
||||
$s = str_replace(array("[", "]"), array("\n[", "]\n"), $s);
|
||||
$string = str_replace(array('[', ']'), array("\n[", "]\n"), $string);
|
||||
|
||||
// ignore anything in a bbtag
|
||||
$s = preg_replace('/\[(.*?)\]/sm','',$s);
|
||||
$string = preg_replace('/\[(.*?)\]/sm', '', $string);
|
||||
|
||||
// Match full names against @tags including the space between first and last
|
||||
// We will look these up afterward to see if they are full names or not recognisable.
|
||||
|
||||
if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) {
|
||||
foreach($match[1] as $mtch) {
|
||||
if(strstr($mtch,"]")) {
|
||||
if (preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/', $string, $matches)) {
|
||||
foreach ($matches[1] as $match) {
|
||||
if (strstr($match, ']')) {
|
||||
// we might be inside a bbcode color tag - leave it alone
|
||||
continue;
|
||||
}
|
||||
if(substr($mtch,-1,1) === '.')
|
||||
$ret[] = substr($mtch,0,-1);
|
||||
else
|
||||
$ret[] = $mtch;
|
||||
if (substr($match, -1, 1) === '.') {
|
||||
$ret[] = substr($match, 0, -1);
|
||||
} else {
|
||||
$ret[] = $match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise pull out single word tags. These can be @nickname, @first_last
|
||||
// and #hash tags.
|
||||
|
||||
if(preg_match_all('/([!#@][^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/',$s,$match)) {
|
||||
foreach($match[1] as $mtch) {
|
||||
if(strstr($mtch,"]")) {
|
||||
if (preg_match_all('/([!#@][^\^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/', $string, $matches)) {
|
||||
foreach($matches[1] as $match) {
|
||||
if (strstr($match, ']')) {
|
||||
// we might be inside a bbcode color tag - leave it alone
|
||||
continue;
|
||||
}
|
||||
if(substr($mtch,-1,1) === '.')
|
||||
$mtch = substr($mtch,0,-1);
|
||||
if (substr($match, -1, 1) === '.') {
|
||||
$match = substr($match,0,-1);
|
||||
}
|
||||
// ignore strictly numeric tags like #1
|
||||
if((strpos($mtch,'#') === 0) && ctype_digit(substr($mtch,1)))
|
||||
if ((strpos($match, '#') === 0) && ctype_digit(substr($match, 1))) {
|
||||
continue;
|
||||
}
|
||||
// try not to catch url fragments
|
||||
if(strpos($s,$mtch) && preg_match('/[a-zA-z0-9\/]/',substr($s,strpos($s,$mtch)-1,1)))
|
||||
if (strpos($string, $match) && preg_match('/[a-zA-z0-9\/]/', substr($string, strpos($string, $match) - 1, 1))) {
|
||||
continue;
|
||||
$ret[] = $mtch;
|
||||
}
|
||||
$ret[] = $match;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -867,7 +890,8 @@ function contact_block() {
|
|||
$micropro = Null;
|
||||
|
||||
} else {
|
||||
$r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `micro`, `network` FROM `contact`
|
||||
// Splitting the query in two parts makes it much faster
|
||||
$r = q("SELECT `id` FROM `contact`
|
||||
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending`
|
||||
AND NOT `hidden` AND NOT `archive`
|
||||
AND `network` IN ('%s', '%s', '%s') ORDER BY RAND() LIMIT %d",
|
||||
|
@ -877,6 +901,13 @@ function contact_block() {
|
|||
dbesc(NETWORK_DIASPORA),
|
||||
intval($shown)
|
||||
);
|
||||
if ($r) {
|
||||
$contacts = "";
|
||||
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)));
|
||||
if(count($r)) {
|
||||
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
|
||||
$micropro = Array();
|
||||
|
@ -885,6 +916,7 @@ function contact_block() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = get_markup_template('contact_block.tpl');
|
||||
$o = replace_macros($tpl, array(
|
||||
|
@ -901,20 +933,28 @@ function contact_block() {
|
|||
|
||||
}}
|
||||
|
||||
if(! function_exists('micropro')) {
|
||||
/**
|
||||
* @brief Format contacts as picture links or as texxt links
|
||||
*
|
||||
* @param array $contact
|
||||
* @param boolean $redirect
|
||||
* @param string $class
|
||||
* @param boolean $textmode
|
||||
* @return string #FIXME: remove html
|
||||
* @param array $contact Array with contacts which contains an array with
|
||||
* int 'id' => The ID of the contact
|
||||
* int 'uid' => The user ID of the user who owns this data
|
||||
* string 'name' => The name of the contact
|
||||
* string 'url' => The url to the profile page of the contact
|
||||
* string 'addr' => The webbie of the contact (e.g.) username@friendica.com
|
||||
* string 'network' => The network to which the contact belongs to
|
||||
* string 'thumb' => The contact picture
|
||||
* string 'click' => js code which is performed when clicking on the contact
|
||||
* @param boolean $redirect If true try to use the redir url if it's possible
|
||||
* @param string $class CSS class for the
|
||||
* @param boolean $textmode If true display the contacts as text links
|
||||
* if false display the contacts as picture links
|
||||
|
||||
* @return string Formatted html
|
||||
*/
|
||||
function micropro($contact, $redirect = false, $class = '', $textmode = false) {
|
||||
|
||||
if($class)
|
||||
$class = ' ' . $class;
|
||||
|
||||
// Use the contact URL if no address is available
|
||||
if ($contact["addr"] == "")
|
||||
$contact["addr"] = $contact["url"];
|
||||
|
||||
|
@ -933,26 +973,23 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
|
|||
else
|
||||
$url = zrl($url);
|
||||
}
|
||||
$click = ((x($contact,'click')) ? ' onclick="' . $contact['click'] . '" ' : '');
|
||||
if($click)
|
||||
|
||||
// If there is some js available we don't need the url
|
||||
if(x($contact,'click'))
|
||||
$url = '';
|
||||
if($textmode) {
|
||||
return '<div class="contact-block-textdiv' . $class . '"><a class="contact-block-link' . $class . $sparkle
|
||||
. (($click) ? ' fakelink' : '') . '" '
|
||||
. (($redir) ? ' target="redir" ' : '')
|
||||
. (($url) ? ' href="' . $url . '"' : '') . $click
|
||||
. '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
|
||||
. '" >'. $contact['name'] . '</a></div>' . "\r\n";
|
||||
|
||||
return replace_macros(get_markup_template(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'),array(
|
||||
'$click' => (($contact['click']) ? $contact['click'] : ''),
|
||||
'$class' => $class,
|
||||
'$url' => $url,
|
||||
'$photo' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
|
||||
'$name' => $contact['name'],
|
||||
'title' => $contact['name'] . ' [' . $contact['addr'] . ']',
|
||||
'$parkle' => $sparkle,
|
||||
'$redir' => $redir,
|
||||
|
||||
));
|
||||
}
|
||||
else {
|
||||
return '<div class="contact-block-div' . $class . '"><a class="contact-block-link' . $class . $sparkle
|
||||
. (($click) ? ' fakelink' : '') . '" '
|
||||
. (($redir) ? ' target="redir" ' : '')
|
||||
. (($url) ? ' href="' . $url . '"' : '') . $click . ' ><img class="contact-block-img' . $class . $sparkle . '" src="'
|
||||
. proxy_url($contact['micro'], false, PROXY_SIZE_THUMB) . '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
|
||||
. '" /></a></div>' . "\r\n";
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
|
||||
|
@ -969,7 +1006,7 @@ function search($s,$id='search-box',$url='search',$save = false, $aside = true)
|
|||
$a = get_app();
|
||||
|
||||
$values = array(
|
||||
'$s' => $s,
|
||||
'$s' => htmlspecialchars($s),
|
||||
'$id' => $id,
|
||||
'$action_url' => $url,
|
||||
'$search_label' => t('Search'),
|
||||
|
@ -2087,3 +2124,54 @@ function format_network_name($network, $url = 0) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Syntax based code highlighting for popular languages.
|
||||
* @param string $s Code block
|
||||
* @param string $lang Programming language
|
||||
* @return string Formated html
|
||||
*/
|
||||
function text_highlight($s,$lang) {
|
||||
if($lang === 'js')
|
||||
$lang = 'javascript';
|
||||
|
||||
if(! strpos('Text_Highlighter',get_include_path())) {
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . 'library/Text_Highlighter');
|
||||
}
|
||||
|
||||
require_once('library/Text_Highlighter/Text/Highlighter.php');
|
||||
require_once('library/Text_Highlighter/Text/Highlighter/Renderer/Html.php');
|
||||
$options = array(
|
||||
'numbers' => HL_NUMBERS_LI,
|
||||
'tabsize' => 4,
|
||||
);
|
||||
|
||||
$tag_added = false;
|
||||
$s = trim(html_entity_decode($s,ENT_COMPAT));
|
||||
$s = str_replace(" ","\t",$s);
|
||||
|
||||
// The highlighter library insists on an opening php tag for php code blocks. If
|
||||
// it isn't present, nothing is highlighted. So we're going to see if it's present.
|
||||
// If not, we'll add it, and then quietly remove it after we get the processed output back.
|
||||
|
||||
if($lang === 'php') {
|
||||
if(strpos('<?php',$s) !== 0) {
|
||||
$s = '<?php' . "\n" . $s;
|
||||
$tag_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
$renderer = new Text_Highlighter_Renderer_HTML($options);
|
||||
$hl = Text_Highlighter::factory($lang);
|
||||
$hl->setRenderer($renderer);
|
||||
$o = $hl->highlight($s);
|
||||
$o = str_replace([" ","\n"],[" ",''],$o);
|
||||
|
||||
if($tag_added) {
|
||||
$b = substr($o,0,strpos($o,'<li>'));
|
||||
$e = substr($o,strpos($o,'</li>'));
|
||||
$o = $b . $e;
|
||||
}
|
||||
|
||||
return('<code>' . $o . '</code>');
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<?php
|
||||
function add_thread($itemid, $onlyshadow = false) {
|
||||
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
|
||||
`deleted`, `origin`, `forum_mode`, `mention`, `network` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
|
||||
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
|
||||
`moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
|
||||
`deleted`, `origin`, `forum_mode`, `mention`, `network`, `author-id`, `owner-id`
|
||||
FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
|
||||
|
||||
if (!$items)
|
||||
return;
|
||||
|
@ -16,42 +18,70 @@ function add_thread($itemid, $onlyshadow = false) {
|
|||
.implode("', '", array_values($item))
|
||||
."')");
|
||||
|
||||
logger("add_thread: Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
|
||||
logger("Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
// is it already a copy?
|
||||
if (($itemid == 0) OR ($item['uid'] == 0))
|
||||
/**
|
||||
* @brief Add a shadow entry for a given item id that is a thread starter
|
||||
*
|
||||
* We store every public item entry additionally with the user id "0".
|
||||
* This is used for the community page and for the search.
|
||||
* It is planned that in the future we will store public item entries only once.
|
||||
*
|
||||
* @param integer $itemid Item ID that should be added
|
||||
*/
|
||||
function add_shadow_thread($itemid) {
|
||||
$items = q("SELECT `uid`, `wall`, `private`, `moderated`, `visible`, `contact-id`, `deleted`, `network`
|
||||
FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
|
||||
|
||||
if (!dbm::is_result($items)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $items[0];
|
||||
|
||||
// is it already a copy?
|
||||
if (($itemid == 0) OR ($item['uid'] == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is it a visible public post?
|
||||
if (!$item["visible"] OR $item["deleted"] OR $item["moderated"] OR $item["private"])
|
||||
if (!$item["visible"] OR $item["deleted"] OR $item["moderated"] OR $item["private"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// is it an entry from a connector? Only add an entry for natively connected networks
|
||||
if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
|
||||
if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only do these checks if the post isn't a wall post
|
||||
if (!$item["wall"]) {
|
||||
// Check, if hide-friends is activated - then don't do a shadow entry
|
||||
$r = q("SELECT `hide-friends` FROM `profile` WHERE `is-default` AND `uid` = %d AND NOT `hide-friends`",
|
||||
$item['uid']);
|
||||
if (!count($r))
|
||||
|
||||
if (!dbm::is_result($r)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the contact is hidden or blocked
|
||||
$r = q("SELECT `id` FROM `contact` WHERE NOT `hidden` AND NOT `blocked` AND `id` = %d",
|
||||
$item['contact-id']);
|
||||
if (!count($r))
|
||||
|
||||
if (!dbm::is_result($r)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Only add a shadow, if the profile isn't hidden
|
||||
$r = q("SELECT `uid` FROM `user` where `uid` = %d AND NOT `hidewall`", $item['uid']);
|
||||
if (!count($r))
|
||||
if (!dbm::is_result($r)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = q("SELECT * FROM `item` WHERE `id` = %d",
|
||||
intval($itemid));
|
||||
$item = q("SELECT * FROM `item` WHERE `id` = %d", intval($itemid));
|
||||
|
||||
if (count($item) AND ($item[0]["allow_cid"] == '') AND ($item[0]["allow_gid"] == '') AND
|
||||
($item[0]["deny_cid"] == '') AND ($item[0]["deny_gid"] == '')) {
|
||||
|
@ -59,7 +89,7 @@ function add_thread($itemid, $onlyshadow = false) {
|
|||
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1",
|
||||
dbesc($item['uri']));
|
||||
|
||||
if (!$r) {
|
||||
if (!dbm::is_result($r)) {
|
||||
// Preparing public shadow (removing user specific data)
|
||||
require_once("include/items.php");
|
||||
require_once("include/Contact.php");
|
||||
|
@ -67,15 +97,33 @@ function add_thread($itemid, $onlyshadow = false) {
|
|||
unset($item[0]['id']);
|
||||
$item[0]['uid'] = 0;
|
||||
$item[0]['origin'] = 0;
|
||||
$item[0]['wall'] = 0;
|
||||
$item[0]['contact-id'] = get_contact($item[0]['author-link'], 0);
|
||||
|
||||
if (in_array($item[0]['type'], array("net-comment", "wall-comment"))) {
|
||||
$item[0]['type'] = 'remote-comment';
|
||||
} elseif ($item[0]['type'] == 'wall') {
|
||||
$item[0]['type'] = 'remote';
|
||||
}
|
||||
|
||||
$public_shadow = item_store($item[0], false, false, true);
|
||||
|
||||
logger("add_thread: Stored public shadow for post ".$itemid." under id ".$public_shadow, LOGGER_DEBUG);
|
||||
logger("Stored public shadow for thread ".$itemid." under id ".$public_shadow, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add_shadow_entry($item) {
|
||||
/**
|
||||
* @brief Add a shadow entry for a given item id that is a comment
|
||||
*
|
||||
* This function does the same like the function above - but for comments
|
||||
*
|
||||
* @param integer $itemid Item ID that should be added
|
||||
*/
|
||||
function add_shadow_entry($itemid) {
|
||||
|
||||
$items = q("SELECT * FROM `item` WHERE `id` = %d", intval($itemid));
|
||||
$item = $items[0];
|
||||
|
||||
// Is this a shadow entry?
|
||||
if ($item['uid'] == 0)
|
||||
|
@ -97,7 +145,16 @@ function add_shadow_entry($item) {
|
|||
|
||||
unset($item['id']);
|
||||
$item['uid'] = 0;
|
||||
$item['origin'] = 0;
|
||||
$item['wall'] = 0;
|
||||
$item['contact-id'] = get_contact($item['author-link'], 0);
|
||||
|
||||
if (in_array($item['type'], array("net-comment", "wall-comment"))) {
|
||||
$item['type'] = 'remote-comment';
|
||||
} elseif ($item['type'] == 'wall') {
|
||||
$item['type'] = 'remote';
|
||||
}
|
||||
|
||||
$public_shadow = item_store($item, false, false, true);
|
||||
|
||||
logger("Stored public shadow for comment ".$item['uri']." under id ".$public_shadow, LOGGER_DEBUG);
|
||||
|
@ -174,7 +231,7 @@ function delete_thread($itemid, $itemuri = "") {
|
|||
intval($item["uid"])
|
||||
);
|
||||
if (!count($r)) {
|
||||
$r = q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = 0)",
|
||||
$r = q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = 0",
|
||||
dbesc($itemuri)
|
||||
);
|
||||
logger("delete_thread: Deleted shadow for item ".$itemuri." - ".print_r($result, true), LOGGER_DEBUG);
|
||||
|
@ -191,8 +248,10 @@ function update_threads() {
|
|||
|
||||
logger("update_threads: fetched messages: ".count($messages));
|
||||
|
||||
while ($message = $db->qfetch())
|
||||
while ($message = $db->qfetch()) {
|
||||
add_thread($message["id"]);
|
||||
add_shadow_thread($message["id"]);
|
||||
}
|
||||
$db->qclose();
|
||||
}
|
||||
|
||||
|
@ -225,7 +284,7 @@ function update_shadow_copy() {
|
|||
|
||||
logger("fetched messages: ".count($messages));
|
||||
while ($message = $db->qfetch())
|
||||
add_thread($message["iid"], true);
|
||||
add_shadow_thread($message["iid"]);
|
||||
|
||||
$db->qclose();
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ function import_account(&$a, $file) {
|
|||
}
|
||||
|
||||
// send relocate messages
|
||||
proc_run('php', 'include/notifier.php', 'relocate', $newuid);
|
||||
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $newuid);
|
||||
|
||||
info(t("Done. You can now login with your username and password"));
|
||||
goaway($a->get_baseurl() . "/login");
|
||||
|
|
|
@ -27,8 +27,11 @@ class xml {
|
|||
foreach ($namespaces AS $nskey => $nsvalue)
|
||||
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
|
||||
|
||||
if (is_array($value)) {
|
||||
$root = new SimpleXMLElement("<".$key."/>");
|
||||
self::from_array($value, $root, $remove_header, $namespaces, false);
|
||||
} else
|
||||
$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
|
||||
|
||||
$dom = dom_import_simplexml($root)->ownerDocument;
|
||||
$dom->formatOutput = true;
|
||||
|
@ -44,7 +47,33 @@ class xml {
|
|||
}
|
||||
|
||||
foreach($array as $key => $value) {
|
||||
if ($key == "@attributes") {
|
||||
if (!isset($element) AND isset($xml))
|
||||
$element = $xml;
|
||||
|
||||
if (is_integer($key)) {
|
||||
if (isset($element)) {
|
||||
if (is_scalar($value)) {
|
||||
$element[0] = $value;
|
||||
} else {
|
||||
/// @todo: handle nested array values
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$element_parts = explode(":", $key);
|
||||
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
|
||||
$namespace = $namespaces[$element_parts[0]];
|
||||
elseif (isset($namespaces[""])) {
|
||||
$namespace = $namespaces[""];
|
||||
} else
|
||||
$namespace = NULL;
|
||||
|
||||
// Remove undefined namespaces from the key
|
||||
if ((count($element_parts) > 1) AND is_null($namespace))
|
||||
$key = $element_parts[1];
|
||||
|
||||
if (substr($key, 0, 11) == "@attributes") {
|
||||
if (!isset($element) OR !is_array($value))
|
||||
continue;
|
||||
|
||||
|
@ -61,12 +90,6 @@ class xml {
|
|||
continue;
|
||||
}
|
||||
|
||||
$element_parts = explode(":", $key);
|
||||
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
|
||||
$namespace = $namespaces[$element_parts[0]];
|
||||
else
|
||||
$namespace = NULL;
|
||||
|
||||
if (!is_array($value))
|
||||
$element = $xml->addChild($key, xmlify($value), $namespace);
|
||||
elseif (is_array($value)) {
|
||||
|
|
67
index.php
67
index.php
|
@ -19,6 +19,10 @@ require_once('object/BaseObject.php');
|
|||
$a = new App;
|
||||
BaseObject::set_app($a);
|
||||
|
||||
// We assume that the index.php is called by a frontend process
|
||||
// The value is set to "true" by default in boot.php
|
||||
$a->backend = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* Load the configuration file which contains our DB credentials.
|
||||
|
@ -41,7 +45,6 @@ $install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false
|
|||
*/
|
||||
|
||||
require_once("include/dba.php");
|
||||
require_once("include/dbm.php");
|
||||
|
||||
if(!$install) {
|
||||
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
|
||||
|
@ -54,35 +57,12 @@ if(!$install) {
|
|||
load_config('config');
|
||||
load_config('system');
|
||||
|
||||
$processlist = dbm::processlist();
|
||||
if ($processlist["list"] != "") {
|
||||
|
||||
logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
|
||||
|
||||
$max_processes = get_config('system', 'max_processes_frontend');
|
||||
if (intval($max_processes) == 0)
|
||||
$max_processes = 20;
|
||||
|
||||
if ($processlist["amount"] > $max_processes) {
|
||||
logger("Processcheck: Maximum number of processes for frontend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
|
||||
system_unavailable();
|
||||
}
|
||||
}
|
||||
|
||||
$maxsysload_frontend = intval(get_config('system','maxloadavg_frontend'));
|
||||
if($maxsysload_frontend < 1)
|
||||
$maxsysload_frontend = 50;
|
||||
|
||||
$load = current_load();
|
||||
if($load) {
|
||||
if($load > $maxsysload_frontend) {
|
||||
logger('system: load ' . $load . ' too high. Service Temporarily Unavailable.');
|
||||
if ($a->max_processes_reached() OR $a->maxload_reached()) {
|
||||
header($_SERVER["SERVER_PROTOCOL"].' 503 Service Temporarily Unavailable');
|
||||
header('Retry-After: 300');
|
||||
header('Retry-After: 120');
|
||||
header('Refresh: 120; url='.$a->get_baseurl()."/".$a->query_string);
|
||||
die("System is currently unavailable. Please try again later");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (get_config('system','force_ssl') AND ($a->get_scheme() == "http") AND
|
||||
(intval(get_config('system','ssl_policy')) == SSL_POLICY_FULL) AND
|
||||
|
@ -114,9 +94,12 @@ load_translation_table($lang);
|
|||
*
|
||||
*/
|
||||
|
||||
// Exclude the backend processes from the session management
|
||||
if (!$a->is_backend()) {
|
||||
$stamp1 = microtime(true);
|
||||
session_start();
|
||||
$a->save_timestamp($stamp1, "parser");
|
||||
}
|
||||
|
||||
/**
|
||||
* Language was set earlier, but we can over-ride it in the session.
|
||||
|
@ -126,7 +109,7 @@ if (x($_SESSION,'authenticated') && !x($_SESSION,'language')) {
|
|||
// we didn't loaded user data yet, but we need user language
|
||||
$r = q("SELECT language FROM user WHERE uid=%d", intval($_SESSION['uid']));
|
||||
$_SESSION['language'] = $lang;
|
||||
if (count($r)>0) $_SESSION['language'] = $r[0]['language'];
|
||||
if (dbm::is_result($r)) $_SESSION['language'] = $r[0]['language'];
|
||||
}
|
||||
|
||||
if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) {
|
||||
|
@ -506,6 +489,7 @@ if (isset($_GET["mode"]) AND ($_GET["mode"] == "raw")) {
|
|||
|
||||
echo substr($target->saveHTML(), 6, -8);
|
||||
|
||||
if (!$a->is_backend())
|
||||
session_write_close();
|
||||
exit;
|
||||
|
||||
|
@ -517,21 +501,20 @@ $profile = $a->profile;
|
|||
header("X-Friendica-Version: ".FRIENDICA_VERSION);
|
||||
header("Content-type: text/html; charset=utf-8");
|
||||
|
||||
|
||||
if (isset($_GET["mode"]) AND ($_GET["mode"] == "minimal")) {
|
||||
//$page['content'] = substr($target->saveHTML(), 6, -8)."\n\n".
|
||||
// '<div id="conversation-end"></div>'."\n\n";
|
||||
|
||||
require "view/minimal.php";
|
||||
} else {
|
||||
$template = 'view/theme/' . current_theme() . '/'
|
||||
. ((x($a->page,'template')) ? $a->page['template'] : 'default' ) . '.php';
|
||||
|
||||
if(file_exists($template))
|
||||
require_once($template);
|
||||
else
|
||||
require_once(str_replace('theme/' . current_theme() . '/', '', $template));
|
||||
// We use $_GET["mode"] for special page templates. So we will check if we have
|
||||
// to load another page template than the default one
|
||||
// The page templates are located in /view/php/ or in the theme directory
|
||||
if (isset($_GET["mode"])) {
|
||||
$template = theme_include($_GET["mode"].'.php');
|
||||
}
|
||||
|
||||
// If there is no page template use the default page template
|
||||
if(!$template) {
|
||||
$template = theme_include("default.php");
|
||||
}
|
||||
|
||||
require_once($template);
|
||||
|
||||
if (!$a->is_backend())
|
||||
session_write_close();
|
||||
exit;
|
||||
|
|
|
@ -41,7 +41,7 @@ function contact_search(term, callback, backend_url, type, mode) {
|
|||
postdata['conversation'] = conv_id[0];
|
||||
|
||||
if(mode !== null)
|
||||
postdata['mode'] = mode;
|
||||
postdata['smode'] = mode;
|
||||
|
||||
|
||||
$.ajax({
|
||||
|
|
30
js/main.js
30
js/main.js
|
@ -5,17 +5,14 @@
|
|||
|
||||
function _resizeIframe(obj, desth) {
|
||||
var h = obj.style.height;
|
||||
var ch = obj.contentWindow.document.body.scrollHeight + 'px';
|
||||
if (h==ch) {
|
||||
var ch = obj.contentWindow.document.body.scrollHeight;
|
||||
if (h == (ch + 'px')) {
|
||||
return;
|
||||
}
|
||||
//console.log("_resizeIframe", obj, desth, ch);
|
||||
if (desth!=ch) {
|
||||
setTimeout(_resizeIframe, 500, obj, ch);
|
||||
} else {
|
||||
if (ch>0) obj.style.height = ch;
|
||||
setTimeout(_resizeIframe, 1000, obj, ch);
|
||||
if (desth == ch && ch>0) {
|
||||
obj.style.height = ch + 'px';
|
||||
}
|
||||
setTimeout(_resizeIframe, 100, obj, ch);
|
||||
}
|
||||
|
||||
function openClose(theID) {
|
||||
|
@ -35,6 +32,11 @@
|
|||
document.getElementById(theID).style.display = "none"
|
||||
}
|
||||
|
||||
function decodeHtml(html) {
|
||||
var txt = document.createElement("textarea");
|
||||
txt.innerHTML = html;
|
||||
return txt.value;
|
||||
}
|
||||
|
||||
|
||||
var src = null;
|
||||
|
@ -125,6 +127,7 @@
|
|||
function close_last_popup_menu() {
|
||||
if(last_popup_menu) {
|
||||
last_popup_menu.hide();
|
||||
last_popup_menu.off('click', function(e) {e.stopPropagation()});
|
||||
last_popup_button.removeClass("selected");
|
||||
last_popup_menu = null;
|
||||
last_popup_button = null;
|
||||
|
@ -147,6 +150,7 @@
|
|||
last_popup_button = null;
|
||||
} else {
|
||||
last_popup_menu = menu;
|
||||
last_popup_menu.on('click', function(e) {e.stopPropagation()});
|
||||
last_popup_button = parent;
|
||||
$('#nav-notifications-menu').perfectScrollbar('update');
|
||||
}
|
||||
|
@ -259,13 +263,13 @@
|
|||
var html = notifications_tpl.format(
|
||||
e.attr('href'), // {0} // link to the source
|
||||
e.attr('photo'), // {1} // photo of the contact
|
||||
text, // {2} // preformatet text (autor + text)
|
||||
text, // {2} // preformatted text (autor + text)
|
||||
e.attr('date'), // {3} // date of notification (time ago)
|
||||
seenclass, // {4} // vistiting status of the notification
|
||||
seenclass, // {4} // visited status of the notification
|
||||
new Date(e.attr('timestamp')*1000), // {5} // date of notification
|
||||
e.attr('url'), // {6} // profile url of the contact
|
||||
e.text().format(""), // {7} // clean status text
|
||||
contact // {8} //preformatat author (name + profile url)
|
||||
e.text().format(contact), // {7} // preformatted html (text including author profile url)
|
||||
'' // {8} // Deprecated
|
||||
);
|
||||
nnm.append(html);
|
||||
});
|
||||
|
@ -275,7 +279,7 @@
|
|||
if (notification_lastitem!== null && notification_id > notification_lastitem) {
|
||||
if (getNotificationPermission()==="granted") {
|
||||
var notification = new Notification(document.title, {
|
||||
body: e.text().replace('→ ','').format(e.attr('name')),
|
||||
body: decodeHtml(e.text().replace('→ ','').format(e.attr('name'))),
|
||||
icon: e.attr('photo'),
|
||||
});
|
||||
notification['url'] = e.attr('href');
|
||||
|
|
455
library/Text_Highlighter/README
Normal file
455
library/Text_Highlighter/README
Normal file
|
@ -0,0 +1,455 @@
|
|||
# $Id$
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Text_Highlighter is a class for syntax highlighting. The main idea is to
|
||||
simplify creation of subclasses implementing syntax highlighting for
|
||||
particular language. Subclasses do not implement any new functioanality, they
|
||||
just provide syntax highlighting rules. The rules sources are in XML format.
|
||||
To create a highlighter for a language, there is no need to code a new class
|
||||
manually. Simply describe the rules in XML file and use Text_Highlighter_Generator
|
||||
to create a new class.
|
||||
|
||||
|
||||
This document does not contain a formal description of API - it is very
|
||||
simple, and I believe providing some examples of code is sufficient.
|
||||
|
||||
|
||||
Highlighter XML source
|
||||
======================
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
Creating a new syntax highlighter begins with describing the highlighting
|
||||
rules. There are two basic elements: block and region. A block is just a
|
||||
portion of text matching a regular expression and highlighted with a single
|
||||
color. Keyword is an example of a block. A region is defined by two regular
|
||||
expressions: one for start of region, and another for the end. The main
|
||||
difference from a block is that a region can contain blocks and regions
|
||||
(including same-named regions). An example of a region is a group of
|
||||
statements enclosed in curly brackets (this is used in many languages, for
|
||||
example PHP and C). Also, characters matching start and end of a region may be
|
||||
highlighted with their own color, and region contents with another.
|
||||
|
||||
Blocks and regions may be declared as contained. Contained blocks and regions
|
||||
can only appear inside regions. If a region or a block is not declared as
|
||||
contained, it can appear both on top level and inside regions. Block or region
|
||||
declared as not-contained can only appear on top level.
|
||||
|
||||
For any region, a list of blocks and regions that can appear inside this
|
||||
region can be specified.
|
||||
|
||||
In this document, the term "color group" is used. Chunks of text assigned to
|
||||
same color group will be highlighted with same color. Note that in versions
|
||||
prior 0.5.0 color goups were refered as CSS classes, but since 0.5.0 not only
|
||||
HTML output is supported, so "color group" is more appropriate term.
|
||||
|
||||
Elements
|
||||
--------
|
||||
|
||||
The toplevel element is <highlight>. Attribute lang is required and denotes
|
||||
the name of the language. Its value is used as a part of generated class name,
|
||||
and must only contain letters, digits and underscores. Optional attribute
|
||||
case, when given value yes, makes the language case sensitive (default is case
|
||||
insensitive). Allowed subelements are:
|
||||
|
||||
* <authors>: Information about the authors of the file.
|
||||
<author>: Information about a single author of the file. (May be used
|
||||
multiple times, one per author.)
|
||||
- name="...": Author's name. Required.
|
||||
- email="...": Author's email address. Optional.
|
||||
|
||||
* <default>: Default color group.
|
||||
- innerGroup="...": color group name. Required.
|
||||
|
||||
* <region>: Region definition
|
||||
- name="...": Region name. Required.
|
||||
- innerGroup="...": Default color group of region contents. Required.
|
||||
- delimGroup="...": color group of start and end of region. Optional,
|
||||
defaults to value of innerGroup attribute.
|
||||
- start="...", end="...": Regular expression matching start and end
|
||||
of region. Required. Regular expression delimiters are optional, but
|
||||
if you need to specify delimiter, use /. The only case when the
|
||||
delimiters are needed, is specifying regular expression modifiers,
|
||||
such as m or U. Examples: \/\* or /$/m.
|
||||
- contained="yes": Marks region as contained.
|
||||
- never-contained="yes": Marks region as not-contained.
|
||||
- <contains>: Elements allowed inside this region.
|
||||
- all="yes" Region can contain any other region or block
|
||||
(except not-contained). May be used multiple times.
|
||||
- <but> Do not allow certain regions or blocks.
|
||||
- region="..." Name of region not allowed within
|
||||
current region.
|
||||
- block="..." Name of block not allowed within
|
||||
current region.
|
||||
- region="..." Name of region allowed within current region.
|
||||
- block="..." Name of block allowed within current region.
|
||||
- <onlyin> Only allow this region within certain regions. May be
|
||||
used multiple times.
|
||||
- block="..." Name of parent region
|
||||
|
||||
* <block>: Block definition
|
||||
- name="...": Block name. Required.
|
||||
- innerGroup="...": color group of block contents. Optional. If not
|
||||
specified, color group of parent region or default color group will be
|
||||
used. One would only want to omit this attribute if there are
|
||||
keyword groups (see below) inherited from this block, and no special
|
||||
highlighting should apply when the block does not match the keyword.
|
||||
- match="..." Regular expression matching the block. Required.
|
||||
Regular expression delimiters are optional, but if you need to
|
||||
specify delimiter, use /. The only case when the delimiters are
|
||||
needed, is specifying regular expression modifiers, such as m or U.
|
||||
Examples: #|\/\/ or /$/m.
|
||||
- contained="yes": Marks block as contained.
|
||||
- never-contained="yes": Marks block as not-contained.
|
||||
- <onlyin> Only allow this block within certain regions. May be used
|
||||
multiple times.
|
||||
- block="..." Name of parent region
|
||||
- multiline="yes": Marks block as multi-line. By default, whole
|
||||
blocks are assumed to reside in a single line. This make the things
|
||||
faster. If you need to declare a multi-line block, use this
|
||||
attribute.
|
||||
- <partgroup>: Assigns another color group to a part of the block that
|
||||
matched a subpattern.
|
||||
- index="n": Subpattern index. Required.
|
||||
- innerGroup="...": color group name. Required.
|
||||
|
||||
This is an example from CSS highlighter: the measure is matched as
|
||||
a whole, but the measurement units are highlighted with different
|
||||
color.
|
||||
|
||||
<block name="measure" match="\d*\.?\d+(\%|em|ex|pc|pt|px|in|mm|cm)"
|
||||
innerGroup="number" contained="yes">
|
||||
<onlyin region="property"/>
|
||||
<partGroup index="1" innerGroup="string" />
|
||||
</block>
|
||||
|
||||
* <keywords>: Keyword group definition. Keyword groups are useful when you
|
||||
want to highlight some words that match a condition for a block with a
|
||||
different color. Keywords are defined with literal match, not regular
|
||||
expressions. For example, you have a block named identifier matching a
|
||||
general identifier, and want to highlight reserved words (which match
|
||||
this block as well) with different color. You inherit a keyword group
|
||||
"reserved" from "identifier" block.
|
||||
- name="...": Keyword group. Required.
|
||||
- ifdef="...", ifndef="..." : Conditional declaration. See
|
||||
"Conditions" below.
|
||||
- inherits="...": Inherited block name. Required.
|
||||
- innerGroup="...": color group of keyword group. Required.
|
||||
- case="yes|no": Overrides case-sensitivity of the language.
|
||||
Optional, defaults to global value.
|
||||
- <keyword>: Single keyword definition.
|
||||
- match="..." The keyword. Note: this is not a regular
|
||||
expression, but literal match (possibly case insensitive).
|
||||
|
||||
Note that for BC reasons element partClass is alias for partGroup, and
|
||||
attributes innerClass and delimClass are aliases of innerGroup and
|
||||
delimGroup, respectively.
|
||||
|
||||
|
||||
Conditions
|
||||
----------
|
||||
|
||||
Conditional declarations allow enabling or disabling certain highlighting
|
||||
rules at runtime. For example, Java highlighter has a very big list of
|
||||
keywords matching Java standard classes. Finding a match in this list can take
|
||||
much time. For that reason, corresponding keyword group is declared with
|
||||
"ifdef" attribute :
|
||||
|
||||
<keywords name="builtin" inherits="identifier" innerClass="builtin"
|
||||
case="yes" ifdef="java.builtins">
|
||||
<keyword match="AbstractAction" />
|
||||
<keyword match="AbstractBorder" />
|
||||
<keyword match="AbstractButton" />
|
||||
...
|
||||
...
|
||||
<keyword match="_Remote_Stub" />
|
||||
<keyword match="_ServantActivatorStub" />
|
||||
<keyword match="_ServantLocatorStub" />
|
||||
</keywords>
|
||||
|
||||
This keyword group will be only enabled when "java.builtins" is passed as an
|
||||
element of "defines" option:
|
||||
|
||||
$options = array(
|
||||
'defines' => array(
|
||||
'java.builtins',
|
||||
),
|
||||
'numbers' => HL_NUMBERS_TABLE,
|
||||
);
|
||||
$highlighter = Text_Highlighter::factory('java', $options);
|
||||
|
||||
"ifndef" attribute has reverse meaning.
|
||||
|
||||
Currently, "ifdef" and "ifndef" attributes are only supported for <keywords>
|
||||
tag.
|
||||
|
||||
|
||||
|
||||
Class generation
|
||||
================
|
||||
|
||||
Creating XML description of highlighting rules is the most complicated part of
|
||||
the process. To generate the class, you need just few lines of code:
|
||||
|
||||
<?php
|
||||
require_once 'Text/Highlighter/Generator.php';
|
||||
$generator = new Text_Highlighter_Generator('php.xml');
|
||||
$generator->generate();
|
||||
$generator->saveCode('PHP.php');
|
||||
?>
|
||||
|
||||
|
||||
|
||||
Command-line class generation tool
|
||||
==================================
|
||||
|
||||
Example from previous section looks pretty simple, but it does not handle any
|
||||
errors which may occur during parsing of XML source. The package provides a
|
||||
command-line script to make generation of classes even more simple, and takes
|
||||
care of possible errors. It is called generate (on Unix/Linux) or generate.bat
|
||||
(on Windows). This script is able to process multiple files in one run, and
|
||||
also to process XML from standard input and write generated code to standard
|
||||
output.
|
||||
|
||||
Usage:
|
||||
generate options
|
||||
|
||||
Options:
|
||||
-x filename, --xml=filename
|
||||
source XML file. Multiple input files can be specified, in which
|
||||
case each -x option must be followed by -p unless -d is specified
|
||||
Defaults to stdin
|
||||
-p filename, --php=filename
|
||||
destination PHP file. Defaults to stdout. If specied multiple times,
|
||||
each -p must follow -x
|
||||
-d dirname, --dir=dirname
|
||||
Default destination directory. File names will be taken from XML input
|
||||
("lang" attribute of <highlight> tag)
|
||||
-h, --help
|
||||
This help
|
||||
|
||||
Examples
|
||||
|
||||
Read from php.xml, write to PHP.php
|
||||
|
||||
generate -x php.xml -p PHP.php
|
||||
|
||||
Read from php.xml, write to standard output
|
||||
|
||||
generate -x php.xml
|
||||
|
||||
Read from php.xml, write to PHP.php, read from xml.xml, write to XML.php
|
||||
|
||||
generate -x php.xml -p PHP.php -x xml.xml -p XML.php
|
||||
|
||||
Read from php.xml, write to /some/dir/PHP.php, read from xml.xml, write to
|
||||
/some/dir/XML.php (assuming that xml.xml contains <highlight lang="xml">, and
|
||||
php.xml contains <highlight lang="php">)
|
||||
|
||||
generate -x php.xml -x xml.xml -d /some/dir/
|
||||
|
||||
|
||||
|
||||
Renderers
|
||||
=========
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Text_Highlighter supports renderes. Using renderers, you can get output in
|
||||
different formats. Two renderers are included in the package:
|
||||
|
||||
- HTML renderer. Generates HTML output. A style sheet should be linked to
|
||||
the document to display colored text
|
||||
|
||||
- Console renderer. Can be used to output highlighted text to
|
||||
color-capable terminals, either directly or trough less -r
|
||||
|
||||
|
||||
Renderers API
|
||||
-------------
|
||||
|
||||
Renderers are subclasses of Text_Highlighter_Renderer. Renderer should
|
||||
override at least two methods - acceptToken and getOutput. Overriding other
|
||||
methods is optional, depending on the nature of renderer's output and details
|
||||
of implementation.
|
||||
|
||||
string reset()
|
||||
resets renderer state. This method is called every time before a new
|
||||
source file is highlighted.
|
||||
|
||||
string preprocess(string $code)
|
||||
preprocesses code. Can be used, for example, to normalize whitespace
|
||||
before highlighting. Returns preprocessed string.
|
||||
|
||||
void acceptToken(string $group, string $content)
|
||||
the core method of the renderer. Highlighter passes chunks of text to
|
||||
this method in $content, and color group in $group
|
||||
|
||||
void finalize()
|
||||
signals the renderer that no more tokens are available.
|
||||
|
||||
mixed getOutput()
|
||||
returns generated output.
|
||||
|
||||
|
||||
Setting renderer options
|
||||
--------------------------------
|
||||
|
||||
Renderers accept an optional argument to their constructor - options array.
|
||||
Elements of this array are renderer-specific.
|
||||
|
||||
HTML renderer
|
||||
-------------
|
||||
|
||||
HTML renderer produces HTML output with optional line numbering. The renderer
|
||||
itself does not provide information about actual colors of highlighted text.
|
||||
Instead, <span class="hl-XXX"> is used, where XXX is replaced with color group
|
||||
name (hl-var, hl-string, etc.). It is up to you to create a CSS stylesheet.
|
||||
If 'use_language' option with value evaluating to true was passed, class names
|
||||
will be formatted as "LANG-hl-XXX", where LANG is language name as defined in
|
||||
highlighter XML source ("lang" attribute of <highlight> tag) in lower case.
|
||||
|
||||
There are 3 special CSS classes:
|
||||
|
||||
hl-main - this class applies to whole output or right table column,
|
||||
depending on 'numbers' option
|
||||
hl-gutter - applies to left column in table
|
||||
hl-table - applies to whole table
|
||||
|
||||
HTML renderer accepts following options (each being optional):
|
||||
|
||||
* numbers - line numbering style.
|
||||
0 - no numbering (default)
|
||||
HL_NUMBERS_LI - use <ol></ol> for line numbering
|
||||
HL_NUMBERS_TABLE - create a 2-column table, with line numbers in left
|
||||
column and highlighted text in right column
|
||||
|
||||
* tabsize - tabulation size. Defaults to 4
|
||||
|
||||
Example:
|
||||
|
||||
require_once 'Text/Highlighter/Renderer/Html.php';
|
||||
$options = array(
|
||||
'numbers' => HL_NUMBERS_LI,
|
||||
'tabsize' => 8,
|
||||
);
|
||||
$renderer = new Text_Highlighter_Renderer_HTML($options);
|
||||
|
||||
Console renderer
|
||||
----------------
|
||||
|
||||
Console renderer produces output for displaying on a color-capable terminal,
|
||||
either directly or through less -r, using ANSI escape sequences. By default,
|
||||
this renderer only highlights most common color groups. Additional colors
|
||||
can be specified using 'colors' option. This renderer also accepts 'numbers'
|
||||
option - a boolean value, and 'tabsize' option.
|
||||
|
||||
Example :
|
||||
|
||||
require_once 'Text/Highlighter/Renderer/Console.php';
|
||||
$colors = array(
|
||||
'prepro' => "\033[35m",
|
||||
'types' => "\033[32m",
|
||||
);
|
||||
$options = array(
|
||||
'numbers' => true,
|
||||
'tabsize' => 8,
|
||||
'colors' => $colors,
|
||||
);
|
||||
$renderer = new Text_Highlighter_Renderer_Console($options);
|
||||
|
||||
|
||||
ANSI color escape sequences have the following format:
|
||||
|
||||
ESC[#;#;....;#m
|
||||
|
||||
where ESC is character with ASCII code 27 (033 octal, 0x1B hexadecimal). # is
|
||||
one of the following:
|
||||
|
||||
0 for normal display
|
||||
1 for bold on
|
||||
4 underline (mono only)
|
||||
5 blink on
|
||||
7 reverse video on
|
||||
8 nondisplayed (invisible)
|
||||
30 black foreground
|
||||
31 red foreground
|
||||
32 green foreground
|
||||
33 yellow foreground
|
||||
34 blue foreground
|
||||
35 magenta foreground
|
||||
36 cyan foreground
|
||||
37 white foreground
|
||||
40 black background
|
||||
41 red background
|
||||
42 green background
|
||||
43 yellow background
|
||||
44 blue background
|
||||
45 magenta background
|
||||
46 cyan background
|
||||
47 white background
|
||||
|
||||
|
||||
How to use Text_Highlighter class
|
||||
=================================
|
||||
|
||||
Creating a highlighter object
|
||||
-----------------------------
|
||||
|
||||
To create a highlighter for a certain language, use Text_Highlighter::factory()
|
||||
static method:
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
$hl = Text_Highlighter::factory('php');
|
||||
|
||||
|
||||
Setting a renderer
|
||||
------------------
|
||||
|
||||
Actual output is produced by a renderer.
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
require_once 'Text/Highlighter/Renderer/Html.php';
|
||||
$options = array(
|
||||
'numbers' => HL_NUMBERS_LI,
|
||||
'tabsize' => 8,
|
||||
);
|
||||
$renderer = new Text_Highlighter_Renderer_HTML($options);
|
||||
$hl = Text_Highlighter::factory('php');
|
||||
$hl->setRenderer($renderer);
|
||||
|
||||
Note that for BC reasons, it is possible to use highlighter without setting a
|
||||
renderer. If no renderer is set, HTML renderer will be used by default. In
|
||||
this case, you should pass options as second parameter to factory method. The
|
||||
following example works exactly as previous one:
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
$options = array(
|
||||
'numbers' => HL_NUMBERS_LI,
|
||||
'tabsize' => 8,
|
||||
);
|
||||
$hl = Text_Highlighter::factory('php', $options);
|
||||
|
||||
|
||||
Getting output
|
||||
--------------
|
||||
|
||||
And finally, do the highlighting and get the output:
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
require_once 'Text/Highlighter/Renderer/Html.php';
|
||||
$options = array(
|
||||
'numbers' => HL_NUMBERS_LI,
|
||||
'tabsize' => 8,
|
||||
);
|
||||
$renderer = new Text_Highlighter_Renderer_HTML($options);
|
||||
$hl = Text_Highlighter::factory('php');
|
||||
$hl->setRenderer($renderer);
|
||||
$html = $hl->highlight(file_get_contents('example.php'));
|
||||
|
||||
# vim: set autoindent tabstop=4 shiftwidth=4 softtabstop=4 tw=78: */
|
||||
|
12
library/Text_Highlighter/TODO
Normal file
12
library/Text_Highlighter/TODO
Normal file
|
@ -0,0 +1,12 @@
|
|||
# $Id$
|
||||
|
||||
Major issues to solve (but I currently have no idea how) :
|
||||
|
||||
- speedup highlighting process
|
||||
|
||||
- switching between highlighters depending on context, for example :
|
||||
PHP code -> HTML -> (JavaScript|CSS)
|
||||
|
||||
|
||||
# vim: set autoindent tabstop=4 shiftwidth=4 softtabstop=4 tw=78: */
|
||||
|
398
library/Text_Highlighter/Text/Highlighter.php
Normal file
398
library/Text_Highlighter/Text/Highlighter.php
Normal file
|
@ -0,0 +1,398 @@
|
|||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
/**
|
||||
* Highlighter base class
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version CVS: $Id$
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
|
||||
// require_once 'PEAR.php';
|
||||
|
||||
// {{{ BC constants
|
||||
|
||||
// BC trick : define constants related to default
|
||||
// renderer if needed
|
||||
if (!defined('HL_NUMBERS_LI')) {
|
||||
/**#@+
|
||||
* Constant for use with $options['numbers']
|
||||
* @see Text_Highlighter_Renderer_Html::_init()
|
||||
*/
|
||||
/**
|
||||
* use numbered list
|
||||
*/
|
||||
define ('HL_NUMBERS_LI' , 1);
|
||||
/**
|
||||
* Use 2-column table with line numbers in left column and code in right column.
|
||||
* Forces $options['tag'] = HL_TAG_PRE
|
||||
*/
|
||||
define ('HL_NUMBERS_TABLE' , 2);
|
||||
/**#@-*/
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ constants
|
||||
/**
|
||||
* for our purpose, it is infinity
|
||||
*/
|
||||
define ('HL_INFINITY', 1000000000);
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Text highlighter base class
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
|
||||
// {{{ Text_Highlighter
|
||||
|
||||
/**
|
||||
* Text highlighter base class
|
||||
*
|
||||
* This class implements all functions necessary for highlighting,
|
||||
* but it does not contain highlighting rules. Actual highlighting is
|
||||
* done using a descendent of this class.
|
||||
*
|
||||
* One is not supposed to manually create descendent classes.
|
||||
* Instead, describe highlighting rules in XML format and
|
||||
* use {@link Text_Highlighter_Generator} to create descendent class.
|
||||
* Alternatively, an instance of a descendent class can be created
|
||||
* directly.
|
||||
*
|
||||
* Use {@link Text_Highlighter::factory()} to create an
|
||||
* object for particular language highlighter
|
||||
*
|
||||
* Usage example
|
||||
* <code>
|
||||
*require_once 'Text/Highlighter.php';
|
||||
*$hlSQL = Text_Highlighter::factory('SQL',array('numbers'=>true));
|
||||
*echo $hlSQL->highlight('SELECT * FROM table a WHERE id = 12');
|
||||
* </code>
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @package Text_Highlighter
|
||||
* @access public
|
||||
*/
|
||||
|
||||
class Text_Highlighter
|
||||
{
|
||||
// {{{ members
|
||||
|
||||
/**
|
||||
* Syntax highlighting rules.
|
||||
* Auto-generated classes set this var
|
||||
*
|
||||
* @access protected
|
||||
* @see _init
|
||||
* @var array
|
||||
*/
|
||||
var $_syntax;
|
||||
|
||||
/**
|
||||
* Renderer object.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_renderer;
|
||||
|
||||
/**
|
||||
* Options. Keeped for BC
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $_options = array();
|
||||
|
||||
/**
|
||||
* Conditionds
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $_conditions = array();
|
||||
|
||||
/**
|
||||
* Disabled keywords
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $_disabled = array();
|
||||
|
||||
/**
|
||||
* Language
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $_language = '';
|
||||
|
||||
// }}}
|
||||
// {{{ _checkDefines
|
||||
|
||||
/**
|
||||
* Called by subclssses' constructors to enable/disable
|
||||
* optional highlighter rules
|
||||
*
|
||||
* @param array $defines Conditional defines
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
function _checkDefines()
|
||||
{
|
||||
if (isset($this->_options['defines'])) {
|
||||
$defines = $this->_options['defines'];
|
||||
} else {
|
||||
$defines = array();
|
||||
}
|
||||
foreach ($this->_conditions as $name => $actions) {
|
||||
foreach($actions as $action) {
|
||||
$present = in_array($name, $defines);
|
||||
if (!$action[1]) {
|
||||
$present = !$present;
|
||||
}
|
||||
if ($present) {
|
||||
unset($this->_disabled[$action[0]]);
|
||||
} else {
|
||||
$this->_disabled[$action[0]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ factory
|
||||
|
||||
/**
|
||||
* Create a new Highlighter object for specified language
|
||||
*
|
||||
* @param string $lang language, for example "SQL"
|
||||
* @param array $options Rendering options. This
|
||||
* parameter is only keeped for BC reasons, use
|
||||
* {@link Text_Highlighter::setRenderer()} instead
|
||||
*
|
||||
* @return mixed a newly created Highlighter object, or
|
||||
* a PEAR error object on error
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function &factory($lang, $options = array())
|
||||
{
|
||||
$lang = strtoupper($lang);
|
||||
@include_once 'Text/Highlighter/' . $lang . '.php';
|
||||
|
||||
$classname = 'Text_Highlighter_' . $lang;
|
||||
|
||||
if (!class_exists($classname)) {
|
||||
return PEAR::raiseError('Highlighter for ' . $lang . ' not found');
|
||||
}
|
||||
|
||||
$obj = new $classname($options);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setRenderer
|
||||
|
||||
/**
|
||||
* Set renderer object
|
||||
*
|
||||
* @param object $renderer Text_Highlighter_Renderer
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setRenderer(&$renderer)
|
||||
{
|
||||
$this->_renderer = $renderer;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Helper function to find matching brackets
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _matchingBrackets($str)
|
||||
{
|
||||
return strtr($str, '()<>[]{}', ')(><][}{');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function _getToken()
|
||||
{
|
||||
if (!empty($this->_tokenStack)) {
|
||||
return array_pop($this->_tokenStack);
|
||||
}
|
||||
if ($this->_pos >= $this->_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ($this->_state != -1 && preg_match($this->_endpattern, $this->_str, $m, PREG_OFFSET_CAPTURE, $this->_pos)) {
|
||||
$endpos = $m[0][1];
|
||||
$endmatch = $m[0][0];
|
||||
} else {
|
||||
$endpos = -1;
|
||||
}
|
||||
preg_match ($this->_regs[$this->_state], $this->_str, $m, PREG_OFFSET_CAPTURE, $this->_pos);
|
||||
$n = 1;
|
||||
|
||||
|
||||
foreach ($this->_counts[$this->_state] as $i=>$count) {
|
||||
if (!isset($m[$n])) {
|
||||
break;
|
||||
}
|
||||
if ($m[$n][1]>-1 && ($endpos == -1 || $m[$n][1] < $endpos)) {
|
||||
if ($this->_states[$this->_state][$i] != -1) {
|
||||
$this->_tokenStack[] = array($this->_delim[$this->_state][$i], $m[$n][0]);
|
||||
} else {
|
||||
$inner = $this->_inner[$this->_state][$i];
|
||||
if (isset($this->_parts[$this->_state][$i])) {
|
||||
$parts = array();
|
||||
$partpos = $m[$n][1];
|
||||
for ($j=1; $j<=$count; $j++) {
|
||||
if ($m[$j+$n][1] < 0) {
|
||||
continue;
|
||||
}
|
||||
if (isset($this->_parts[$this->_state][$i][$j])) {
|
||||
if ($m[$j+$n][1] > $partpos) {
|
||||
array_unshift($parts, array($inner, substr($this->_str, $partpos, $m[$j+$n][1]-$partpos)));
|
||||
}
|
||||
array_unshift($parts, array($this->_parts[$this->_state][$i][$j], $m[$j+$n][0]));
|
||||
}
|
||||
$partpos = $m[$j+$n][1] + strlen($m[$j+$n][0]);
|
||||
}
|
||||
if ($partpos < $m[$n][1] + strlen($m[$n][0])) {
|
||||
array_unshift($parts, array($inner, substr($this->_str, $partpos, $m[$n][1] - $partpos + strlen($m[$n][0]))));
|
||||
}
|
||||
$this->_tokenStack = array_merge($this->_tokenStack, $parts);
|
||||
} else {
|
||||
foreach ($this->_keywords[$this->_state][$i] as $g => $re) {
|
||||
if (isset($this->_disabled[$g])) {
|
||||
continue;
|
||||
}
|
||||
if (preg_match($re, $m[$n][0])) {
|
||||
$inner = $this->_kwmap[$g];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->_tokenStack[] = array($inner, $m[$n][0]);
|
||||
}
|
||||
}
|
||||
if ($m[$n][1] > $this->_pos) {
|
||||
$this->_tokenStack[] = array($this->_lastinner, substr($this->_str, $this->_pos, $m[$n][1]-$this->_pos));
|
||||
}
|
||||
$this->_pos = $m[$n][1] + strlen($m[$n][0]);
|
||||
if ($this->_states[$this->_state][$i] != -1) {
|
||||
$this->_stack[] = array($this->_state, $this->_lastdelim, $this->_lastinner, $this->_endpattern);
|
||||
$this->_lastinner = $this->_inner[$this->_state][$i];
|
||||
$this->_lastdelim = $this->_delim[$this->_state][$i];
|
||||
$l = $this->_state;
|
||||
$this->_state = $this->_states[$this->_state][$i];
|
||||
$this->_endpattern = $this->_end[$this->_state];
|
||||
if ($this->_subst[$l][$i]) {
|
||||
for ($k=0; $k<=$this->_counts[$l][$i]; $k++) {
|
||||
if (!isset($m[$i+$k])) {
|
||||
break;
|
||||
}
|
||||
$quoted = preg_quote($m[$n+$k][0], '/');
|
||||
$this->_endpattern = str_replace('%'.$k.'%', $quoted, $this->_endpattern);
|
||||
$this->_endpattern = str_replace('%b'.$k.'%', $this->_matchingBrackets($quoted), $this->_endpattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_pop($this->_tokenStack);
|
||||
}
|
||||
$n += $count + 1;
|
||||
}
|
||||
|
||||
if ($endpos > -1) {
|
||||
$this->_tokenStack[] = array($this->_lastdelim, $endmatch);
|
||||
if ($endpos > $this->_pos) {
|
||||
$this->_tokenStack[] = array($this->_lastinner, substr($this->_str, $this->_pos, $endpos-$this->_pos));
|
||||
}
|
||||
list($this->_state, $this->_lastdelim, $this->_lastinner, $this->_endpattern) = array_pop($this->_stack);
|
||||
$this->_pos = $endpos + strlen($endmatch);
|
||||
return array_pop($this->_tokenStack);
|
||||
}
|
||||
$p = $this->_pos;
|
||||
$this->_pos = HL_INFINITY;
|
||||
return array($this->_lastinner, substr($this->_str, $p));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// {{{ highlight
|
||||
|
||||
/**
|
||||
* Highlights code
|
||||
*
|
||||
* @param string $str Code to highlight
|
||||
* @access public
|
||||
* @return string Highlighted text
|
||||
*
|
||||
*/
|
||||
|
||||
function highlight($str)
|
||||
{
|
||||
if (!($this->_renderer)) {
|
||||
include_once('Text/Highlighter/Renderer/Html.php');
|
||||
$this->_renderer = new Text_Highlighter_Renderer_Html($this->_options);
|
||||
}
|
||||
$this->_state = -1;
|
||||
$this->_pos = 0;
|
||||
$this->_stack = array();
|
||||
$this->_tokenStack = array();
|
||||
$this->_lastinner = $this->_defClass;
|
||||
$this->_lastdelim = $this->_defClass;
|
||||
$this->_endpattern = '';
|
||||
$this->_renderer->reset();
|
||||
$this->_renderer->setCurrentLanguage($this->_language);
|
||||
$this->_str = $this->_renderer->preprocess($str);
|
||||
$this->_len = strlen($this->_str);
|
||||
while ($token = $this->_getToken()) {
|
||||
$this->_renderer->acceptToken($token[0], $token[1]);
|
||||
}
|
||||
$this->_renderer->finalize();
|
||||
return $this->_renderer->getOutput();
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* c-hanging-comment-ender-p: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
519
library/Text_Highlighter/Text/Highlighter/ABAP.php
Normal file
519
library/Text_Highlighter/Text/Highlighter/ABAP.php
Normal file
|
@ -0,0 +1,519 @@
|
|||
<?php
|
||||
/**
|
||||
* Auto-generated class. ABAP syntax highlighting
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: : abap.xml,v 1.1 2007/06/03 02:35:28 ssttoo Exp
|
||||
* @author Stoyan Stefanov <ssttoo@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. ABAP syntax highlighting
|
||||
*
|
||||
* @author Stoyan Stefanov <ssttoo@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_ABAP extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'abap';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_ABAP($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)^\\*|")|((?i)\')|((?i)[a-z_\\-]\\w*)/',
|
||||
0 => '/((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)^\\*|")|((?i)\')|((?i)0[xX][\\da-f]+)|((?i)\\d\\d*|\\b0\\b)|((?i)0[0-7]+)|((?i)(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?i)[a-z_\\-]\\w*)/',
|
||||
1 => '/((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)^\\*|")|((?i)\')|((?i)0[xX][\\da-f]+)|((?i)\\d\\d*|\\b0\\b)|((?i)0[0-7]+)|((?i)(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?i)[a-z_\\-]\\w*)/',
|
||||
2 => '/((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)^\\*|")|((?i)\')|((?i)0[xX][\\da-f]+)|((?i)\\d\\d*|\\b0\\b)|((?i)0[0-7]+)|((?i)(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?i)[a-z_\\-]\\w*)/',
|
||||
3 => '//',
|
||||
4 => '//',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'brackets',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'comment',
|
||||
4 => 'quotes',
|
||||
5 => '',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 'brackets',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'comment',
|
||||
4 => 'quotes',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => '',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'brackets',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'comment',
|
||||
4 => 'quotes',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => '',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'brackets',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'comment',
|
||||
4 => 'quotes',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => '',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'code',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'comment',
|
||||
4 => 'string',
|
||||
5 => 'identifier',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 'code',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'comment',
|
||||
4 => 'string',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'identifier',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'code',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'comment',
|
||||
4 => 'string',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'identifier',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'code',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'comment',
|
||||
4 => 'string',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'identifier',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?i)\\}/',
|
||||
1 => '/(?i)\\)/',
|
||||
2 => '/(?i)\\]/',
|
||||
3 => '/(?mi)$/',
|
||||
4 => '/(?i)\'/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 =>
|
||||
array (
|
||||
'sy' => '/^((?i)screen-name|screen-group1|screen-group2|screen-group3|screen-group4|screen-required|screen-input|screen-output|screen-intensified|screen-invisible|screen-length|screen-active|sy-index|sy-pagno|sy-tabix|sy-tfill|sy-tlopc|sy-tmaxl|sy-toccu|sy-ttabc|sy-tstis|sy-ttabi|sy-dbcnt|sy-fdpos|sy-colno|sy-linct|sy-linno|sy-linsz|sy-pagct|sy-macol|sy-marow|sy-tleng|sy-sfoff|sy-willi|sy-lilli|sy-subrc|sy-fleng|sy-cucol|sy-curow|sy-lsind|sy-listi|sy-stepl|sy-tpagi|sy-winx1|sy-winy1|sy-winx2|sy-winy2|sy-winco|sy-winro|sy-windi|sy-srows|sy-scols|sy-loopc|sy-folen|sy-fodec|sy-tzone|sy-dayst|sy-ftype|sy-appli|sy-fdayw|sy-ccurs|sy-ccurt|sy-debug|sy-ctype|sy-input|sy-langu|sy-modno|sy-batch|sy-binpt|sy-calld|sy-dynnr|sy-dyngr|sy-newpa|sy-pri40|sy-rstrt|sy-wtitl|sy-cpage|sy-dbnam|sy-mandt|sy-prefx|sy-fmkey|sy-pexpi|sy-prini|sy-primm|sy-prrel|sy-playo|sy-prbig|sy-playp|sy-prnew|sy-prlog|sy-pdest|sy-plist|sy-pauth|sy-prdsn|sy-pnwpa|sy-callr|sy-repi2|sy-rtitl|sy-prrec|sy-prtxt|sy-prabt|sy-lpass|sy-nrpag|sy-paart|sy-prcop|sy-batzs|sy-bspld|sy-brep4|sy-batzo|sy-batzd|sy-batzw|sy-batzm|sy-ctabl|sy-dbsys|sy-dcsys|sy-macdb|sy-sysid|sy-opsys|sy-pfkey|sy-saprl|sy-tcode|sy-ucomm|sy-cfwae|sy-chwae|sy-spono|sy-sponr|sy-waers|sy-cdate|sy-datum|sy-slset|sy-subty|sy-subcs|sy-group|sy-ffile|sy-uzeit|sy-dsnam|sy-repid|sy-tabid|sy-tfdsn|sy-uname|sy-lstat|sy-abcde|sy-marky|sy-sfnam|sy-tname|sy-msgli|sy-title|sy-entry|sy-lisel|sy-uline|sy-xcode|sy-cprog|sy-xprog|sy-xform|sy-ldbpg|sy-tvar0|sy-tvar1|sy-tvar2|sy-tvar3|sy-tvar4|sy-tvar5|sy-tvar6|sy-tvar7|sy-tvar8|sy-tvar9|sy-msgid|sy-msgty|sy-msgno|sy-msgv1|sy-msgv2|sy-msgv3|sy-msgv4|sy-oncom|sy-vline|sy-winsl|sy-staco|sy-staro|sy-datar|sy-host|sy-locdb|sy-locop|sy-datlo|sy-timlo|sy-zonlo|syst-index|syst-pagno|syst-tabix|syst-tfill|syst-tlopc|syst-tmaxl|syst-toccu|syst-ttabc|syst-tstis|syst-ttabi|syst-dbcnt|syst-fdpos|syst-colno|syst-linct|syst-linno|syst-linsz|syst-pagct|syst-macol|syst-marow|syst-tleng|syst-sfoff|syst-willi|syst-lilli|syst-subrc|syst-fleng|syst-cucol|syst-curow|syst-lsind|syst-listi|syst-stepl|syst-tpagi|syst-winx1|syst-winy1|syst-winx2|syst-winy2|syst-winco|syst-winro|syst-windi|syst-srows|syst-scols|syst-loopc|syst-folen|syst-fodec|syst-tzone|syst-dayst|syst-ftype|syst-appli|syst-fdayw|syst-ccurs|syst-ccurt|syst-debug|syst-ctype|syst-input|syst-langu|syst-modno|syst-batch|syst-binpt|syst-calld|syst-dynnr|syst-dyngr|syst-newpa|syst-pri40|syst-rstrt|syst-wtitl|syst-cpage|syst-dbnam|syst-mandt|syst-prefx|syst-fmkey|syst-pexpi|syst-prini|syst-primm|syst-prrel|syst-playo|syst-prbig|syst-playp|syst-prnew|syst-prlog|syst-pdest|syst-plist|syst-pauth|syst-prdsn|syst-pnwpa|syst-callr|syst-repi2|syst-rtitl|syst-prrec|syst-prtxt|syst-prabt|syst-lpass|syst-nrpag|syst-paart|syst-prcop|syst-batzs|syst-bspld|syst-brep4|syst-batzo|syst-batzd|syst-batzw|syst-batzm|syst-ctabl|syst-dbsys|syst-dcsys|syst-macdb|syst-sysid|syst-opsys|syst-pfkey|syst-saprl|syst-tcode|syst-ucomm|syst-cfwae|syst-chwae|syst-spono|syst-sponr|syst-waers|syst-cdate|syst-datum|syst-slset|syst-subty|syst-subcs|syst-group|syst-ffile|syst-uzeit|syst-dsnam|syst-repid|syst-tabid|syst-tfdsn|syst-uname|syst-lstat|syst-abcde|syst-marky|syst-sfnam|syst-tname|syst-msgli|syst-title|syst-entry|syst-lisel|syst-uline|syst-xcode|syst-cprog|syst-xprog|syst-xform|syst-ldbpg|syst-tvar0|syst-tvar1|syst-tvar2|syst-tvar3|syst-tvar4|syst-tvar5|syst-tvar6|syst-tvar7|syst-tvar8|syst-tvar9|syst-msgid|syst-msgty|syst-msgno|syst-msgv1|syst-msgv2|syst-msgv3|syst-msgv4|syst-oncom|syst-vline|syst-winsl|syst-staco|syst-staro|syst-datar|syst-host|syst-locdb|syst-locop|syst-datlo|syst-timlo|syst-zonlo)$/',
|
||||
'reserved' => '/^((?i)abs|acos|add|add-corresponding|adjacent|after|aliases|all|analyzer|and|any|append|as|ascending|asin|assign|assigned|assigning|at|atan|authority-check|avg|back|before|begin|binary|bit|bit-and|bit-not|bit-or|bit-xor|blank|block|break-point|buffer|by|c|call|case|catch|ceil|centered|chain|change|changing|check|checkbox|class|class-data|class-events|class-methods|class-pool|clear|client|close|cnt|code|collect|color|comment|commit|communication|compute|concatenate|condense|constants|context|contexts|continue|control|controls|convert|copy|corresponding|cos|cosh|count|country|create|currency|cursor|customer-function|data|database|dataset|delete|decimals|default|define|demand|descending|describe|dialog|distinct|div|divide|divide-corresponding|do|duplicates|dynpro|edit|editor-call|else|elseif|end|end-of-definition|end-of-page|end-of-selection|endat|endcase|endcatch|endchain|endclass|enddo|endexec|endform|endfunction|endif|endinterface|endloop|endmethod|endmodule|endon|endprovide|endselect|endwhile|entries|events|exec|exit|exit-command|exp|exponent|export|exporting|exceptions|extended|extract|fetch|field|field-groups|field-symbols|fields|floor|for|form|format|frac|frame|free|from|function|function-pool|generate|get|group|hashed|header|help-id|help-request|hide|hotspot|icon|id|if|import|importing|include|index|infotypes|initialization|inner|input|insert|intensified|interface|interface-pool|interfaces|into|inverse|join|key|language|last|leave|left|left-justified|like|line|line-count|line-selection|line-size|lines|list-processing|load|load-of-program|local|locale|log|log10|loop|m|margin|mask|matchcode|max|memory|message|message-id|messages|method|methods|min|mod|mode|modif|modify|module|move|move-corresponding|multiply|multiply-corresponding|new|new-line|new-page|next|no|no-gap|no-gaps|no-heading|no-scrolling|no-sign|no-title|no-zero|nodes|non-unique|o|object|obligatory|occurs|of|off|on|open|or|order|others|outer|output|overlay|pack|page|parameter|parameters|perform|pf-status|position|print|print-control|private|process|program|property|protected|provide|public|put|radiobutton|raise|raising|range|ranges|read|receive|refresh|reject|replace|report|requested|reserve|reset|right-justified|rollback|round|rows|rtti|run|scan|screen|search|separated|scroll|scroll-boundary|select|select-options|selection-screen|selection-table|set|shared|shift|sign|sin|single|sinh|size|skip|sort|sorted|split|sql|sqrt|stamp|standard|start-of-selection|statics|stop|string|strlen|structure|submit|subtract|subtract-corresponding|sum|supply|suppress|symbol|syntax-check|syntax-trace|system-call|system-exceptions|table|table_line|tables|tan|tanh|text|textpool|time|times|title|titlebar|to|top-of-page|transaction|transfer|translate|transporting|trunc|type|type-pool|type-pools|types|uline|under|unique|unit|unpack|up|update|user-command|using|value|value-request|values|vary|when|where|while|window|with|with-title|work|write|x|xstring|z|zone)$/',
|
||||
'constants' => '/^((?i)initial|null|space|col_background|col_heading|col_normal|col_total|col_key|col_positive|col_negative|col_group)$/',
|
||||
),
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
'sy' => '/^((?i)screen-name|screen-group1|screen-group2|screen-group3|screen-group4|screen-required|screen-input|screen-output|screen-intensified|screen-invisible|screen-length|screen-active|sy-index|sy-pagno|sy-tabix|sy-tfill|sy-tlopc|sy-tmaxl|sy-toccu|sy-ttabc|sy-tstis|sy-ttabi|sy-dbcnt|sy-fdpos|sy-colno|sy-linct|sy-linno|sy-linsz|sy-pagct|sy-macol|sy-marow|sy-tleng|sy-sfoff|sy-willi|sy-lilli|sy-subrc|sy-fleng|sy-cucol|sy-curow|sy-lsind|sy-listi|sy-stepl|sy-tpagi|sy-winx1|sy-winy1|sy-winx2|sy-winy2|sy-winco|sy-winro|sy-windi|sy-srows|sy-scols|sy-loopc|sy-folen|sy-fodec|sy-tzone|sy-dayst|sy-ftype|sy-appli|sy-fdayw|sy-ccurs|sy-ccurt|sy-debug|sy-ctype|sy-input|sy-langu|sy-modno|sy-batch|sy-binpt|sy-calld|sy-dynnr|sy-dyngr|sy-newpa|sy-pri40|sy-rstrt|sy-wtitl|sy-cpage|sy-dbnam|sy-mandt|sy-prefx|sy-fmkey|sy-pexpi|sy-prini|sy-primm|sy-prrel|sy-playo|sy-prbig|sy-playp|sy-prnew|sy-prlog|sy-pdest|sy-plist|sy-pauth|sy-prdsn|sy-pnwpa|sy-callr|sy-repi2|sy-rtitl|sy-prrec|sy-prtxt|sy-prabt|sy-lpass|sy-nrpag|sy-paart|sy-prcop|sy-batzs|sy-bspld|sy-brep4|sy-batzo|sy-batzd|sy-batzw|sy-batzm|sy-ctabl|sy-dbsys|sy-dcsys|sy-macdb|sy-sysid|sy-opsys|sy-pfkey|sy-saprl|sy-tcode|sy-ucomm|sy-cfwae|sy-chwae|sy-spono|sy-sponr|sy-waers|sy-cdate|sy-datum|sy-slset|sy-subty|sy-subcs|sy-group|sy-ffile|sy-uzeit|sy-dsnam|sy-repid|sy-tabid|sy-tfdsn|sy-uname|sy-lstat|sy-abcde|sy-marky|sy-sfnam|sy-tname|sy-msgli|sy-title|sy-entry|sy-lisel|sy-uline|sy-xcode|sy-cprog|sy-xprog|sy-xform|sy-ldbpg|sy-tvar0|sy-tvar1|sy-tvar2|sy-tvar3|sy-tvar4|sy-tvar5|sy-tvar6|sy-tvar7|sy-tvar8|sy-tvar9|sy-msgid|sy-msgty|sy-msgno|sy-msgv1|sy-msgv2|sy-msgv3|sy-msgv4|sy-oncom|sy-vline|sy-winsl|sy-staco|sy-staro|sy-datar|sy-host|sy-locdb|sy-locop|sy-datlo|sy-timlo|sy-zonlo|syst-index|syst-pagno|syst-tabix|syst-tfill|syst-tlopc|syst-tmaxl|syst-toccu|syst-ttabc|syst-tstis|syst-ttabi|syst-dbcnt|syst-fdpos|syst-colno|syst-linct|syst-linno|syst-linsz|syst-pagct|syst-macol|syst-marow|syst-tleng|syst-sfoff|syst-willi|syst-lilli|syst-subrc|syst-fleng|syst-cucol|syst-curow|syst-lsind|syst-listi|syst-stepl|syst-tpagi|syst-winx1|syst-winy1|syst-winx2|syst-winy2|syst-winco|syst-winro|syst-windi|syst-srows|syst-scols|syst-loopc|syst-folen|syst-fodec|syst-tzone|syst-dayst|syst-ftype|syst-appli|syst-fdayw|syst-ccurs|syst-ccurt|syst-debug|syst-ctype|syst-input|syst-langu|syst-modno|syst-batch|syst-binpt|syst-calld|syst-dynnr|syst-dyngr|syst-newpa|syst-pri40|syst-rstrt|syst-wtitl|syst-cpage|syst-dbnam|syst-mandt|syst-prefx|syst-fmkey|syst-pexpi|syst-prini|syst-primm|syst-prrel|syst-playo|syst-prbig|syst-playp|syst-prnew|syst-prlog|syst-pdest|syst-plist|syst-pauth|syst-prdsn|syst-pnwpa|syst-callr|syst-repi2|syst-rtitl|syst-prrec|syst-prtxt|syst-prabt|syst-lpass|syst-nrpag|syst-paart|syst-prcop|syst-batzs|syst-bspld|syst-brep4|syst-batzo|syst-batzd|syst-batzw|syst-batzm|syst-ctabl|syst-dbsys|syst-dcsys|syst-macdb|syst-sysid|syst-opsys|syst-pfkey|syst-saprl|syst-tcode|syst-ucomm|syst-cfwae|syst-chwae|syst-spono|syst-sponr|syst-waers|syst-cdate|syst-datum|syst-slset|syst-subty|syst-subcs|syst-group|syst-ffile|syst-uzeit|syst-dsnam|syst-repid|syst-tabid|syst-tfdsn|syst-uname|syst-lstat|syst-abcde|syst-marky|syst-sfnam|syst-tname|syst-msgli|syst-title|syst-entry|syst-lisel|syst-uline|syst-xcode|syst-cprog|syst-xprog|syst-xform|syst-ldbpg|syst-tvar0|syst-tvar1|syst-tvar2|syst-tvar3|syst-tvar4|syst-tvar5|syst-tvar6|syst-tvar7|syst-tvar8|syst-tvar9|syst-msgid|syst-msgty|syst-msgno|syst-msgv1|syst-msgv2|syst-msgv3|syst-msgv4|syst-oncom|syst-vline|syst-winsl|syst-staco|syst-staro|syst-datar|syst-host|syst-locdb|syst-locop|syst-datlo|syst-timlo|syst-zonlo)$/',
|
||||
'reserved' => '/^((?i)abs|acos|add|add-corresponding|adjacent|after|aliases|all|analyzer|and|any|append|as|ascending|asin|assign|assigned|assigning|at|atan|authority-check|avg|back|before|begin|binary|bit|bit-and|bit-not|bit-or|bit-xor|blank|block|break-point|buffer|by|c|call|case|catch|ceil|centered|chain|change|changing|check|checkbox|class|class-data|class-events|class-methods|class-pool|clear|client|close|cnt|code|collect|color|comment|commit|communication|compute|concatenate|condense|constants|context|contexts|continue|control|controls|convert|copy|corresponding|cos|cosh|count|country|create|currency|cursor|customer-function|data|database|dataset|delete|decimals|default|define|demand|descending|describe|dialog|distinct|div|divide|divide-corresponding|do|duplicates|dynpro|edit|editor-call|else|elseif|end|end-of-definition|end-of-page|end-of-selection|endat|endcase|endcatch|endchain|endclass|enddo|endexec|endform|endfunction|endif|endinterface|endloop|endmethod|endmodule|endon|endprovide|endselect|endwhile|entries|events|exec|exit|exit-command|exp|exponent|export|exporting|exceptions|extended|extract|fetch|field|field-groups|field-symbols|fields|floor|for|form|format|frac|frame|free|from|function|function-pool|generate|get|group|hashed|header|help-id|help-request|hide|hotspot|icon|id|if|import|importing|include|index|infotypes|initialization|inner|input|insert|intensified|interface|interface-pool|interfaces|into|inverse|join|key|language|last|leave|left|left-justified|like|line|line-count|line-selection|line-size|lines|list-processing|load|load-of-program|local|locale|log|log10|loop|m|margin|mask|matchcode|max|memory|message|message-id|messages|method|methods|min|mod|mode|modif|modify|module|move|move-corresponding|multiply|multiply-corresponding|new|new-line|new-page|next|no|no-gap|no-gaps|no-heading|no-scrolling|no-sign|no-title|no-zero|nodes|non-unique|o|object|obligatory|occurs|of|off|on|open|or|order|others|outer|output|overlay|pack|page|parameter|parameters|perform|pf-status|position|print|print-control|private|process|program|property|protected|provide|public|put|radiobutton|raise|raising|range|ranges|read|receive|refresh|reject|replace|report|requested|reserve|reset|right-justified|rollback|round|rows|rtti|run|scan|screen|search|separated|scroll|scroll-boundary|select|select-options|selection-screen|selection-table|set|shared|shift|sign|sin|single|sinh|size|skip|sort|sorted|split|sql|sqrt|stamp|standard|start-of-selection|statics|stop|string|strlen|structure|submit|subtract|subtract-corresponding|sum|supply|suppress|symbol|syntax-check|syntax-trace|system-call|system-exceptions|table|table_line|tables|tan|tanh|text|textpool|time|times|title|titlebar|to|top-of-page|transaction|transfer|translate|transporting|trunc|type|type-pool|type-pools|types|uline|under|unique|unit|unpack|up|update|user-command|using|value|value-request|values|vary|when|where|while|window|with|with-title|work|write|x|xstring|z|zone)$/',
|
||||
'constants' => '/^((?i)initial|null|space|col_background|col_heading|col_normal|col_total|col_key|col_positive|col_negative|col_group)$/',
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
'sy' => '/^((?i)screen-name|screen-group1|screen-group2|screen-group3|screen-group4|screen-required|screen-input|screen-output|screen-intensified|screen-invisible|screen-length|screen-active|sy-index|sy-pagno|sy-tabix|sy-tfill|sy-tlopc|sy-tmaxl|sy-toccu|sy-ttabc|sy-tstis|sy-ttabi|sy-dbcnt|sy-fdpos|sy-colno|sy-linct|sy-linno|sy-linsz|sy-pagct|sy-macol|sy-marow|sy-tleng|sy-sfoff|sy-willi|sy-lilli|sy-subrc|sy-fleng|sy-cucol|sy-curow|sy-lsind|sy-listi|sy-stepl|sy-tpagi|sy-winx1|sy-winy1|sy-winx2|sy-winy2|sy-winco|sy-winro|sy-windi|sy-srows|sy-scols|sy-loopc|sy-folen|sy-fodec|sy-tzone|sy-dayst|sy-ftype|sy-appli|sy-fdayw|sy-ccurs|sy-ccurt|sy-debug|sy-ctype|sy-input|sy-langu|sy-modno|sy-batch|sy-binpt|sy-calld|sy-dynnr|sy-dyngr|sy-newpa|sy-pri40|sy-rstrt|sy-wtitl|sy-cpage|sy-dbnam|sy-mandt|sy-prefx|sy-fmkey|sy-pexpi|sy-prini|sy-primm|sy-prrel|sy-playo|sy-prbig|sy-playp|sy-prnew|sy-prlog|sy-pdest|sy-plist|sy-pauth|sy-prdsn|sy-pnwpa|sy-callr|sy-repi2|sy-rtitl|sy-prrec|sy-prtxt|sy-prabt|sy-lpass|sy-nrpag|sy-paart|sy-prcop|sy-batzs|sy-bspld|sy-brep4|sy-batzo|sy-batzd|sy-batzw|sy-batzm|sy-ctabl|sy-dbsys|sy-dcsys|sy-macdb|sy-sysid|sy-opsys|sy-pfkey|sy-saprl|sy-tcode|sy-ucomm|sy-cfwae|sy-chwae|sy-spono|sy-sponr|sy-waers|sy-cdate|sy-datum|sy-slset|sy-subty|sy-subcs|sy-group|sy-ffile|sy-uzeit|sy-dsnam|sy-repid|sy-tabid|sy-tfdsn|sy-uname|sy-lstat|sy-abcde|sy-marky|sy-sfnam|sy-tname|sy-msgli|sy-title|sy-entry|sy-lisel|sy-uline|sy-xcode|sy-cprog|sy-xprog|sy-xform|sy-ldbpg|sy-tvar0|sy-tvar1|sy-tvar2|sy-tvar3|sy-tvar4|sy-tvar5|sy-tvar6|sy-tvar7|sy-tvar8|sy-tvar9|sy-msgid|sy-msgty|sy-msgno|sy-msgv1|sy-msgv2|sy-msgv3|sy-msgv4|sy-oncom|sy-vline|sy-winsl|sy-staco|sy-staro|sy-datar|sy-host|sy-locdb|sy-locop|sy-datlo|sy-timlo|sy-zonlo|syst-index|syst-pagno|syst-tabix|syst-tfill|syst-tlopc|syst-tmaxl|syst-toccu|syst-ttabc|syst-tstis|syst-ttabi|syst-dbcnt|syst-fdpos|syst-colno|syst-linct|syst-linno|syst-linsz|syst-pagct|syst-macol|syst-marow|syst-tleng|syst-sfoff|syst-willi|syst-lilli|syst-subrc|syst-fleng|syst-cucol|syst-curow|syst-lsind|syst-listi|syst-stepl|syst-tpagi|syst-winx1|syst-winy1|syst-winx2|syst-winy2|syst-winco|syst-winro|syst-windi|syst-srows|syst-scols|syst-loopc|syst-folen|syst-fodec|syst-tzone|syst-dayst|syst-ftype|syst-appli|syst-fdayw|syst-ccurs|syst-ccurt|syst-debug|syst-ctype|syst-input|syst-langu|syst-modno|syst-batch|syst-binpt|syst-calld|syst-dynnr|syst-dyngr|syst-newpa|syst-pri40|syst-rstrt|syst-wtitl|syst-cpage|syst-dbnam|syst-mandt|syst-prefx|syst-fmkey|syst-pexpi|syst-prini|syst-primm|syst-prrel|syst-playo|syst-prbig|syst-playp|syst-prnew|syst-prlog|syst-pdest|syst-plist|syst-pauth|syst-prdsn|syst-pnwpa|syst-callr|syst-repi2|syst-rtitl|syst-prrec|syst-prtxt|syst-prabt|syst-lpass|syst-nrpag|syst-paart|syst-prcop|syst-batzs|syst-bspld|syst-brep4|syst-batzo|syst-batzd|syst-batzw|syst-batzm|syst-ctabl|syst-dbsys|syst-dcsys|syst-macdb|syst-sysid|syst-opsys|syst-pfkey|syst-saprl|syst-tcode|syst-ucomm|syst-cfwae|syst-chwae|syst-spono|syst-sponr|syst-waers|syst-cdate|syst-datum|syst-slset|syst-subty|syst-subcs|syst-group|syst-ffile|syst-uzeit|syst-dsnam|syst-repid|syst-tabid|syst-tfdsn|syst-uname|syst-lstat|syst-abcde|syst-marky|syst-sfnam|syst-tname|syst-msgli|syst-title|syst-entry|syst-lisel|syst-uline|syst-xcode|syst-cprog|syst-xprog|syst-xform|syst-ldbpg|syst-tvar0|syst-tvar1|syst-tvar2|syst-tvar3|syst-tvar4|syst-tvar5|syst-tvar6|syst-tvar7|syst-tvar8|syst-tvar9|syst-msgid|syst-msgty|syst-msgno|syst-msgv1|syst-msgv2|syst-msgv3|syst-msgv4|syst-oncom|syst-vline|syst-winsl|syst-staco|syst-staro|syst-datar|syst-host|syst-locdb|syst-locop|syst-datlo|syst-timlo|syst-zonlo)$/',
|
||||
'reserved' => '/^((?i)abs|acos|add|add-corresponding|adjacent|after|aliases|all|analyzer|and|any|append|as|ascending|asin|assign|assigned|assigning|at|atan|authority-check|avg|back|before|begin|binary|bit|bit-and|bit-not|bit-or|bit-xor|blank|block|break-point|buffer|by|c|call|case|catch|ceil|centered|chain|change|changing|check|checkbox|class|class-data|class-events|class-methods|class-pool|clear|client|close|cnt|code|collect|color|comment|commit|communication|compute|concatenate|condense|constants|context|contexts|continue|control|controls|convert|copy|corresponding|cos|cosh|count|country|create|currency|cursor|customer-function|data|database|dataset|delete|decimals|default|define|demand|descending|describe|dialog|distinct|div|divide|divide-corresponding|do|duplicates|dynpro|edit|editor-call|else|elseif|end|end-of-definition|end-of-page|end-of-selection|endat|endcase|endcatch|endchain|endclass|enddo|endexec|endform|endfunction|endif|endinterface|endloop|endmethod|endmodule|endon|endprovide|endselect|endwhile|entries|events|exec|exit|exit-command|exp|exponent|export|exporting|exceptions|extended|extract|fetch|field|field-groups|field-symbols|fields|floor|for|form|format|frac|frame|free|from|function|function-pool|generate|get|group|hashed|header|help-id|help-request|hide|hotspot|icon|id|if|import|importing|include|index|infotypes|initialization|inner|input|insert|intensified|interface|interface-pool|interfaces|into|inverse|join|key|language|last|leave|left|left-justified|like|line|line-count|line-selection|line-size|lines|list-processing|load|load-of-program|local|locale|log|log10|loop|m|margin|mask|matchcode|max|memory|message|message-id|messages|method|methods|min|mod|mode|modif|modify|module|move|move-corresponding|multiply|multiply-corresponding|new|new-line|new-page|next|no|no-gap|no-gaps|no-heading|no-scrolling|no-sign|no-title|no-zero|nodes|non-unique|o|object|obligatory|occurs|of|off|on|open|or|order|others|outer|output|overlay|pack|page|parameter|parameters|perform|pf-status|position|print|print-control|private|process|program|property|protected|provide|public|put|radiobutton|raise|raising|range|ranges|read|receive|refresh|reject|replace|report|requested|reserve|reset|right-justified|rollback|round|rows|rtti|run|scan|screen|search|separated|scroll|scroll-boundary|select|select-options|selection-screen|selection-table|set|shared|shift|sign|sin|single|sinh|size|skip|sort|sorted|split|sql|sqrt|stamp|standard|start-of-selection|statics|stop|string|strlen|structure|submit|subtract|subtract-corresponding|sum|supply|suppress|symbol|syntax-check|syntax-trace|system-call|system-exceptions|table|table_line|tables|tan|tanh|text|textpool|time|times|title|titlebar|to|top-of-page|transaction|transfer|translate|transporting|trunc|type|type-pool|type-pools|types|uline|under|unique|unit|unpack|up|update|user-command|using|value|value-request|values|vary|when|where|while|window|with|with-title|work|write|x|xstring|z|zone)$/',
|
||||
'constants' => '/^((?i)initial|null|space|col_background|col_heading|col_normal|col_total|col_key|col_positive|col_negative|col_group)$/',
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
'sy' => '/^((?i)screen-name|screen-group1|screen-group2|screen-group3|screen-group4|screen-required|screen-input|screen-output|screen-intensified|screen-invisible|screen-length|screen-active|sy-index|sy-pagno|sy-tabix|sy-tfill|sy-tlopc|sy-tmaxl|sy-toccu|sy-ttabc|sy-tstis|sy-ttabi|sy-dbcnt|sy-fdpos|sy-colno|sy-linct|sy-linno|sy-linsz|sy-pagct|sy-macol|sy-marow|sy-tleng|sy-sfoff|sy-willi|sy-lilli|sy-subrc|sy-fleng|sy-cucol|sy-curow|sy-lsind|sy-listi|sy-stepl|sy-tpagi|sy-winx1|sy-winy1|sy-winx2|sy-winy2|sy-winco|sy-winro|sy-windi|sy-srows|sy-scols|sy-loopc|sy-folen|sy-fodec|sy-tzone|sy-dayst|sy-ftype|sy-appli|sy-fdayw|sy-ccurs|sy-ccurt|sy-debug|sy-ctype|sy-input|sy-langu|sy-modno|sy-batch|sy-binpt|sy-calld|sy-dynnr|sy-dyngr|sy-newpa|sy-pri40|sy-rstrt|sy-wtitl|sy-cpage|sy-dbnam|sy-mandt|sy-prefx|sy-fmkey|sy-pexpi|sy-prini|sy-primm|sy-prrel|sy-playo|sy-prbig|sy-playp|sy-prnew|sy-prlog|sy-pdest|sy-plist|sy-pauth|sy-prdsn|sy-pnwpa|sy-callr|sy-repi2|sy-rtitl|sy-prrec|sy-prtxt|sy-prabt|sy-lpass|sy-nrpag|sy-paart|sy-prcop|sy-batzs|sy-bspld|sy-brep4|sy-batzo|sy-batzd|sy-batzw|sy-batzm|sy-ctabl|sy-dbsys|sy-dcsys|sy-macdb|sy-sysid|sy-opsys|sy-pfkey|sy-saprl|sy-tcode|sy-ucomm|sy-cfwae|sy-chwae|sy-spono|sy-sponr|sy-waers|sy-cdate|sy-datum|sy-slset|sy-subty|sy-subcs|sy-group|sy-ffile|sy-uzeit|sy-dsnam|sy-repid|sy-tabid|sy-tfdsn|sy-uname|sy-lstat|sy-abcde|sy-marky|sy-sfnam|sy-tname|sy-msgli|sy-title|sy-entry|sy-lisel|sy-uline|sy-xcode|sy-cprog|sy-xprog|sy-xform|sy-ldbpg|sy-tvar0|sy-tvar1|sy-tvar2|sy-tvar3|sy-tvar4|sy-tvar5|sy-tvar6|sy-tvar7|sy-tvar8|sy-tvar9|sy-msgid|sy-msgty|sy-msgno|sy-msgv1|sy-msgv2|sy-msgv3|sy-msgv4|sy-oncom|sy-vline|sy-winsl|sy-staco|sy-staro|sy-datar|sy-host|sy-locdb|sy-locop|sy-datlo|sy-timlo|sy-zonlo|syst-index|syst-pagno|syst-tabix|syst-tfill|syst-tlopc|syst-tmaxl|syst-toccu|syst-ttabc|syst-tstis|syst-ttabi|syst-dbcnt|syst-fdpos|syst-colno|syst-linct|syst-linno|syst-linsz|syst-pagct|syst-macol|syst-marow|syst-tleng|syst-sfoff|syst-willi|syst-lilli|syst-subrc|syst-fleng|syst-cucol|syst-curow|syst-lsind|syst-listi|syst-stepl|syst-tpagi|syst-winx1|syst-winy1|syst-winx2|syst-winy2|syst-winco|syst-winro|syst-windi|syst-srows|syst-scols|syst-loopc|syst-folen|syst-fodec|syst-tzone|syst-dayst|syst-ftype|syst-appli|syst-fdayw|syst-ccurs|syst-ccurt|syst-debug|syst-ctype|syst-input|syst-langu|syst-modno|syst-batch|syst-binpt|syst-calld|syst-dynnr|syst-dyngr|syst-newpa|syst-pri40|syst-rstrt|syst-wtitl|syst-cpage|syst-dbnam|syst-mandt|syst-prefx|syst-fmkey|syst-pexpi|syst-prini|syst-primm|syst-prrel|syst-playo|syst-prbig|syst-playp|syst-prnew|syst-prlog|syst-pdest|syst-plist|syst-pauth|syst-prdsn|syst-pnwpa|syst-callr|syst-repi2|syst-rtitl|syst-prrec|syst-prtxt|syst-prabt|syst-lpass|syst-nrpag|syst-paart|syst-prcop|syst-batzs|syst-bspld|syst-brep4|syst-batzo|syst-batzd|syst-batzw|syst-batzm|syst-ctabl|syst-dbsys|syst-dcsys|syst-macdb|syst-sysid|syst-opsys|syst-pfkey|syst-saprl|syst-tcode|syst-ucomm|syst-cfwae|syst-chwae|syst-spono|syst-sponr|syst-waers|syst-cdate|syst-datum|syst-slset|syst-subty|syst-subcs|syst-group|syst-ffile|syst-uzeit|syst-dsnam|syst-repid|syst-tabid|syst-tfdsn|syst-uname|syst-lstat|syst-abcde|syst-marky|syst-sfnam|syst-tname|syst-msgli|syst-title|syst-entry|syst-lisel|syst-uline|syst-xcode|syst-cprog|syst-xprog|syst-xform|syst-ldbpg|syst-tvar0|syst-tvar1|syst-tvar2|syst-tvar3|syst-tvar4|syst-tvar5|syst-tvar6|syst-tvar7|syst-tvar8|syst-tvar9|syst-msgid|syst-msgty|syst-msgno|syst-msgv1|syst-msgv2|syst-msgv3|syst-msgv4|syst-oncom|syst-vline|syst-winsl|syst-staco|syst-staro|syst-datar|syst-host|syst-locdb|syst-locop|syst-datlo|syst-timlo|syst-zonlo)$/',
|
||||
'reserved' => '/^((?i)abs|acos|add|add-corresponding|adjacent|after|aliases|all|analyzer|and|any|append|as|ascending|asin|assign|assigned|assigning|at|atan|authority-check|avg|back|before|begin|binary|bit|bit-and|bit-not|bit-or|bit-xor|blank|block|break-point|buffer|by|c|call|case|catch|ceil|centered|chain|change|changing|check|checkbox|class|class-data|class-events|class-methods|class-pool|clear|client|close|cnt|code|collect|color|comment|commit|communication|compute|concatenate|condense|constants|context|contexts|continue|control|controls|convert|copy|corresponding|cos|cosh|count|country|create|currency|cursor|customer-function|data|database|dataset|delete|decimals|default|define|demand|descending|describe|dialog|distinct|div|divide|divide-corresponding|do|duplicates|dynpro|edit|editor-call|else|elseif|end|end-of-definition|end-of-page|end-of-selection|endat|endcase|endcatch|endchain|endclass|enddo|endexec|endform|endfunction|endif|endinterface|endloop|endmethod|endmodule|endon|endprovide|endselect|endwhile|entries|events|exec|exit|exit-command|exp|exponent|export|exporting|exceptions|extended|extract|fetch|field|field-groups|field-symbols|fields|floor|for|form|format|frac|frame|free|from|function|function-pool|generate|get|group|hashed|header|help-id|help-request|hide|hotspot|icon|id|if|import|importing|include|index|infotypes|initialization|inner|input|insert|intensified|interface|interface-pool|interfaces|into|inverse|join|key|language|last|leave|left|left-justified|like|line|line-count|line-selection|line-size|lines|list-processing|load|load-of-program|local|locale|log|log10|loop|m|margin|mask|matchcode|max|memory|message|message-id|messages|method|methods|min|mod|mode|modif|modify|module|move|move-corresponding|multiply|multiply-corresponding|new|new-line|new-page|next|no|no-gap|no-gaps|no-heading|no-scrolling|no-sign|no-title|no-zero|nodes|non-unique|o|object|obligatory|occurs|of|off|on|open|or|order|others|outer|output|overlay|pack|page|parameter|parameters|perform|pf-status|position|print|print-control|private|process|program|property|protected|provide|public|put|radiobutton|raise|raising|range|ranges|read|receive|refresh|reject|replace|report|requested|reserve|reset|right-justified|rollback|round|rows|rtti|run|scan|screen|search|separated|scroll|scroll-boundary|select|select-options|selection-screen|selection-table|set|shared|shift|sign|sin|single|sinh|size|skip|sort|sorted|split|sql|sqrt|stamp|standard|start-of-selection|statics|stop|string|strlen|structure|submit|subtract|subtract-corresponding|sum|supply|suppress|symbol|syntax-check|syntax-trace|system-call|system-exceptions|table|table_line|tables|tan|tanh|text|textpool|time|times|title|titlebar|to|top-of-page|transaction|transfer|translate|transporting|trunc|type|type-pool|type-pools|types|uline|under|unique|unit|unpack|up|update|user-command|using|value|value-request|values|vary|when|where|while|window|with|with-title|work|write|x|xstring|z|zone)$/',
|
||||
'constants' => '/^((?i)initial|null|space|col_background|col_heading|col_normal|col_total|col_key|col_positive|col_negative|col_group)$/',
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
'sy' => 'reserved',
|
||||
'reserved' => 'reserved',
|
||||
'constants' => 'reserved',
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
894
library/Text_Highlighter/Text/Highlighter/AVRC.php
Normal file
894
library/Text_Highlighter/Text/Highlighter/AVRC.php
Normal file
|
@ -0,0 +1,894 @@
|
|||
|
||||
<?php
|
||||
/**
|
||||
* Auto-generated class. AVRC syntax highlighting
|
||||
*
|
||||
*
|
||||
* C/C++ highlighter specific to Atmel AVR microcontrollers
|
||||
*
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: avrc.xml
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. AVRC syntax highlighting
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: 0.7.0
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_AVRC extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'avrc';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_AVRC($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
0 => '/((?i)\\\\)/',
|
||||
1 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
2 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
3 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
4 => '//',
|
||||
5 => '/((?i)")|((?i)<)/',
|
||||
6 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
7 => '/((?i)\\$\\w+\\s*:.+\\$)/',
|
||||
8 => '/((?i)\\$\\w+\\s*:.+\\$)/',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 2,
|
||||
8 => 0,
|
||||
9 => 0,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'quotes',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => '',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => 'mlcomment',
|
||||
9 => 'comment',
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'string',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'identifier',
|
||||
4 => 'number',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'mlcomment',
|
||||
9 => 'comment',
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => 'inlinedoc',
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => 'inlinedoc',
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?i)"/',
|
||||
1 => '/(?i)\\}/',
|
||||
2 => '/(?i)\\)/',
|
||||
3 => '/(?i)\\]/',
|
||||
4 => '/(?i)>/',
|
||||
5 => '/(?mi)(?<!\\\\)$/',
|
||||
6 => '/(?mi)(?<!\\\\)$/',
|
||||
7 => '/(?i)\\*\\//',
|
||||
8 => '/(?mi)$/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 4,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => 7,
|
||||
9 => 8,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'registers' => '/^(ACSR|ADCH|ADCL|ADCSRA|ADMUX|ASSR|DDRA|DDRB|DDRC|DDRD|DDRE|DDRF|DDRG|EEARH|EEARL|EECR|EEDR|EICRA|EICRB|EIFR|EIMSK|ETIFR|ETIMSK|GICR|GIFR|ICR1H|ICR1L|ICR3H|ICR3L|MCUCR|MCUCSR|OCDR|OCR0|OCR1AH|OCR1AL|OCR1BH|OCR1BL|OCR1CH|OCR1CL|OCR2|OCR3AH|OCR3AL|OCR3BH|OCR3BL|OCR3CH|OCR3CL|OSCCAL|PINA|PINB|PINC|PIND|PINE|PINF|PING|PORTA|PORTB|PORTC|PORTD|PORTE|PORTF|PORTG|RAMPZ|SFIOR|SPCR|SPDR|SPH|SPL|SPMCR|SPMCSR|SPSR|SREG|TCCR0|TCCR1A|TCCR1B|TCCR1C|TCCR2|TCCR3A|TCCR3B|TCCR3C|TCNT0|TCNT1H|TCNT1L|TCNT2|TCNT3H|TCNT3L|TIFR|TIMSK|TWAR|TWBR|TWCR|TWDR|TWSR|UBRR0H|UBRR0L|UBRR1H|UBRR1L|UBRRH|UBRRL|UCSR0A|UCSR0B|UCSR0C|UCSR1A|UCSR1B|UCSR1C|UCSRA|UCSRB|UCSRC|UDR|UDR0|UDR1|WDTCR|XDIV|XMCRA|XMCRB)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'registers' => '/^(ACSR|ADCH|ADCL|ADCSRA|ADMUX|ASSR|DDRA|DDRB|DDRC|DDRD|DDRE|DDRF|DDRG|EEARH|EEARL|EECR|EEDR|EICRA|EICRB|EIFR|EIMSK|ETIFR|ETIMSK|GICR|GIFR|ICR1H|ICR1L|ICR3H|ICR3L|MCUCR|MCUCSR|OCDR|OCR0|OCR1AH|OCR1AL|OCR1BH|OCR1BL|OCR1CH|OCR1CL|OCR2|OCR3AH|OCR3AL|OCR3BH|OCR3BL|OCR3CH|OCR3CL|OSCCAL|PINA|PINB|PINC|PIND|PINE|PINF|PING|PORTA|PORTB|PORTC|PORTD|PORTE|PORTF|PORTG|RAMPZ|SFIOR|SPCR|SPDR|SPH|SPL|SPMCR|SPMCSR|SPSR|SREG|TCCR0|TCCR1A|TCCR1B|TCCR1C|TCCR2|TCCR3A|TCCR3B|TCCR3C|TCNT0|TCNT1H|TCNT1L|TCNT2|TCNT3H|TCNT3L|TIFR|TIMSK|TWAR|TWBR|TWCR|TWDR|TWSR|UBRR0H|UBRR0L|UBRR1H|UBRR1L|UBRRH|UBRRL|UCSR0A|UCSR0B|UCSR0C|UCSR1A|UCSR1B|UCSR1C|UCSRA|UCSRB|UCSRC|UDR|UDR0|UDR1|WDTCR|XDIV|XMCRA|XMCRB)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'registers' => '/^(ACSR|ADCH|ADCL|ADCSRA|ADMUX|ASSR|DDRA|DDRB|DDRC|DDRD|DDRE|DDRF|DDRG|EEARH|EEARL|EECR|EEDR|EICRA|EICRB|EIFR|EIMSK|ETIFR|ETIMSK|GICR|GIFR|ICR1H|ICR1L|ICR3H|ICR3L|MCUCR|MCUCSR|OCDR|OCR0|OCR1AH|OCR1AL|OCR1BH|OCR1BL|OCR1CH|OCR1CL|OCR2|OCR3AH|OCR3AL|OCR3BH|OCR3BL|OCR3CH|OCR3CL|OSCCAL|PINA|PINB|PINC|PIND|PINE|PINF|PING|PORTA|PORTB|PORTC|PORTD|PORTE|PORTF|PORTG|RAMPZ|SFIOR|SPCR|SPDR|SPH|SPL|SPMCR|SPMCSR|SPSR|SREG|TCCR0|TCCR1A|TCCR1B|TCCR1C|TCCR2|TCCR3A|TCCR3B|TCCR3C|TCNT0|TCNT1H|TCNT1L|TCNT2|TCNT3H|TCNT3L|TIFR|TIMSK|TWAR|TWBR|TWCR|TWDR|TWSR|UBRR0H|UBRR0L|UBRR1H|UBRR1L|UBRRH|UBRRL|UCSR0A|UCSR0B|UCSR0C|UCSR1A|UCSR1B|UCSR1C|UCSRA|UCSRB|UCSRC|UDR|UDR0|UDR1|WDTCR|XDIV|XMCRA|XMCRB)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'registers' => '/^(ACSR|ADCH|ADCL|ADCSRA|ADMUX|ASSR|DDRA|DDRB|DDRC|DDRD|DDRE|DDRF|DDRG|EEARH|EEARL|EECR|EEDR|EICRA|EICRB|EIFR|EIMSK|ETIFR|ETIMSK|GICR|GIFR|ICR1H|ICR1L|ICR3H|ICR3L|MCUCR|MCUCSR|OCDR|OCR0|OCR1AH|OCR1AL|OCR1BH|OCR1BL|OCR1CH|OCR1CL|OCR2|OCR3AH|OCR3AL|OCR3BH|OCR3BL|OCR3CH|OCR3CL|OSCCAL|PINA|PINB|PINC|PIND|PINE|PINF|PING|PORTA|PORTB|PORTC|PORTD|PORTE|PORTF|PORTG|RAMPZ|SFIOR|SPCR|SPDR|SPH|SPL|SPMCR|SPMCSR|SPSR|SREG|TCCR0|TCCR1A|TCCR1B|TCCR1C|TCCR2|TCCR3A|TCCR3B|TCCR3C|TCNT0|TCNT1H|TCNT1L|TCNT2|TCNT3H|TCNT3L|TIFR|TIMSK|TWAR|TWBR|TWCR|TWDR|TWSR|UBRR0H|UBRR0L|UBRR1H|UBRR1L|UBRRH|UBRRL|UCSR0A|UCSR0B|UCSR0C|UCSR1A|UCSR1B|UCSR1C|UCSRA|UCSRB|UCSRC|UDR|UDR0|UDR1|WDTCR|XDIV|XMCRA|XMCRB)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'registers' => '/^(ACSR|ADCH|ADCL|ADCSRA|ADMUX|ASSR|DDRA|DDRB|DDRC|DDRD|DDRE|DDRF|DDRG|EEARH|EEARL|EECR|EEDR|EICRA|EICRB|EIFR|EIMSK|ETIFR|ETIMSK|GICR|GIFR|ICR1H|ICR1L|ICR3H|ICR3L|MCUCR|MCUCSR|OCDR|OCR0|OCR1AH|OCR1AL|OCR1BH|OCR1BL|OCR1CH|OCR1CL|OCR2|OCR3AH|OCR3AL|OCR3BH|OCR3BL|OCR3CH|OCR3CL|OSCCAL|PINA|PINB|PINC|PIND|PINE|PINF|PING|PORTA|PORTB|PORTC|PORTD|PORTE|PORTF|PORTG|RAMPZ|SFIOR|SPCR|SPDR|SPH|SPL|SPMCR|SPMCSR|SPSR|SREG|TCCR0|TCCR1A|TCCR1B|TCCR1C|TCCR2|TCCR3A|TCCR3B|TCCR3C|TCNT0|TCNT1H|TCNT1L|TCNT2|TCNT3H|TCNT3L|TIFR|TIMSK|TWAR|TWBR|TWCR|TWDR|TWSR|UBRR0H|UBRR0L|UBRR1H|UBRR1L|UBRRH|UBRRL|UCSR0A|UCSR0B|UCSR0C|UCSR1A|UCSR1B|UCSR1C|UCSRA|UCSRB|UCSRC|UDR|UDR0|UDR1|WDTCR|XDIV|XMCRA|XMCRB)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
'reserved' => 'reserved',
|
||||
'registers' => 'reserved',
|
||||
'types' => 'types',
|
||||
'Common Macros' => 'prepro',
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
891
library/Text_Highlighter/Text/Highlighter/CPP.php
Normal file
891
library/Text_Highlighter/Text/Highlighter/CPP.php
Normal file
|
@ -0,0 +1,891 @@
|
|||
|
||||
<?php
|
||||
/**
|
||||
* Auto-generated class. CPP syntax highlighting
|
||||
*
|
||||
*
|
||||
* Thanks to Aaron Kalin for initial
|
||||
* implementation of this highlighter
|
||||
*
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: cpp.xml
|
||||
* @author Aaron Kalin
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. CPP syntax highlighting
|
||||
*
|
||||
* @author Aaron Kalin
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: 0.7.0
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_CPP extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'cpp';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_CPP($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
0 => '/((?i)\\\\)/',
|
||||
1 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
2 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
3 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)\\[)|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?mi)^[ \\t]*#include)|((?mii)^[ \\t]*#[ \\t]*[a-z]+)|((?i)\\d*\\.?\\d+)|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
4 => '//',
|
||||
5 => '/((?i)")|((?i)<)/',
|
||||
6 => '/((?i)")|((?i)\\{)|((?i)\\()|((?i)[a-z_]\\w*)|((?i)\\b0[xX][\\da-f]+)|((?i)\\b\\d\\d*|\\b0\\b)|((?i)\\b0[0-7]+)|((?i)\\b(\\d*\\.\\d+)|(\\d+\\.\\d*))|((?i)\\/\\*)|((?i)\\/\\/.+)/',
|
||||
7 => '/((?i)\\$\\w+\\s*:.+\\$)/',
|
||||
8 => '/((?i)\\$\\w+\\s*:.+\\$)/',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 2,
|
||||
9 => 0,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 2,
|
||||
8 => 0,
|
||||
9 => 0,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => 'brackets',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => 'prepro',
|
||||
10 => 'prepro',
|
||||
11 => '',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'quotes',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'brackets',
|
||||
2 => 'brackets',
|
||||
3 => '',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => 'mlcomment',
|
||||
9 => 'comment',
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'code',
|
||||
4 => 'identifier',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'number',
|
||||
9 => 'prepro',
|
||||
10 => 'code',
|
||||
11 => 'number',
|
||||
12 => 'mlcomment',
|
||||
13 => 'comment',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'string',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'code',
|
||||
2 => 'code',
|
||||
3 => 'identifier',
|
||||
4 => 'number',
|
||||
5 => 'number',
|
||||
6 => 'number',
|
||||
7 => 'number',
|
||||
8 => 'mlcomment',
|
||||
9 => 'comment',
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => 'inlinedoc',
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => 'inlinedoc',
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?i)"/',
|
||||
1 => '/(?i)\\}/',
|
||||
2 => '/(?i)\\)/',
|
||||
3 => '/(?i)\\]/',
|
||||
4 => '/(?i)>/',
|
||||
5 => '/(?mi)(?<!\\\\)$/',
|
||||
6 => '/(?mi)(?<!\\\\)$/',
|
||||
7 => '/(?i)\\*\\//',
|
||||
8 => '/(?mi)$/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => 5,
|
||||
10 => 6,
|
||||
11 => -1,
|
||||
12 => 7,
|
||||
13 => 8,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 4,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => 7,
|
||||
9 => 8,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 =>
|
||||
array (
|
||||
'reserved' => '/^(and|and_eq|asm|bitand|bitor|break|case|catch|compl|const_cast|continue|default|delete|do|dynamic_cast|else|for|fortran|friend|goto|if|new|not|not_eq|operator|or|or_eq|private|protected|public|reinterpret_cast|return|sizeof|static_cast|switch|this|throw|try|typeid|using|while|xor|xor_eq|false|true)$/',
|
||||
'types' => '/^(auto|bool|char|class|const|double|enum|explicit|export|extern|float|inline|int|long|mutable|namespace|register|short|signed|static|struct|template|typedef|typename|union|unsigned|virtual|void|volatile|wchar_t)$/',
|
||||
'Common Macros' => '/^(NULL|TRUE|FALSE|MAX|MIN|__LINE__|__DATA__|__FILE__|__TIME__|__STDC__)$/',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
10 => NULL,
|
||||
11 => NULL,
|
||||
12 => NULL,
|
||||
13 => NULL,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
9 => NULL,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
'reserved' => 'reserved',
|
||||
'types' => 'types',
|
||||
'Common Macros' => 'prepro',
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
437
library/Text_Highlighter/Text/Highlighter/CSS.php
Normal file
437
library/Text_Highlighter/Text/Highlighter/CSS.php
Normal file
|
@ -0,0 +1,437 @@
|
|||
<?php
|
||||
/**
|
||||
* Auto-generated class. CSS syntax highlighting
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: css.xml
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. CSS syntax highlighting
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: 0.7.0
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_CSS extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'css';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_CSS($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?i)\\/\\*)|((?i)(@[a-z\\d]+))|((?i)(((\\.|#)?[a-z]+[a-z\\d\\-]*(?![a-z\\d\\-]))|(\\*))(?!\\s*:\\s*[\\s\\{]))|((?i):[a-z][a-z\\d\\-]*)|((?i)\\[)|((?i)\\{)/',
|
||||
0 => '//',
|
||||
1 => '/((?i)\\d*\\.?\\d+(\\%|em|ex|pc|pt|px|in|mm|cm))|((?i)\\d*\\.?\\d+)|((?i)[a-z][a-z\\d\\-]*)|((?i)#([\\da-f]{6}|[\\da-f]{3})\\b)/',
|
||||
2 => '/((?i)\')|((?i)")|((?i)[\\w\\-\\:]+)/',
|
||||
3 => '/((?i)\\/\\*)|((?i)[a-z][a-z\\d\\-]*\\s*:)|((?i)(((\\.|#)?[a-z]+[a-z\\d\\-]*(?![a-z\\d\\-]))|(\\*))(?!\\s*:\\s*[\\s\\{]))|((?i)\\{)/',
|
||||
4 => '/((?i)\\\\[\\\\(\\\\)\\\\])/',
|
||||
5 => '/((?i)\\\\\\\\|\\\\"|\\\\\'|\\\\`)/',
|
||||
6 => '/((?i)\\\\\\\\|\\\\"|\\\\\'|\\\\`|\\\\t|\\\\n|\\\\r)/',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 4,
|
||||
3 => 0,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 1,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 4,
|
||||
3 => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => 'brackets',
|
||||
5 => 'brackets',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'quotes',
|
||||
1 => 'quotes',
|
||||
2 => '',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'reserved',
|
||||
2 => '',
|
||||
3 => 'brackets',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'var',
|
||||
2 => 'identifier',
|
||||
3 => 'special',
|
||||
4 => 'code',
|
||||
5 => 'code',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'number',
|
||||
1 => 'number',
|
||||
2 => 'code',
|
||||
3 => 'var',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
1 => 'string',
|
||||
2 => 'var',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'code',
|
||||
2 => 'identifier',
|
||||
3 => 'code',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => 'string',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?i)\\*\\//',
|
||||
1 => '/(?i)(?=;|\\})/',
|
||||
2 => '/(?i)\\]/',
|
||||
3 => '/(?i)\\}/',
|
||||
4 => '/(?i)\\)/',
|
||||
5 => '/(?i)\'/',
|
||||
6 => '/(?i)"/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => 2,
|
||||
5 => 3,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 5,
|
||||
1 => 6,
|
||||
2 => -1,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => -1,
|
||||
3 => 3,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'propertyValue' => '/^((?i)far-left|left|center-left|center-right|center|far-right|right-side|right|behind|leftwards|rightwards|inherit|scroll|fixed|transparent|none|repeat-x|repeat-y|repeat|no-repeat|collapse|separate|auto|top|bottom|both|open-quote|close-quote|no-open-quote|no-close-quote|crosshair|default|pointer|move|e-resize|ne-resize|nw-resize|n-resize|se-resize|sw-resize|s-resize|text|wait|help|ltr|rtl|inline|block|list-item|run-in|compact|marker|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|below|level|above|higher|lower|show|hide|caption|icon|menu|message-box|small-caption|status-bar|normal|wider|narrower|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|italic|oblique|small-caps|bold|bolder|lighter|inside|outside|disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman|lower-greek|lower-alpha|lower-latin|upper-alpha|upper-latin|hebrew|armenian|georgian|cjk-ideographic|hiragana|katakana|hiragana-iroha|katakana-iroha|crop|cross|invert|visible|hidden|always|avoid|x-low|low|medium|high|x-high|mix?|repeat?|static|relative|absolute|portrait|landscape|spell-out|once|digits|continuous|code|x-slow|slow|fast|x-fast|faster|slower|justify|underline|overline|line-through|blink|capitalize|uppercase|lowercase|embed|bidi-override|baseline|sub|super|text-top|middle|text-bottom|silent|x-soft|soft|loud|x-loud|pre|nowrap|serif|sans-serif|cursive|fantasy|monospace|empty|string|strict|loose|char|true|false|dotted|dashed|solid|double|groove|ridge|inset|outset|larger|smaller|xx-small|x-small|small|large|x-large|xx-large|all|newspaper|distribute|distribute-all-lines|distribute-center-last|inter-word|inter-ideograph|inter-cluster|kashida|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|keep-all|break-all|break-word|lr-tb|tb-rl|thin|thick|inline-block|w-resize|hand|distribute-letter|distribute-space|whitespace|male|female|child)$/',
|
||||
'namedcolor' => '/^((?i)aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow|activeborder|activecaption|appworkspace|background|buttonface|buttonhighlight|buttonshadow|buttontext|captiontext|graytext|highlight|highlighttext|inactiveborder|inactivecaption|inactivecaptiontext|infobackground|infotext|menu|menutext|scrollbar|threeddarkshadow|threedface|threedhighlight|threedlightshadow|threedshadow|window|windowframe|windowtext)$/',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 => -1,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
1 => 'string',
|
||||
),
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
'propertyValue' => 'string',
|
||||
'namedcolor' => 'var',
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
384
library/Text_Highlighter/Text/Highlighter/DIFF.php
Normal file
384
library/Text_Highlighter/Text/Highlighter/DIFF.php
Normal file
|
@ -0,0 +1,384 @@
|
|||
<?php
|
||||
/**
|
||||
* Auto-generated class. DIFF syntax highlighting
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: : diff.xml,v 1.1 2007/06/03 02:35:28 ssttoo Exp
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. DIFF syntax highlighting
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_DIFF extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'diff';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_DIFF($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?m)^\\\\\\sNo\\snewline.+$)|((?m)^\\-\\-\\-$)|((?m)^(diff\\s+\\-|Only\\s+|Index).*$)|((?m)^(\\-\\-\\-|\\+\\+\\+)\\s.+$)|((?m)^\\*.*$)|((?m)^\\+.*$)|((?m)^!.*$)|((?m)^\\<\\s.*$)|((?m)^\\>\\s.*$)|((?m)^\\d+(\\,\\d+)?[acd]\\d+(,\\d+)?$)|((?m)^\\-.*$)|((?m)^\\+.*$)|((?m)^@@.+@@$)|((?m)^d\\d+\\s\\d+$)|((?m)^a\\d+\\s\\d+$)|((?m)^(\\d+)(,\\d+)?(a)$)|((?m)^(\\d+)(,\\d+)?(c)$)|((?m)^(\\d+)(,\\d+)?(d)$)|((?m)^a(\\d+)(\\s\\d+)?$)|((?m)^c(\\d+)(\\s\\d+)?$)|((?m)^d(\\d+)(\\s\\d+)?$)/',
|
||||
0 => '//',
|
||||
1 => '//',
|
||||
2 => '//',
|
||||
3 => '//',
|
||||
4 => '//',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 1,
|
||||
4 => 0,
|
||||
5 => 0,
|
||||
6 => 0,
|
||||
7 => 0,
|
||||
8 => 0,
|
||||
9 => 2,
|
||||
10 => 0,
|
||||
11 => 0,
|
||||
12 => 0,
|
||||
13 => 0,
|
||||
14 => 0,
|
||||
15 => 3,
|
||||
16 => 3,
|
||||
17 => 3,
|
||||
18 => 2,
|
||||
19 => 2,
|
||||
20 => 2,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
9 => '',
|
||||
10 => '',
|
||||
11 => '',
|
||||
12 => '',
|
||||
13 => '',
|
||||
14 => 'code',
|
||||
15 => 'code',
|
||||
16 => 'code',
|
||||
17 => '',
|
||||
18 => 'code',
|
||||
19 => 'code',
|
||||
20 => '',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
1 => 'code',
|
||||
2 => 'var',
|
||||
3 => 'reserved',
|
||||
4 => 'quotes',
|
||||
5 => 'string',
|
||||
6 => 'inlinedoc',
|
||||
7 => 'quotes',
|
||||
8 => 'string',
|
||||
9 => 'code',
|
||||
10 => 'quotes',
|
||||
11 => 'string',
|
||||
12 => 'code',
|
||||
13 => 'code',
|
||||
14 => 'var',
|
||||
15 => 'string',
|
||||
16 => 'inlinedoc',
|
||||
17 => 'code',
|
||||
18 => 'string',
|
||||
19 => 'inlinedoc',
|
||||
20 => 'code',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?m)(?=^[ad]\\d+\\s\\d+)/',
|
||||
1 => '/(?m)^(\\.)$/',
|
||||
2 => '/(?m)^(\\.)$/',
|
||||
3 => '/(?m)^(\\.)$/',
|
||||
4 => '/(?m)^(\\.)$/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
9 => -1,
|
||||
10 => -1,
|
||||
11 => -1,
|
||||
12 => -1,
|
||||
13 => -1,
|
||||
14 => 0,
|
||||
15 => 1,
|
||||
16 => 2,
|
||||
17 => -1,
|
||||
18 => 3,
|
||||
19 => 4,
|
||||
20 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
),
|
||||
10 =>
|
||||
array (
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
12 =>
|
||||
array (
|
||||
),
|
||||
13 =>
|
||||
array (
|
||||
),
|
||||
14 => -1,
|
||||
15 => -1,
|
||||
16 => -1,
|
||||
17 =>
|
||||
array (
|
||||
),
|
||||
18 => -1,
|
||||
19 => -1,
|
||||
20 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
9 => false,
|
||||
10 => false,
|
||||
11 => false,
|
||||
12 => false,
|
||||
13 => false,
|
||||
14 => false,
|
||||
15 => false,
|
||||
16 => false,
|
||||
17 => false,
|
||||
18 => false,
|
||||
19 => false,
|
||||
20 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
);
|
||||
$this->_defClass = 'default';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
426
library/Text_Highlighter/Text/Highlighter/DTD.php
Normal file
426
library/Text_Highlighter/Text/Highlighter/DTD.php
Normal file
|
@ -0,0 +1,426 @@
|
|||
<?php
|
||||
/**
|
||||
* Auto-generated class. DTD syntax highlighting
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: : dtd.xml,v 1.1 2007/06/03 02:35:28 ssttoo Exp
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. DTD syntax highlighting
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_DTD extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'dtd';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_DTD($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/(\\<!--)|(\\<\\!\\[)|((\\&|\\%)[\\w\\-\\.]+;)/',
|
||||
0 => '//',
|
||||
1 => '/(\\<!--)|(\\<)|(#PCDATA\\b)|((\\&|\\%)[\\w\\-\\.]+;)|((?i)[a-z][a-z\\d\\-\\,:]+)/',
|
||||
2 => '/(\\<!--)|(\\()|(\')|(")|((?<=\\<)!(ENTITY|ATTLIST|ELEMENT|NOTATION)\\b)|(\\s(#(IMPLIED|REQUIRED|FIXED))|CDATA|ENTITY|NOTATION|NMTOKENS?|PUBLIC|SYSTEM\\b)|(#PCDATA\\b)|((\\&|\\%)[\\w\\-\\.]+;)|((?i)[a-z][a-z\\d\\-\\,:]+)/',
|
||||
3 => '/(\\()|((\\&|\\%)[\\w\\-\\.]+;)|((?i)[a-z][a-z\\d\\-\\,:]+)/',
|
||||
4 => '/((\\&|\\%)[\\w\\-\\.]+;)/',
|
||||
5 => '/((\\&|\\%)[\\w\\-\\.]+;)/',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 1,
|
||||
4 => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0,
|
||||
4 => 1,
|
||||
5 => 2,
|
||||
6 => 0,
|
||||
7 => 1,
|
||||
8 => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => 1,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 1,
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'brackets',
|
||||
2 => '',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'brackets',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => '',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'brackets',
|
||||
2 => 'quotes',
|
||||
3 => 'quotes',
|
||||
4 => '',
|
||||
5 => '',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => '',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'brackets',
|
||||
1 => '',
|
||||
2 => '',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'code',
|
||||
2 => 'special',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'code',
|
||||
2 => 'reserved',
|
||||
3 => 'special',
|
||||
4 => 'identifier',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'code',
|
||||
2 => 'string',
|
||||
3 => 'string',
|
||||
4 => 'var',
|
||||
5 => 'reserved',
|
||||
6 => 'reserved',
|
||||
7 => 'special',
|
||||
8 => 'identifier',
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 'code',
|
||||
1 => 'special',
|
||||
2 => 'identifier',
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/--\\>/',
|
||||
1 => '/\\]\\]\\>/',
|
||||
2 => '/\\>/',
|
||||
3 => '/\\)/',
|
||||
4 => '/\'/',
|
||||
5 => '/"/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 2,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 3,
|
||||
2 => 4,
|
||||
3 => 5,
|
||||
4 => -1,
|
||||
5 => -1,
|
||||
6 => -1,
|
||||
7 => -1,
|
||||
8 => -1,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => 3,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => -1,
|
||||
3 => -1,
|
||||
4 =>
|
||||
array (
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
3 => NULL,
|
||||
4 => NULL,
|
||||
5 => NULL,
|
||||
6 => NULL,
|
||||
7 => NULL,
|
||||
8 => NULL,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
3 => false,
|
||||
4 => false,
|
||||
5 => false,
|
||||
6 => false,
|
||||
7 => false,
|
||||
8 => false,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
1291
library/Text_Highlighter/Text/Highlighter/Generator.php
Normal file
1291
library/Text_Highlighter/Text/Highlighter/Generator.php
Normal file
File diff suppressed because it is too large
Load diff
234
library/Text_Highlighter/Text/Highlighter/HTML.php
Normal file
234
library/Text_Highlighter/Text/Highlighter/HTML.php
Normal file
|
@ -0,0 +1,234 @@
|
|||
<?php
|
||||
/**
|
||||
* Auto-generated class. HTML syntax highlighting
|
||||
*
|
||||
* PHP version 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @version generated from: : html.xml,v 1.1 2007/06/03 02:35:28 ssttoo Exp
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
require_once 'Text/Highlighter.php';
|
||||
|
||||
/**
|
||||
* Auto-generated class. HTML syntax highlighting
|
||||
*
|
||||
* @author Andrey Demenev <demenev@gmail.com>
|
||||
* @category Text
|
||||
* @package Text_Highlighter
|
||||
* @copyright 2004-2006 Andrey Demenev
|
||||
* @license http://www.php.net/license/3_0.txt PHP License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Text_Highlighter
|
||||
*/
|
||||
class Text_Highlighter_HTML extends Text_Highlighter
|
||||
{
|
||||
var $_language = 'html';
|
||||
|
||||
/**
|
||||
* PHP4 Compatible Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function Text_Highlighter_HTML($options=array())
|
||||
{
|
||||
$this->__construct($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options=array())
|
||||
{
|
||||
|
||||
$this->_options = $options;
|
||||
$this->_regs = array (
|
||||
-1 => '/((?i)\\<!--)|((?i)\\<[\\?\\/]?)|((?i)(&)[\\w\\-\\.]+;)/',
|
||||
0 => '//',
|
||||
1 => '/((?i)(?<=[\\<\\/?])[\\w\\-\\:]+)|((?i)[\\w\\-\\:]+)|((?i)")/',
|
||||
2 => '/((?i)(&)[\\w\\-\\.]+;)/',
|
||||
);
|
||||
$this->_counts = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 1,
|
||||
),
|
||||
);
|
||||
$this->_delim = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'brackets',
|
||||
2 => '',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => 'quotes',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => '',
|
||||
),
|
||||
);
|
||||
$this->_inner = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 'comment',
|
||||
1 => 'code',
|
||||
2 => 'special',
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => 'reserved',
|
||||
1 => 'var',
|
||||
2 => 'string',
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => 'special',
|
||||
),
|
||||
);
|
||||
$this->_end = array (
|
||||
0 => '/(?i)--\\>/',
|
||||
1 => '/(?i)[\\/\\?]?\\>/',
|
||||
2 => '/(?i)"/',
|
||||
);
|
||||
$this->_states = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => -1,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 => 2,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => -1,
|
||||
),
|
||||
);
|
||||
$this->_keywords = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => -1,
|
||||
1 => -1,
|
||||
2 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
2 => -1,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->_parts = array (
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
1 => NULL,
|
||||
2 => NULL,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => NULL,
|
||||
),
|
||||
);
|
||||
$this->_subst = array (
|
||||
-1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
),
|
||||
0 =>
|
||||
array (
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => false,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
0 => false,
|
||||
),
|
||||
);
|
||||
$this->_conditions = array (
|
||||
);
|
||||
$this->_kwmap = array (
|
||||
);
|
||||
$this->_defClass = 'code';
|
||||
$this->_checkDefines();
|
||||
}
|
||||
|
||||
}
|
802
library/Text_Highlighter/Text/Highlighter/JAVA.php
Normal file
802
library/Text_Highlighter/Text/Highlighter/JAVA.php
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue