Browse Source

Merge remote-tracking branch 'upstream/develop' into develop

Also removed <<<<< as this interfers (a bit) with searching for merge conflicts
with a more simplier editor.

Signed-off-by: Roland Häder <roland@mxchange.org>

Conflicts:
	mod/ping.php
	view/lang/fr/messages.po
	view/lang/fr/strings.php
pull/3010/head
Roland Häder 5 years ago
parent
commit
d489ba1510
  1. 6
      .gitignore
  2. 2
      LICENSE
  3. 10
      README.translate.md
  4. 52
      Vagrantfile
  5. 321
      boot.php
  6. 19
      convert_innodb.sql
  7. 45
      database.sql
  8. 2
      doc/Accesskeys.md
  9. 796
      doc/BBCode.md
  10. 2
      doc/Bugs-and-Issues.md
  11. 10
      doc/Home.md
  12. 22
      doc/Message-Flow.md
  13. 42
      doc/Protocol.md
  14. 63
      doc/SSL.md
  15. 5
      doc/Settings.md
  16. 29
      doc/Vagrant.md
  17. 35
      doc/api.md
  18. 36
      doc/database/db_notify.md
  19. 809
      doc/de/BBCode.md
  20. 2
      doc/de/Bugs-and-Issues.md
  21. 17
      doc/de/Home.md
  22. 12
      doc/de/Message-Flow.md
  23. 50
      doc/de/SSL.md
  24. 5
      doc/de/Settings.md
  25. 2
      doc/de/Text_editor.md
  26. 151
      doc/htconfig.md
  27. BIN
      doc/img/editor_frio.png
  28. 12
      doc/translations.md
  29. 34
      doc/upgrade.md
  30. 5
      htconfig.php
  31. 369
      include/Contact.php
  32. 124
      include/Core/Config.php
  33. 112
      include/Core/PConfig.php
  34. 28
      include/NotificationsManager.php
  35. 552
      include/ParseUrl.php
  36. 1312
      include/Photo.php
  37. 87
      include/Probe.php
  38. 472
      include/api.php
  39. 346
      include/auth_ejabberd.php
  40. 36
      include/bb2diaspora.php
  41. 26
      include/bbcode.php
  42. 226
      include/cache.php
  43. 106
      include/conversation.php
  44. 40
      include/create_shadowentry.php
  45. 39
      include/cron.php
  46. 20
      include/datetime.php
  47. 263
      include/dba.php
  48. 157
      include/dbclean.php
  49. 4
      include/dbm.php
  50. 132
      include/dbstructure.php
  51. 9
      include/delivery.php
  52. 76
      include/dfrn.php
  53. 18
      include/diaspora.php
  54. 39
      include/enotify.php
  55. 11
      include/event.php
  56. 32
      include/features.php
  57. 8
      include/feed.php
  58. 2
      include/follow.php
  59. 21
      include/gprobe.php
  60. 40
      include/html2bbcode.php
  61. 35
      include/identity.php
  62. 651
      include/items.php
  63. 214
      include/nav.php
  64. 6
      include/network.php
  65. 12
      include/notifier.php
  66. 177
      include/oembed.php
  67. 7
      include/onepoll.php
  68. 33
      include/ostatus.php
  69. 90
      include/pgettext.php
  70. 31
      include/photos.php
  71. 22
      include/plaintext.php
  72. 407
      include/poller.php
  73. 56
      include/post_update.php
  74. 33
      include/queue_fn.php
  75. 52
      include/remove_contact.php
  76. 3
      include/salmon.php
  77. 4
      include/security.php
  78. 100
      include/session.php
  79. 83
      include/socgraph.php
  80. 49
      include/spool_post.php
  81. 172
      include/text.php
  82. 96
      include/threads.php
  83. 23
      include/user.php
  84. 155
      include/xml.php
  85. 4
      index.php
  86. 2
      js/autocomplete.js
  87. 12
      js/country.js
  88. 236
      js/main.js
  89. 1063
      library/fullcalendar/CHANGELOG.txt
  90. 127
      library/fullcalendar/CONTRIBUTING.txt
  91. 2
      library/fullcalendar/LICENSE.txt
  92. 382
      library/fullcalendar/changelog.txt
  93. 1730
      library/fullcalendar/fullcalendar.css
  94. 17739
      library/fullcalendar/fullcalendar.js
  95. 5
      library/fullcalendar/fullcalendar.min.css
  96. 12
      library/fullcalendar/fullcalendar.min.js
  97. 216
      library/fullcalendar/fullcalendar.print.css
  98. 215
      library/fullcalendar/gcal.js
  99. 5
      library/fullcalendar/locale-all.js
  100. 2
      library/langdet/Text/LanguageDetect.php

6
.gitignore

@ -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

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

10
README.translate.md

@ -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

52
Vagrantfile

@ -1,31 +1,55 @@
server_ip = "192.168.22.10"
server_memory = "384" # MB
server_ip_trusty = "192.168.22.10"
server_ip_xenial = "192.168.22.11"
server_memory = "1024" # MB
server_timezone = "UTC"
public_folder = "/vagrant"
Vagrant.configure(2) do |config|
######################################################################
# Set server to Ubuntu 14.04
config.vm.box = "ubuntu/trusty64"
config.vm.define "trusty" do |trusty|
trusty.vm.box = "ubuntu/trusty64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a hostname, don't forget to put it to the `hosts` file
# This will point to the server's default virtual host
# TO DO: Make this work with virtualhost along-side xip.io URL
trusty.vm.hostname = "friendica-trusty.dev"
# Create a static IP
trusty.vm.network :private_network, ip: server_ip_trusty
end
######################################################################
# Set server to Ubuntu 16.04
config.vm.define "xenial" do |xenial|
xenial.vm.box = "boxcutter/ubuntu1604"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a hostname, don't forget to put it to the `hosts` file
# This will point to the server's default virtual host
# TO DO: Make this work with virtualhost along-side xip.io URL
config.vm.hostname = "friendica.dev"
# Create a hostname, don't forget to put it to the `hosts` file
# This will point to the server's default virtual host
# TO DO: Make this work with virtualhost along-side xip.io URL
xenial.vm.hostname = "friendica-xenial.dev"
# Create a static IP
config.vm.network :private_network, ip: server_ip
# Create a static IP
xenial.vm.network :private_network, ip: server_ip_xenial
end
######################################################################
# Share a folder between host and guest
config.vm.synced_folder "./", "/vagrant/", owner: "www-data", group: "vagrant"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
config.vm.provider "virtualbox" do |vb|

321
boot.php

@ -36,9 +36,9 @@ require_once('include/dbstructure.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5' );
define ( 'FRIENDICA_VERSION', '3.5.1-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1202 );
define ( 'DB_UPDATE_VERSION', 1209 );
/**
* @brief Constant with a HTML line break.
@ -53,7 +53,7 @@ define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
/**
* @brief Image storage quality.
*
*
* Lower numbers save space at cost of image detail.
* For ease of upgrade, please do not change here. Change jpeg quality with
* $a->config['system']['jpeg_quality'] = n;
@ -95,7 +95,7 @@ define ( 'DEFAULT_DB_ENGINE', 'MyISAM' );
/**
* @name SSL Policy
*
*
* SSL redirection policies
* @{
*/
@ -106,7 +106,7 @@ define ( 'SSL_POLICY_SELFSIGN', 2 );
/**
* @name Logger
*
*
* log levels
* @{
*/
@ -119,7 +119,7 @@ define ( 'LOGGER_ALL', 4 );
/**
* @name Cache
*
*
* Cache levels
* @{
*/
@ -127,11 +127,15 @@ 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 );
/* @}*/
/**
* @name Register
*
*
* Registration policies
* @{
*/
@ -142,7 +146,7 @@ define ( 'REGISTER_OPEN', 2 );
/**
* @name Contact_is
*
*
* Relationship types
* @{
*/
@ -153,7 +157,7 @@ define ( 'CONTACT_IS_FRIEND', 3);
/**
* @name Update
*
*
* DB update return values
* @{
*/
@ -181,9 +185,31 @@ 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
*
*
* Type of the community page
* @{
*/
@ -194,7 +220,7 @@ define ( 'CP_GLOBAL_COMMUNITY', 1 );
/**
* @name Network
*
*
* Network and protocol family types
* @{
*/
@ -266,7 +292,7 @@ define ( 'ZCURL_TIMEOUT' , (-1));
/**
* @name Notify
*
*
* Email notification options
* @{
*/
@ -288,7 +314,7 @@ define ( 'NOTIFY_SYSTEM', 0x8000 );
/**
* @name Term
*
*
* Tag/term types
* @{
*/
@ -308,7 +334,7 @@ define ( 'TERM_OBJ_PHOTO', 2 );
/**
* @name Namespaces
*
*
* Various namespaces we may need to parse
* @{
*/
@ -331,7 +357,7 @@ define ( 'NAMESPACE_ATOM1', 'http://www.w3.org/2005/Atom' );
/**
* @name Activity
*
*
* Activity stream defines
* @{
*/
@ -377,7 +403,7 @@ define ( 'ACTIVITY_OBJ_QUESTION', 'http://activityschema.org/object/question' );
/**
* @name Gravity
*
*
* Item weight for query ordering
* @{
*/
@ -444,9 +470,9 @@ function startup() {
/**
*
* class: App
*
*
* @brief Our main application structure for the life of this page.
*
*
* Primarily deals with the URL that got us here
* and tries to make some sense of it, and
* stores our page contents and config storage
@ -504,6 +530,7 @@ class App {
public $videoheight = 350;
public $force_max_items = 0;
public $theme_thread_allow = true;
public $theme_richtext_editor = true;
public $theme_events_in_profile = true;
/**
@ -583,6 +610,7 @@ class App {
$this->performance["markstart"] = microtime(true);
$this->callstack["database"] = array();
$this->callstack["database_write"] = array();
$this->callstack["network"] = array();
$this->callstack["file"] = array();
$this->callstack["rendering"] = array();
@ -759,60 +787,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 ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) {
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 ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
if ($ssl) {
$scheme = 'https';
else
} else {
$scheme = 'http';
}
}
}
if (get_config('config','hostname') != "")
$this->hostname = get_config('config','hostname');
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;
$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'))
$this->path = trim($parsed['path'],'\\/');
}
if (x($parsed, 'path')) {
$this->path = trim($parsed['path'], '\\/');
}
if (file_exists(".htpreconfig.php"))
if (file_exists(".htpreconfig.php")) {
@include(".htpreconfig.php");
}
if (get_config('config','hostname') != "")
$this->hostname = get_config('config','hostname');
if (get_config('config', 'hostname') != '') {
$this->hostname = get_config('config', 'hostname');
}
if (!isset($this->hostname) OR ($this->hostname == ""))
if (!isset($this->hostname) OR ($this->hostname == '')) {
$this->hostname = $hostname;
}
}
}
function get_hostname() {
@ -975,27 +1043,35 @@ class App {
/**
* @brief Removes the baseurl from an url. This avoids some mixed content problems.
*
* @param string $url
* @param string $orig_url
*
* @return string The cleaned url
*/
function remove_baseurl($url){
function remove_baseurl($orig_url){
// Is the function called statically?
if (!is_object($this))
return(self::$a->remove_baseurl($url));
if (!is_object($this)) {
return(self::$a->remove_baseurl($orig_url));
}
$url = normalise_link($url);
// Remove the hostname from the url if it is an internal link
$nurl = normalise_link($orig_url);
$base = normalise_link($this->get_baseurl());
$url = str_replace($base."/", "", $url);
return $url;
$url = str_replace($base."/", "", $nurl);
// if it is an external link return the orignal value
if ($url == normalise_link($orig_url)) {
return $orig_url;
} else {
return $url;
}
}
/**
* @brief Register template engine class
*
*
* If $name is "", is used class static property $class::$name
*
*
* @param string $class
* @param string $name
*/
@ -1013,7 +1089,7 @@ class App {
/**
* @brief Return template engine instance.
*
*
* If $name is not defined, return engine defined by theme,
* or default
*
@ -1078,6 +1154,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])) {
@ -1109,23 +1188,33 @@ class App {
$this->remove_inactive_processes();
q("START TRANSACTION");
$r = q("SELECT `pid` FROM `process` WHERE `pid` = %d", intval(getmypid()));
if(!dbm::is_result($r))
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))
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");
}
/**
@ -1154,11 +1243,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());
}
@ -1302,8 +1386,12 @@ class App {
function proc_run($args) {
if (!function_exists("proc_open")) {
return;
}
// Add the php path if it is a php call
if (count($args) && ($args[0] === 'php' OR is_int($args[0]))) {
if (count($args) && ($args[0] === 'php' OR !is_string($args[0]))) {
// If the last worker fork was less than 10 seconds before then don't fork another one.
// This should prevent the forking of masses of workers.
@ -1336,7 +1424,7 @@ class App {
/**
* @brief Retrieve the App structure
*
*
* Useful in functions which require it but don't get it passed to them
*/
function get_app() {
@ -1590,7 +1678,7 @@ function run_update_function($x) {
* and mark it uninstalled in the database (for now we'll remove it).
* Then go through the config list and if we have a plugin that isn't installed,
* call the install procedure and add it to the database.
*
*
* @param App $a
*
*/
@ -1656,17 +1744,17 @@ function get_guid($size=16, $prefix = "") {
}
}
/**
/**
* @brief Wrapper for adding a login box.
*
*
* @param bool $register
* If $register == true provide a registration link.
* This will most always depend on the value of $a->config['register_policy'].
* @param bool $hiddens
*
*
* @return string
* Returns the complete html for inserting into the page
*
*
* @hooks 'login_hook'
* string $o
*/
@ -1756,7 +1844,7 @@ function goaway($s) {
/**
* @brief Returns the user id of locally logged in user or false.
*
*
* @return int|bool user id or false
*/
function local_user() {
@ -1767,7 +1855,7 @@ function local_user() {
/**
* @brief Returns contact id of authenticated site visitor or false
*
*
* @return int|bool visitor_id or false
*/
function remote_user() {
@ -1823,14 +1911,15 @@ function get_max_import_size() {
* @brief Wrap calls to proc_close(proc_open()) and call hook
* so plugins can take part in process :)
*
* @param (string|integer) $cmd program to run or priority
*
* @param (string|integer|array) $cmd program to run, priority or parameter array
*
* next args are passed as $cmd command line
* e.g.: proc_run("ls","-la","/tmp");
* or: proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id);
* or: proc_run(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), "include/create_shadowentry.php", $post_id);
*
* @note $cmd and string args are surrounded with ""
*
*
* @hooks 'proc_run'
* array $arr
*/
@ -1838,24 +1927,31 @@ function proc_run($cmd){
$a = get_app();
$args = func_get_args();
$proc_args = func_get_args();
$newargs = array();
if (!count($args))
$args = array();
if (!count($proc_args)) {
return;
}
// expand any arrays
// Preserve the first parameter
// It could contain a command, the priority or an parameter array
// If we use the parameter array we have to protect it from the following function
$run_parameter = array_shift($proc_args);
foreach($args as $arg) {
if(is_array($arg)) {
foreach($arg as $n) {
$newargs[] = $n;
// expand any arrays
foreach ($proc_args as $arg) {
if (is_array($arg)) {
foreach ($arg as $n) {
$args[] = $n;
}
} else
$newargs[] = $arg;
} else {
$args[] = $arg;
}
}
$args = $newargs;
// Now we add the run parameters back to the array
array_unshift($args, $run_parameter);
$arr = array('args' => $args, 'run_cmd' => true);
@ -1863,16 +1959,24 @@ function proc_run($cmd){
if (!$arr['run_cmd'] OR !count($args))
return;
if (!get_config("system", "worker") OR
(($args[0] != 'php') AND !is_int($args[0]))) {
if (!get_config("system", "worker") OR (is_string($run_parameter) AND ($run_parameter != 'php'))) {
$a->proc_run($args);
return;
}
if (is_int($args[0]))
$priority = $args[0];
else
$priority = PRIORITY_MEDIUM;
$priority = PRIORITY_MEDIUM;
$dont_fork = get_config("system", "worker_dont_fork");
if (is_int($run_parameter)) {
$priority = $run_parameter;
} elseif (is_array($run_parameter)) {
if (isset($run_parameter['priority'])) {
$priority = $run_parameter['priority'];
}
if (isset($run_parameter['dont_fork'])) {
$dont_fork = $run_parameter['dont_fork'];
}
}
$argv = $args;
array_shift($argv);
@ -1889,8 +1993,9 @@ function proc_run($cmd){
intval($priority));
// Should we quit and wait for the poller to be called as a cronjob?
if (get_config("system", "worker_dont_fork"))
if ($dont_fork) {
return;
}
// Checking number of workers
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
@ -1989,9 +2094,9 @@ function current_theme(){
/**
* @brief Return full URL to theme which is currently in effect.
*
*
* Provide a sane default if nothing is chosen or the specified theme does not exist.
*
*
* @return string
*/
function current_theme_url() {
@ -2260,6 +2365,36 @@ function get_lockpath() {
return "";
}
/**
* @brief Returns the path where spool files are stored
*
* @return string Spool path
*/
function get_spoolpath() {
$spoolpath = get_config('system','spoolpath');
if (($spoolpath != "") AND is_dir($spoolpath) AND is_writable($spoolpath)) {
return($spoolpath);
}
$temppath = get_temppath();
if ($temppath != "") {
$spoolpath = $temppath."/spool";
if (!is_dir($spoolpath)) {
mkdir($spoolpath);
} elseif (!is_writable($spoolpath)) {
$spoolpath = $temppath;
}
if (is_dir($spoolpath) AND is_writable($spoolpath)) {
set_config("system", "spoolpath", $spoolpath);
return($spoolpath);
}
}
return "";
}
function get_temppath() {
$a = get_app();
@ -2338,7 +2473,7 @@ function current_load() {
/**
* @brief get c-style args
*
*
* @return int
*/
function argc() {
@ -2347,7 +2482,7 @@ function argc() {
/**
* @brief Returns the value of a argv key
*
*
* @param int $x argv key
* @return string Value of the argv key
*/
@ -2360,12 +2495,12 @@ function argv($x) {
/**
* @brief Get the data which is needed for infinite scroll
*
*
* For invinite scroll we need the page number of the actual page
* and the the URI where the content of the next page comes from.
* This data is needed for the js part in main.js.
* Note: infinite scroll does only work for the network page (module)
*
*
* @param string $module The name of the module (e.g. "network")
* @return array Of infinite scroll data
* 'pageno' => $pageno The number of the actual page

19
convert_innodb.sql

@ -1,19 +0,0 @@
ALTER TABLE `profile` DROP INDEX `pub_keywords` ;
ALTER TABLE `profile` DROP INDEX `prv_keywords` ;
ALTER TABLE `item` DROP INDEX `title` ;
ALTER TABLE `item` DROP INDEX `body` ;
ALTER TABLE `item` DROP INDEX `allow_cid` ;
ALTER TABLE `item` DROP INDEX `allow_gid` ;
ALTER TABLE `item` DROP INDEX `deny_cid` ;
ALTER TABLE `item` DROP INDEX `deny_gid` ;
ALTER TABLE `item` DROP INDEX `tag` ;
ALTER TABLE `item` DROP INDEX `file` ;
SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM';

45
database.sql

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 3.5-dev (Asparagus)
-- DB_UPDATE_VERSION 1200
-- Friendica 3.5.1-dev (Asparagus)
-- DB_UPDATE_VERSION 1208
-- ------------------------------------------
@ -58,8 +58,9 @@ CREATE TABLE IF NOT EXISTS `cache` (
`v` text,
`expire_mode` int(11) NOT NULL DEFAULT 0,
`updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY(`k`),
INDEX `updated` (`updated`)
PRIMARY KEY(`k`(191)),
INDEX `updated` (`updated`),
INDEX `expire_mode_updated` (`expire_mode`,`updated`)
) DEFAULT CHARSET=utf8mb4;
--
@ -97,7 +98,7 @@ CREATE TABLE IF NOT EXISTS `config` (
`k` varchar(255) NOT NULL DEFAULT '',
`v` text,
PRIMARY KEY(`id`),
INDEX `cat_k` (`cat`(30),`k`(30))
UNIQUE INDEX `cat_k` (`cat`(30),`k`(30))
) DEFAULT CHARSET=utf8mb4;
--
@ -118,6 +119,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`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,
@ -157,6 +159,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`writable` tinyint(1) NOT NULL DEFAULT 0,
`forum` tinyint(1) NOT NULL DEFAULT 0,
`prv` tinyint(1) NOT NULL DEFAULT 0,
`contact-type` int(11) unsigned NOT NULL DEFAULT 0,
`hidden` tinyint(1) NOT NULL DEFAULT 0,
`archive` tinyint(1) NOT NULL DEFAULT 0,
`pending` tinyint(1) NOT NULL DEFAULT 1,
@ -172,6 +175,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`ffi_keyword_blacklist` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`),
INDEX `addr_uid` (`addr`,`uid`),
INDEX `nurl` (`nurl`)
) DEFAULT CHARSET=utf8mb4;
@ -199,7 +203,8 @@ CREATE TABLE IF NOT EXISTS `deliverq` (
`cmd` varchar(32) NOT NULL DEFAULT '',
`item` int(11) NOT NULL DEFAULT 0,
`contact` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
PRIMARY KEY(`id`),
UNIQUE INDEX `cmd_item_contact` (`cmd`,`item`,`contact`)
) DEFAULT CHARSET=utf8mb4;
--
@ -326,6 +331,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
`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 '',
@ -652,6 +658,8 @@ 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_cache` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
@ -677,7 +685,7 @@ CREATE TABLE IF NOT EXISTS `oembed` (
`url` varchar(255) 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=utf8mb4;
@ -690,7 +698,7 @@ CREATE TABLE IF NOT EXISTS `parsed_url` (
`oembed` tinyint(1) NOT NULL DEFAULT 0,
`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=utf8mb4;
@ -704,7 +712,7 @@ CREATE TABLE IF NOT EXISTS `pconfig` (
`k` varchar(255) NOT NULL DEFAULT '',
`v` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid_cat_k` (`uid`,`cat`(30),`k`(30))
UNIQUE INDEX `uid_cat_k` (`uid`,`cat`(30),`k`(30))
) DEFAULT CHARSET=utf8mb4;
--
@ -734,7 +742,9 @@ CREATE TABLE IF NOT EXISTS `photo` (
`deny_cid` mediumtext,
`deny_gid` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`),
INDEX `uid_contactid` (`uid`,`contact-id`),
INDEX `uid_profile` (`uid`,`profile`),
INDEX `uid_album_created` (`uid`,`album`,`created`),
INDEX `resource-id` (`resource-id`),
INDEX `guid` (`guid`)
) DEFAULT CHARSET=utf8mb4;
@ -771,6 +781,17 @@ CREATE TABLE IF NOT EXISTS `poll_result` (
INDEX `choice` (`choice`)
) 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
--
@ -812,6 +833,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`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,
@ -877,6 +899,7 @@ CREATE TABLE IF NOT EXISTS `register` (
`uid` int(11) unsigned NOT NULL DEFAULT 0,
`password` varchar(255) NOT NULL DEFAULT '',
`language` varchar(16) NOT NULL DEFAULT '',
`note` text,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
@ -957,6 +980,7 @@ CREATE TABLE IF NOT EXISTS `term` (
INDEX `type_term` (`type`,`term`),
INDEX `uid_otype_type_term_global_created` (`uid`,`otype`,`type`,`term`,`global`,`created`),
INDEX `otype_type_term_tid` (`otype`,`type`,`term`,`tid`),
INDEX `uid_otype_type_url` (`uid`,`otype`,`type`,`url`),
INDEX `guid` (`guid`)
) DEFAULT CHARSET=utf8mb4;
@ -1048,6 +1072,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,

2
doc/Accesskeys.md

@ -1,6 +1,8 @@
Accesskeys in Friendica
=======================
* [Home](help)
General
-------
* p: profile

796
doc/BBCode.md

@ -1,208 +1,616 @@
Friendica BBCode tags reference
========================
* [Home](help)
Inline
-----
<pre>[b]bold[/b]</pre> : <strong>bold</strong>
<pre>[i]italic[/i]</pre> : <em>italic</em>
<pre>[u]underlined[/u]</pre> : <u>underlined</u>
<pre>[s]strike[/s]</pre> : <strike>strike</strike>
<pre>[color=red]red[/color]</pre> : <span style="color: red;">red</span>
<pre>[url=http://www.friendica.com]Friendica[/url]</pre> : <a href="http://www.friendica.com" target="external-link">Friendica</a>
<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">
<pre>[size=xx-small]small text[/size]</pre> : <span style="font-size: xx-small;">small text</span>
<pre>[size=xx-large]big text[/size]</pre> : <span style="font-size: xx-large;">big text</span>
<pre>[size=20]exact size[/size] (size can be any number, in pixel)</pre> : <span style="font-size: 20px;">exact size</span>
Block
-----
<pre>[code]code[/code]</pre>
<code>code</code>
<p style="clear:both;">&nbsp;</p>
<pre>[code=php]function text_highlight($s,$lang)[/code]</pre>
<code><div class="hl-main"><ol class="hl-main"><li><span class="hl-code">&nbsp;</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>
<p style="clear:both;">&nbsp;</p>
<pre>[quote]quote[/quote]</pre>
<blockquote>quote</blockquote>
<p style="clear:both;">&nbsp;</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;">&nbsp;</p>
<pre>[center]centered text[/center]</pre>
<div style="text-align:center;">centered text</div>
<p style="clear:both;">&nbsp;</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;">&nbsp;</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;">&nbsp;</p>
**List**
<pre>[list]
[*] First list element
[*] Second list element
[/list]</pre>
<ul class="listbullet" style="list-style-type: circle;">
<li> First list element<br>
</li>
<li> Second list element</li>
</ul>
[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
------
* [Creating posts](help/Text_editor)
## Inline
<style>
table.bbcodes {
margin: 1em 0;
background-color: #f9f9f9;
border: 1px solid #aaa;
border-collapse: collapse;
color: #000;
width: 100%;
}
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
}
table.bbcodes > tr > th,
table.bbcodes > * > tr > th {
background-color: #f2f2f2;
text-align: center;
width: 50%
}
</style>
<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>
### Links
<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>
## Blocks
<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">&nbsp;</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>
### Titles
<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>
### Tables
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[table]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 1[/th]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 2[/th]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 2[/th]<br>
&nbsp;&nbsp;[/tr]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 1[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 2[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 3[/td]<br>
&nbsp;&nbsp;[/tr]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 4[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 5[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 6[/td]<br>
&nbsp;&nbsp;[/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>