1
1
Fork 0

Merge pull request #5981 from MrPetovan/task/move-dbstructure-to-php

Move dbstructure to PHP array
This commit is contained in:
Michael Vogel 2018-10-22 23:19:38 +02:00 committed by GitHub
commit ebc97ba8fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 1842 additions and 1679 deletions

View file

@ -41,7 +41,6 @@ define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily'); define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
define('FRIENDICA_VERSION', '2018.12-dev'); define('FRIENDICA_VERSION', '2018.12-dev');
define('DFRN_PROTOCOL_VERSION', '2.23'); define('DFRN_PROTOCOL_VERSION', '2.23');
define('DB_UPDATE_VERSION', 1289);
define('NEW_UPDATE_ROUTINE_VERSION', 1170); define('NEW_UPDATE_ROUTINE_VERSION', 1170);
/** /**
@ -345,11 +344,6 @@ define('SR_SCOPE_ALL', 'all');
define('SR_SCOPE_TAGS', 'tags'); define('SR_SCOPE_TAGS', 'tags');
/* @}*/ /* @}*/
/**
* Lowest possible date time value
*/
define('NULL_DATE', '0001-01-01 00:00:00');
// Normally this constant is defined - but not if "pcntl" isn't installed // Normally this constant is defined - but not if "pcntl" isn't installed
if (!defined("SIGTERM")) { if (!defined("SIGTERM")) {
define("SIGTERM", 15); define("SIGTERM", 15);

File diff suppressed because it is too large Load diff

1374
config/dbstructure.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -214,11 +214,12 @@ function admin_content(App $a)
$r = q("SELECT `name` FROM `addon` WHERE `plugin_admin` = 1 ORDER BY `name`"); $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin` = 1 ORDER BY `name`");
$aside_tools['addons_admin'] = []; $aside_tools['addons_admin'] = [];
$addons_admin = [];
foreach ($r as $h) { foreach ($r as $h) {
$addon = $h['name']; $addon = $h['name'];
$aside_tools['addons_admin'][] = ["admin/addons/" . $addon, $addon, "addon"]; $aside_tools['addons_admin'][] = ["admin/addons/" . $addon, $addon, "addon"];
// temp addons with admin // temp addons with admin
$a->addons_admin[] = $addon; $addons_admin[] = $addon;
} }
$t = get_markup_template('admin/aside.tpl'); $t = get_markup_template('admin/aside.tpl');
@ -243,7 +244,7 @@ function admin_content(App $a)
$o = admin_page_users($a); $o = admin_page_users($a);
break; break;
case 'addons': case 'addons':
$o = admin_page_addons($a); $o = admin_page_addons($a, $addons_admin);
break; break;
case 'themes': case 'themes':
$o = admin_page_themes($a); $o = admin_page_themes($a);
@ -932,7 +933,7 @@ function admin_page_summary(App $a)
'$platform' => FRIENDICA_PLATFORM, '$platform' => FRIENDICA_PLATFORM,
'$codename' => FRIENDICA_CODENAME, '$codename' => FRIENDICA_CODENAME,
'$build' => Config::get('system', 'build'), '$build' => Config::get('system', 'build'),
'$addons' => [L10n::t('Active addons'), $a->addons], '$addons' => [L10n::t('Active addons'), Addon::getEnabledList()],
'$serversettings' => $server_settings, '$serversettings' => $server_settings,
'$showwarning' => $showwarning, '$showwarning' => $showwarning,
'$warningtext' => $warningtext '$warningtext' => $warningtext
@ -1957,9 +1958,10 @@ function admin_page_users(App $a)
* The returned string returned hulds the HTML code of the page. * The returned string returned hulds the HTML code of the page.
* *
* @param App $a * @param App $a
* @param array $addons_admin A list of admin addon names
* @return string * @return string
*/ */
function admin_page_addons(App $a) function admin_page_addons(App $a, array $addons_admin)
{ {
/* /*
* Single addon * Single addon
@ -1971,27 +1973,25 @@ function admin_page_addons(App $a)
return ''; return '';
} }
if (x($_GET, "a") && $_GET['a'] == "t") { if (defaults($_GET, 'a', '') == "t") {
BaseModule::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_themes', 't'); BaseModule::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_themes', 't');
// Toggle addon status // Toggle addon status
$idx = array_search($addon, $a->addons); if (Addon::isEnabled($addon)) {
if ($idx !== false) {
unset($a->addons[$idx]);
Addon::uninstall($addon); Addon::uninstall($addon);
info(L10n::t("Addon %s disabled.", $addon)); info(L10n::t("Addon %s disabled.", $addon));
} else { } else {
$a->addons[] = $addon;
Addon::install($addon); Addon::install($addon);
info(L10n::t("Addon %s enabled.", $addon)); info(L10n::t("Addon %s enabled.", $addon));
} }
Config::set("system", "addon", implode(", ", $a->addons));
Addon::saveEnabledList();
$a->internalRedirect('admin/addons'); $a->internalRedirect('admin/addons');
return ''; // NOTREACHED return ''; // NOTREACHED
} }
// display addon details // display addon details
if (in_array($addon, $a->addons)) { if (Addon::isEnabled($addon)) {
$status = "on"; $status = "on";
$action = L10n::t("Disable"); $action = L10n::t("Disable");
} else { } else {
@ -2007,7 +2007,7 @@ function admin_page_addons(App $a)
} }
$admin_form = ""; $admin_form = "";
if (in_array($addon, $a->addons_admin)) { if (in_array($addon, $addons_admin)) {
require_once "addon/$addon/$addon.php"; require_once "addon/$addon/$addon.php";
$func = $addon . '_addon_admin'; $func = $addon . '_addon_admin';
$func($a, $admin_form); $func($a, $admin_form);
@ -2058,7 +2058,7 @@ function admin_page_addons(App $a)
$show_addon = true; $show_addon = true;
// If the addon is unsupported, then only show it, when it is enabled // If the addon is unsupported, then only show it, when it is enabled
if ((strtolower($info["status"]) == "unsupported") && !in_array($id, $a->addons)) { if ((strtolower($info["status"]) == "unsupported") && !Addon::isEnabled($id)) {
$show_addon = false; $show_addon = false;
} }
@ -2068,7 +2068,7 @@ function admin_page_addons(App $a)
} }
if ($show_addon) { if ($show_addon) {
$addons[] = [$id, (in_array($id, $a->addons) ? "on" : "off"), $info]; $addons[] = [$id, (Addon::isEnabled($id) ? "on" : "off"), $info];
} }
} }
} }

View file

@ -15,9 +15,9 @@ use Friendica\Database\DBA;
use Friendica\Model\Event; use Friendica\Model\Event;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Module\Login;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use Friendica\Module\Login;
require_once 'include/items.php'; require_once 'include/items.php';
@ -66,8 +66,8 @@ function events_post(App $a)
// The default setting for the `private` field in event_store() is false, so mirror that // The default setting for the `private` field in event_store() is false, so mirror that
$private_event = false; $private_event = false;
$start = NULL_DATE; $start = DBA::NULL_DATETIME;
$finish = NULL_DATE; $finish = DBA::NULL_DATETIME;
if ($start_text) { if ($start_text) {
$start = $start_text; $start = $start_text;
@ -111,7 +111,7 @@ function events_post(App $a)
$a->internalRedirect($onerror_path); $a->internalRedirect($onerror_path);
} }
if (!$summary || ($start === NULL_DATE)) { if (!$summary || ($start === DBA::NULL_DATETIME)) {
notice(L10n::t('Event title and start time are required.') . EOL); notice(L10n::t('Event title and start time are required.') . EOL);
if (intval($_REQUEST['preview'])) { if (intval($_REQUEST['preview'])) {
echo L10n::t('Event title and start time are required.'); echo L10n::t('Event title and start time are required.');

View file

@ -31,15 +31,7 @@ function friendica_init(App $a)
$admin = false; $admin = false;
} }
$visible_addons = []; $visible_addons = Addon::getVisibleList();
if (is_array($a->addons) && count($a->addons)) {
$r = q("SELECT * FROM `addon` WHERE `hidden` = 0");
if (DBA::isResult($r)) {
foreach ($r as $rr) {
$visible_addons[] = $rr['name'];
}
}
}
Config::load('feature_lock'); Config::load('feature_lock');
$locked_features = []; $locked_features = [];
@ -91,16 +83,7 @@ function friendica_content(App $a)
$o .= L10n::t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'); $o .= L10n::t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca');
$o .= '</p>' . PHP_EOL; $o .= '</p>' . PHP_EOL;
$visible_addons = []; $visible_addons = Addon::getVisibleList();
if (is_array($a->addons) && count($a->addons)) {
$r = q("SELECT * FROM `addon` WHERE `hidden` = 0");
if (DBA::isResult($r)) {
foreach ($r as $rr) {
$visible_addons[] = $rr['name'];
}
}
}
if (count($visible_addons)) { if (count($visible_addons)) {
$o .= '<p>' . L10n::t('Installed addons/apps:') . '</p>' . PHP_EOL; $o .= '<p>' . L10n::t('Installed addons/apps:') . '</p>' . PHP_EOL;
$sorted = $visible_addons; $sorted = $visible_addons;

View file

@ -18,10 +18,10 @@ use Friendica\Database\DBA;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\GContact; use Friendica\Model\GContact;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Module\Login;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use Friendica\Module\Login;
function profiles_init(App $a) { function profiles_init(App $a) {
@ -252,7 +252,7 @@ function profiles_post(App $a) {
$with = ((x($_POST,'with')) ? notags(trim($_POST['with'])) : ''); $with = ((x($_POST,'with')) ? notags(trim($_POST['with'])) : '');
if (! strlen($howlong)) { if (! strlen($howlong)) {
$howlong = NULL_DATE; $howlong = DBA::NULL_DATETIME;
} else { } else {
$howlong = DateTimeFormat::convert($howlong, 'UTC', date_default_timezone_get()); $howlong = DateTimeFormat::convert($howlong, 'UTC', date_default_timezone_get());
} }
@ -619,7 +619,7 @@ function profiles_content(App $a) {
'$gender' => ContactSelector::gender($r[0]['gender']), '$gender' => ContactSelector::gender($r[0]['gender']),
'$marital' => ['selector' => ContactSelector::maritalStatus($r[0]['marital']), 'value' => $r[0]['marital']], '$marital' => ['selector' => ContactSelector::maritalStatus($r[0]['marital']), 'value' => $r[0]['marital']],
'$with' => ['with', L10n::t("Who: \x28if applicable\x29"), strip_tags($r[0]['with']), L10n::t('Examples: cathy123, Cathy Williams, cathy@example.com')], '$with' => ['with', L10n::t("Who: \x28if applicable\x29"), strip_tags($r[0]['with']), L10n::t('Examples: cathy123, Cathy Williams, cathy@example.com')],
'$howlong' => ['howlong', L10n::t('Since [date]:'), ($r[0]['howlong'] <= NULL_DATE ? '' : DateTimeFormat::local($r[0]['howlong']))], '$howlong' => ['howlong', L10n::t('Since [date]:'), ($r[0]['howlong'] <= DBA::NULL_DATETIME ? '' : DateTimeFormat::local($r[0]['howlong']))],
'$sexual' => ['selector' => ContactSelector::sexualPreference($r[0]['sexual']), 'value' => $r[0]['sexual']], '$sexual' => ['selector' => ContactSelector::sexualPreference($r[0]['sexual']), 'value' => $r[0]['sexual']],
'$about' => ['about', L10n::t('Tell us about yourself...'), $r[0]['about']], '$about' => ['about', L10n::t('Tell us about yourself...'), $r[0]['about']],
'$xmpp' => ['xmpp', L10n::t("XMPP \x28Jabber\x29 address:"), $r[0]['xmpp'], L10n::t("The XMPP address will be propagated to your contacts so that they can follow you.")], '$xmpp' => ['xmpp', L10n::t("XMPP \x28Jabber\x29 address:"), $r[0]['xmpp'], L10n::t("The XMPP address will be propagated to your contacts so that they can follow you.")],

View file

@ -20,11 +20,10 @@ use Friendica\Model\Contact;
use Friendica\Model\GContact; use Friendica\Model\GContact;
use Friendica\Model\Group; use Friendica\Model\Group;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\Login;
use Friendica\Protocol\Email; use Friendica\Protocol\Email;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use Friendica\Util\Security;
use Friendica\Module\Login;
function get_theme_config_file($theme) function get_theme_config_file($theme)
{ {
@ -830,7 +829,7 @@ function settings_content(App $a)
$mail_pubmail = ((DBA::isResult($r)) ? $r[0]['pubmail'] : 0); $mail_pubmail = ((DBA::isResult($r)) ? $r[0]['pubmail'] : 0);
$mail_action = ((DBA::isResult($r)) ? $r[0]['action'] : 0); $mail_action = ((DBA::isResult($r)) ? $r[0]['action'] : 0);
$mail_movetofolder = ((DBA::isResult($r)) ? $r[0]['movetofolder'] : ''); $mail_movetofolder = ((DBA::isResult($r)) ? $r[0]['movetofolder'] : '');
$mail_chk = ((DBA::isResult($r)) ? $r[0]['last_check'] : NULL_DATE); $mail_chk = ((DBA::isResult($r)) ? $r[0]['last_check'] : DBA::NULL_DATETIME);
$tpl = get_markup_template('settings/connectors.tpl'); $tpl = get_markup_template('settings/connectors.tpl');

View file

@ -50,11 +50,8 @@ class App
public $argv; public $argv;
public $argc; public $argc;
public $module; public $module;
public $hooks = [];
public $timezone; public $timezone;
public $interactive = true; public $interactive = true;
public $addons;
public $addons_admin = [];
public $identities; public $identities;
public $is_mobile = false; public $is_mobile = false;
public $is_tablet = false; public $is_tablet = false;
@ -360,7 +357,7 @@ class App
Core\Config::load(); Core\Config::load();
if ($this->getMode()->has(App\Mode::DBAVAILABLE)) { if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
Core\Addon::loadHooks(); Core\Hook::loadHooks();
$this->loadAddonConfig(); $this->loadAddonConfig();
} }
@ -576,7 +573,11 @@ class App
$stamp1 = microtime(true); $stamp1 = microtime(true);
DBA::connect($db_host, $db_user, $db_pass, $db_data, $charset); if (DBA::connect($db_host, $db_user, $db_pass, $db_data, $charset)) {
// Loads DB_UPDATE_VERSION constant
Database\DBStructure::definition(false);
}
unset($db_host, $db_user, $db_pass, $db_data, $charset); unset($db_host, $db_user, $db_pass, $db_data, $charset);
$this->saveTimestamp($stamp1, 'network'); $this->saveTimestamp($stamp1, 'network');

View file

@ -8,15 +8,20 @@ use Friendica\App;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Database\DBA; use Friendica\Database\DBA;
require_once 'include/dba.php';
/** /**
* Some functions to handle addons * Some functions to handle addons
*/ */
class Addon extends BaseObject class Addon extends BaseObject
{ {
/** /**
* @brief Synchronise addons: * List of the names of enabled addons
*
* @var array
*/
private static $addons = [];
/**
* @brief Synchronize addons:
* *
* system.addon contains a comma-separated list of names * system.addon contains a comma-separated list of names
* of addons which are used on this system. * of addons which are used on this system.
@ -27,15 +32,13 @@ class Addon extends BaseObject
* call the install procedure and add it to the database. * call the install procedure and add it to the database.
* *
*/ */
public static function check() public static function loadAddons()
{ {
$a = self::getApp(); $installed_addons = [];
$r = DBA::select('addon', [], ['installed' => 1]); $r = DBA::select('addon', [], ['installed' => 1]);
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
$installed = DBA::toArray($r); $installed_addons = DBA::toArray($r);
} else {
$installed = [];
} }
$addons = Config::get('system', 'addon'); $addons = Config::get('system', 'addon');
@ -45,33 +48,25 @@ class Addon extends BaseObject
$addons_arr = explode(',', str_replace(' ', '', $addons)); $addons_arr = explode(',', str_replace(' ', '', $addons));
} }
$a->addons = $addons_arr; self::$addons = $addons_arr;
$installed_arr = []; $installed_arr = [];
if (count($installed)) { foreach ($installed_addons as $addon) {
foreach ($installed as $i) { if (!self::isEnabled($addon['name'])) {
if (!in_array($i['name'], $addons_arr)) { self::uninstall($addon['name']);
self::uninstall($i['name']);
} else { } else {
$installed_arr[] = $i['name']; $installed_arr[] = $addon['name'];
}
} }
} }
if (count($addons_arr)) { foreach (self::$addons as $p) {
foreach ($addons_arr as $p) {
if (!in_array($p, $installed_arr)) { if (!in_array($p, $installed_arr)) {
self::install($p); self::install($p);
} }
} }
} }
self::loadHooks();
return;
}
/** /**
* @brief uninstalls an addon. * @brief uninstalls an addon.
* *
@ -88,6 +83,8 @@ class Addon extends BaseObject
$func = $addon . '_uninstall'; $func = $addon . '_uninstall';
$func(); $func();
} }
unset(self::$addons[$idx]);
} }
/** /**
@ -110,7 +107,7 @@ class Addon extends BaseObject
$func = $addon . '_install'; $func = $addon . '_install';
$func(); $func();
$addon_admin = (function_exists($addon."_addon_admin") ? 1 : 0); $addon_admin = (function_exists($addon . "_addon_admin") ? 1 : 0);
DBA::insert('addon', ['name' => $addon, 'installed' => true, DBA::insert('addon', ['name' => $addon, 'installed' => true,
'timestamp' => $t, 'plugin_admin' => $addon_admin]); 'timestamp' => $t, 'plugin_admin' => $addon_admin]);
@ -122,6 +119,10 @@ class Addon extends BaseObject
if (file_exists('addon/' . $addon . '/.hidden')) { if (file_exists('addon/' . $addon . '/.hidden')) {
DBA::update('addon', ['hidden' => true], ['name' => $addon]); DBA::update('addon', ['hidden' => true], ['name' => $addon]);
} }
if (!self::isEnabled($addon)) {
self::$addons[] = $addon;
}
return true; return true;
} else { } else {
logger("Addons: FAILED installing " . $addon); logger("Addons: FAILED installing " . $addon);
@ -174,165 +175,6 @@ class Addon extends BaseObject
} }
} }
/**
* @brief check if addon is enabled
*
* @param string $addon
* @return boolean
*/
public static function isEnabled($addon)
{
return DBA::exists('addon', ['installed' => true, 'name' => $addon]);
}
/**
* @brief registers a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook will call
* @param int $priority A priority (defaults to 0)
* @return mixed|bool
*/
public static function registerHook($hook, $file, $function, $priority = 0)
{
$file = str_replace(self::getApp()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
$condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
$exists = DBA::exists('hook', $condition);
if ($exists) {
return true;
}
$r = DBA::insert('hook', ['hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority]);
return $r;
}
/**
* @brief unregisters a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook called
* @return array
*/
public static function unregisterHook($hook, $file, $function)
{
$relative_file = str_replace(self::getApp()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
// This here is only needed for fixing a problem that existed on the develop branch
$condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
DBA::delete('hook', $condition);
$condition = ['hook' => $hook, 'file' => $relative_file, 'function' => $function];
$r = DBA::delete('hook', $condition);
return $r;
}
/**
* Load hooks
*/
public static function loadHooks()
{
$a = self::getApp();
$a->hooks = [];
$r = DBA::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]);
while ($rr = DBA::fetch($r)) {
if (! array_key_exists($rr['hook'], $a->hooks)) {
$a->hooks[$rr['hook']] = [];
}
$a->hooks[$rr['hook']][] = [$rr['file'],$rr['function']];
}
DBA::close($r);
}
/**
* @brief Forks a hook.
*
* Use this function when you want to fork a hook via the worker.
*
* @param string $name of the hook to call
* @param string|array $data to transmit to the callback handler
*/
public static function forkHooks($priority, $name, $data = null)
{
$a = self::getApp();
if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {
foreach ($a->hooks[$name] as $hook) {
Worker::add($priority, 'ForkHook', $name, $hook, $data);
}
}
}
/**
* @brief Calls a hook.
*
* Use this function when you want to be able to allow a hook to manipulate
* the provided data.
*
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
public static function callHooks($name, &$data = null)
{
$a = self::getApp();
if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {
foreach ($a->hooks[$name] as $hook) {
self::callSingleHook($a, $name, $hook, $data);
}
}
}
/**
* @brief Calls a single hook.
*
* @param App $a
* @param string $name of the hook to call
* @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler
*/
public static function callSingleHook(App $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/' . $a->getCurrentTheme()) === false) {
return;
}
@include_once($hook[0]);
if (function_exists($hook[1])) {
$func = $hook[1];
$func($a, $data);
} else {
// remove orphan hooks
$condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];
DBA::delete('hook', $condition, ['cascade' => false]);
}
}
/**
* check if an app_menu hook exist for addon $name.
* Return true if the addon is an app
*/
public static function isApp($name)
{
$a = self::getApp();
if (is_array($a->hooks) && (array_key_exists('app_menu', $a->hooks))) {
foreach ($a->hooks['app_menu'] as $hook) {
if ($hook[0] == 'addon/'.$name.'/'.$name.'.php') {
return true;
}
}
}
return false;
}
/** /**
* @brief Parse addon comment in search of addon infos. * @brief Parse addon comment in search of addon infos.
* *
@ -401,4 +243,97 @@ class Addon extends BaseObject
} }
return $info; return $info;
} }
/**
* Checks if the provided addon is enabled
*
* @param string $addon
* @return boolean
*/
public static function isEnabled($addon)
{
return in_array($addon, self::$addons);
}
/**
* Returns a list of the enabled addon names
*
* @return array
*/
public static function getEnabledList()
{
return self::$addons;
}
/**
* Saves the current enabled addon list in the system.addon config key
*
* @return boolean
*/
public static function saveEnabledList()
{
return Config::set("system", "addon", implode(", ", self::$addons));
}
/**
* Returns the list of non-hidden enabled addon names
*
* @return array
*/
public static function getVisibleList()
{
$visible_addons = [];
$stmt = DBA::select('addon', ['name'], ['hidden' => false, 'installed' => true]);
if (DBA::isResult($stmt)) {
foreach (DBA::toArray($stmt) as $addon) {
$visible_addons[] = $addon['name'];
}
}
return $visible_addons;
}
/**
* Shim of Hook::register left for backward compatibility purpose.
*
* @see Hook::register
* @deprecated since version 2018.12
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook will call
* @param int $priority A priority (defaults to 0)
* @return mixed|bool
*/
public static function registerHook($hook, $file, $function, $priority = 0)
{
return Hook::register($hook, $file, $function, $priority);
}
/**
* Shim of Hook::unregister left for backward compatibility purpose.
*
* @see Hook::unregister
* @deprecated since version 2018.12
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook called
* @return boolean
*/
public static function unregisterHook($hook, $file, $function)
{
return Hook::unregister($hook, $file, $function);
}
/**
* Shim of Hook::callAll left for backward-compatibility purpose.
*
* @see Hook::callAll
* @deprecated since version 2018.12
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
public static function callHooks($name, &$data = null)
{
Hook::callAll($name, $data);
}
} }

View file

@ -5,13 +5,13 @@
namespace Friendica\Core; namespace Friendica\Core;
use Friendica\Core\Addon;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Util\DateTimeFormat;
use Friendica\Database\DBA;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Database\DBA;
use Friendica\Util\DateTimeFormat;
/** /**
* Handle Authentification, Session and Cookies * Handle Authentification, Session and Cookies
@ -81,7 +81,7 @@ class Authentication extends BaseObject
$a->user = $user_record; $a->user = $user_record;
if ($interactive) { if ($interactive) {
if ($a->user['login_date'] <= NULL_DATE) { if ($a->user['login_date'] <= DBA::NULL_DATETIME) {
$_SESSION['return_path'] = 'profile_photo/new'; $_SESSION['return_path'] = 'profile_photo/new';
$a->module = 'profile_photo'; $a->module = 'profile_photo';
info(L10n::t("Welcome ") . $a->user['username'] . EOL); info(L10n::t("Welcome ") . $a->user['username'] . EOL);

191
src/Core/Hook.php Normal file
View file

@ -0,0 +1,191 @@
<?php
/**
* @file src/Core/Hook.php
*/
namespace Friendica\Core;
use Friendica\App;
use Friendica\BaseObject;
use Friendica\Database\DBA;
/**
* Some functions to handle hooks
*/
class Hook extends BaseObject
{
/**
* Array of registered hooks
*
* Format:
* [
* ["<hook name>"] => [
* 0 => "<hook file>",
* 1 => "<hook function name>"
* ],
* ...
* ]
*
* @var array
*/
private static $hooks = [];
/**
* Load hooks
*/
public static function loadHooks()
{
self::$hooks = [];
$stmt = DBA::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]);
while ($hook = DBA::fetch($stmt)) {
if (!array_key_exists($hook['hook'], self::$hooks)) {
self::$hooks[$hook['hook']] = [];
}
self::$hooks[$hook['hook']][] = [$hook['file'], $hook['function']];
}
DBA::close($stmt);
}
/**
* Registers a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook will call
* @param int $priority A priority (defaults to 0)
* @return mixed|bool
*/
public static function register($hook, $file, $function, $priority = 0)
{
$file = str_replace(self::getApp()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
$condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
if (DBA::exists('hook', $condition)) {
return true;
}
$result = DBA::insert('hook', ['hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority]);
return $result;
}
/**
* Unregisters a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook called
* @return boolean
*/
public static function unregister($hook, $file, $function)
{
$relative_file = str_replace(self::getApp()->getBasePath() . DIRECTORY_SEPARATOR, '', $file);
// This here is only needed for fixing a problem that existed on the develop branch
$condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
DBA::delete('hook', $condition);
$condition = ['hook' => $hook, 'file' => $relative_file, 'function' => $function];
$result = DBA::delete('hook', $condition);
return $result;
}
/**
* Returns the list of callbacks for a single hook
*
* @param string $name Name of the hook
* @return array
*/
public static function getByName($name)
{
$return = [];
if (isset(self::$hooks[$name])) {
$return = self::$hooks[$name];
}
return $return;
}
/**
* @brief Forks a hook.
*
* Use this function when you want to fork a hook via the worker.
*
* @param integer $priority of the hook
* @param string $name of the hook to call
* @param mixed $data to transmit to the callback handler
*/
public static function fork($priority, $name, $data = null)
{
if (array_key_exists($name, self::$hooks)) {
foreach (self::$hooks[$name] as $hook) {
Worker::add($priority, 'ForkHook', $name, $hook, $data);
}
}
}
/**
* @brief Calls a hook.
*
* Use this function when you want to be able to allow a hook to manipulate
* the provided data.
*
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
public static function callAll($name, &$data = null)
{
if (array_key_exists($name, self::$hooks)) {
foreach (self::$hooks[$name] as $hook) {
self::callSingle(self::getApp(), $name, $hook, $data);
}
}
}
/**
* @brief Calls a single hook.
*
* @param App $a
* @param string $name of the hook to call
* @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler
*/
public static function callSingle(App $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/' . $a->getCurrentTheme()) === false) {
return;
}
@include_once($hook[0]);
if (function_exists($hook[1])) {
$func = $hook[1];
$func($a, $data);
} else {
// remove orphan hooks
$condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];
DBA::delete('hook', $condition, ['cascade' => false]);
}
}
/**
* Checks if an app_menu hook exist for the provided addon name.
* Return true if the addon is an app
*
* @param string $name Name of the addon
* @return boolean
*/
public static function isAddonApp($name)
{
if (array_key_exists('app_menu', self::$hooks)) {
foreach (self::$hooks['app_menu'] as $hook) {
if ($hook[0] == 'addon/' . $name . '/' . $name . '.php') {
return true;
}
}
}
return false;
}
}

View file

@ -180,7 +180,7 @@ class UserImport
} }
if ($contact['uid'] == $olduid && $contact['self'] == '0') { if ($contact['uid'] == $olduid && $contact['self'] == '0') {
// set contacts 'avatar-date' to NULL_DATE to let worker to update urls // set contacts 'avatar-date' to NULL_DATE to let worker to update urls
$contact["avatar-date"] = NULL_DATE; $contact["avatar-date"] = DBA::NULL_DATETIME;
switch ($contact['network']) { switch ($contact['network']) {
case Protocol::DFRN: case Protocol::DFRN:

View file

@ -4,11 +4,11 @@
*/ */
namespace Friendica\Core; namespace Friendica\Core;
use Friendica\BaseObject;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Process; use Friendica\Model\Process;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\BaseObject;
require_once 'include/dba.php'; require_once 'include/dba.php';
@ -154,7 +154,7 @@ class Worker
private static function totalEntries() private static function totalEntries()
{ {
return DBA::count('workerqueue', ["`executed` <= ? AND NOT `done` AND `next_try` < ?", return DBA::count('workerqueue', ["`executed` <= ? AND NOT `done` AND `next_try` < ?",
NULL_DATE, DateTimeFormat::utcNow()]); DBA::NULL_DATETIME, DateTimeFormat::utcNow()]);
} }
/** /**
@ -164,7 +164,7 @@ class Worker
*/ */
private static function highestPriority() private static function highestPriority()
{ {
$condition = ["`executed` <= ? AND NOT `done` AND `next_try` < ?", NULL_DATE, DateTimeFormat::utcNow()]; $condition = ["`executed` <= ? AND NOT `done` AND `next_try` < ?", DBA::NULL_DATETIME, DateTimeFormat::utcNow()];
$workerqueue = DBA::selectFirst('workerqueue', ['priority'], $condition, ['order' => ['priority']]); $workerqueue = DBA::selectFirst('workerqueue', ['priority'], $condition, ['order' => ['priority']]);
if (DBA::isResult($workerqueue)) { if (DBA::isResult($workerqueue)) {
return $workerqueue["priority"]; return $workerqueue["priority"];
@ -183,7 +183,7 @@ class Worker
private static function processWithPriorityActive($priority) private static function processWithPriorityActive($priority)
{ {
$condition = ["`priority` <= ? AND `executed` > ? AND NOT `done` AND `next_try` < ?", $condition = ["`priority` <= ? AND `executed` > ? AND NOT `done` AND `next_try` < ?",
$priority, NULL_DATE, DateTimeFormat::utcNow()]; $priority, DBA::NULL_DATETIME, DateTimeFormat::utcNow()];
return DBA::exists('workerqueue', $condition); return DBA::exists('workerqueue', $condition);
} }
@ -553,7 +553,7 @@ class Worker
$entries = DBA::select( $entries = DBA::select(
'workerqueue', 'workerqueue',
['id', 'pid', 'executed', 'priority', 'parameter'], ['id', 'pid', 'executed', 'priority', 'parameter'],
['`executed` > ? AND NOT `done` AND `pid` != 0', NULL_DATE], ['`executed` > ? AND NOT `done` AND `pid` != 0', DBA::NULL_DATETIME],
['order' => ['priority', 'created']] ['order' => ['priority', 'created']]
); );
@ -561,7 +561,7 @@ class Worker
if (!posix_kill($entry["pid"], 0)) { if (!posix_kill($entry["pid"], 0)) {
DBA::update( DBA::update(
'workerqueue', 'workerqueue',
['executed' => NULL_DATE, 'pid' => 0], ['executed' => DBA::NULL_DATETIME, 'pid' => 0],
['id' => $entry["id"]] ['id' => $entry["id"]]
); );
} else { } else {
@ -597,7 +597,7 @@ class Worker
} }
DBA::update( DBA::update(
'workerqueue', 'workerqueue',
['executed' => NULL_DATE, 'created' => DateTimeFormat::utcNow(), 'priority' => $new_priority, 'pid' => 0], ['executed' => DBA::NULL_DATETIME, 'created' => DateTimeFormat::utcNow(), 'priority' => $new_priority, 'pid' => 0],
['id' => $entry["id"]] ['id' => $entry["id"]]
); );
} else { } else {
@ -809,7 +809,7 @@ class Worker
'workerqueue', 'workerqueue',
['id'], ['id'],
["`executed` <= ? AND `priority` < ? AND NOT `done` AND `next_try` < ?", ["`executed` <= ? AND `priority` < ? AND NOT `done` AND `next_try` < ?",
NULL_DATE, $highest_priority, DateTimeFormat::utcNow()], DBA::NULL_DATETIME, $highest_priority, DateTimeFormat::utcNow()],
['limit' => $limit, 'order' => ['priority', 'created']] ['limit' => $limit, 'order' => ['priority', 'created']]
); );
@ -826,7 +826,7 @@ class Worker
'workerqueue', 'workerqueue',
['id'], ['id'],
["`executed` <= ? AND `priority` > ? AND NOT `done` AND `next_try` < ?", ["`executed` <= ? AND `priority` > ? AND NOT `done` AND `next_try` < ?",
NULL_DATE, $highest_priority, DateTimeFormat::utcNow()], DBA::NULL_DATETIME, $highest_priority, DateTimeFormat::utcNow()],
['limit' => $limit, 'order' => ['priority', 'created']] ['limit' => $limit, 'order' => ['priority', 'created']]
); );
@ -846,7 +846,7 @@ class Worker
'workerqueue', 'workerqueue',
['id'], ['id'],
["`executed` <= ? AND NOT `done` AND `next_try` < ?", ["`executed` <= ? AND NOT `done` AND `next_try` < ?",
NULL_DATE, DateTimeFormat::utcNow()], DBA::NULL_DATETIME, DateTimeFormat::utcNow()],
['limit' => $limit, 'order' => ['priority', 'created']] ['limit' => $limit, 'order' => ['priority', 'created']]
); );
@ -912,7 +912,7 @@ class Worker
{ {
$mypid = getmypid(); $mypid = getmypid();
DBA::update('workerqueue', ['executed' => NULL_DATE, 'pid' => 0], ['pid' => $mypid, 'done' => false]); DBA::update('workerqueue', ['executed' => DBA::NULL_DATETIME, 'pid' => 0], ['pid' => $mypid, 'done' => false]);
} }
/** /**
@ -1147,7 +1147,7 @@ class Worker
logger('Defer execution ' . $retrial . ' of id ' . $id . ' to ' . $next, LOGGER_DEBUG); logger('Defer execution ' . $retrial . ' of id ' . $id . ' to ' . $next, LOGGER_DEBUG);
$fields = ['retrial' => $retrial + 1, 'next_try' => $next, 'executed' => NULL_DATE, 'pid' => 0]; $fields = ['retrial' => $retrial + 1, 'next_try' => $next, 'executed' => DBA::NULL_DATETIME, 'pid' => 0];
DBA::update('workerqueue', $fields, ['id' => $id]); DBA::update('workerqueue', $fields, ['id' => $id]);
} }

View file

@ -24,6 +24,15 @@ require_once 'include/dba.php';
*/ */
class DBA class DBA
{ {
/**
* Lowest possible date value
*/
const NULL_DATE = '0001-01-01';
/**
* Lowest possible datetime value
*/
const NULL_DATETIME = '0001-01-01 00:00:00';
public static $connected = false; public static $connected = false;
private static $server_info = ''; private static $server_info = '';

View file

@ -5,8 +5,8 @@
namespace Friendica\Database; namespace Friendica\Database;
use Exception; use Exception;
use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
@ -22,6 +22,13 @@ require_once 'include/text.php';
*/ */
class DBStructure class DBStructure
{ {
/**
* Database structure definition loaded from config/dbstructure.php
*
* @var array
*/
private static $definition = [];
/* /*
* Converts all tables from MyISAM to InnoDB * Converts all tables from MyISAM to InnoDB
*/ */
@ -166,7 +173,7 @@ class DBStructure
} }
public static function printStructure() { public static function printStructure() {
$database = self::definition(); $database = self::definition(false);
echo "-- ------------------------------------------\n"; echo "-- ------------------------------------------\n";
echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n"; echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
@ -822,43 +829,40 @@ class DBStructure
} }
/** /**
* Loads the database structure definition from the /config/dbstructure.json file * Loads the database structure definition from the config/dbstructure.php file.
* * On first pass, defines DB_UPDATE_VERSION constant.
* Expected format:
* "table_name": {
* "comment": "meaningful table comment",
* "fields": {
* "field_name1": {"type": "int unsigned", "not null": "1", "extra": "auto_increment", "primary": "1", "comment": "meaningful field comment"},
* "field_name2": {"type": "varchar(50)", "not null": "1", "default": "", "comment": "meaningful field comment"},
* },
* "indexes": {
* "PRIMARY": ["field_name1"],
* "name": ["UNIQUE", "field_name2"]
* }
* }
* *
* @see config/dbstructure.php
* @param boolean $with_addons_structure Whether to tack on addons additional tables
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function definition() { public static function definition($with_addons_structure = true)
{
if (!self::$definition) {
$a = \Friendica\BaseObject::getApp(); $a = \Friendica\BaseObject::getApp();
$filename = $a->getBasePath() . '/config/dbstructure.json'; $filename = $a->getBasePath() . '/config/dbstructure.php';
if (!is_readable($filename)) { if (!is_readable($filename)) {
throw new Exception('Missing database structure config file config/dbstructure.json'); throw new Exception('Missing database structure config file config/dbstructure.php');
} }
$json = file_get_contents($filename); $definition = require $filename;
$database = json_decode($json, true); if (!$definition) {
throw new Exception('Corrupted database structure config file config/dbstructure.php');
if (!$database) {
throw new Exception('Corrupted database structure config file config/dbstructure.json');
} }
Addon::callHooks('dbstructure_definition', $database); self::$definition = $definition;
} else {
$definition = self::$definition;
}
return $database; if ($with_addons_structure) {
Hook::callAll('dbstructure_definition', $definition);
}
return $definition;
} }
} }

View file

@ -8,7 +8,6 @@ use Friendica\BaseObject;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
@ -17,8 +16,8 @@ use Friendica\Model\Profile;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\DFRN; use Friendica\Protocol\DFRN;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
use Friendica\Protocol\PortableContact; use Friendica\Protocol\PortableContact;
use Friendica\Protocol\Salmon; use Friendica\Protocol\Salmon;
@ -594,9 +593,9 @@ class Contact extends BaseObject
return; return;
} }
if ($contact['term-date'] <= NULL_DATE) { if ($contact['term-date'] <= DBA::NULL_DATETIME) {
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]); DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE]); DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), DBA::NULL_DATETIME]);
} else { } else {
/* @todo /* @todo
* We really should send a notification to the owner after 2-3 weeks * We really should send a notification to the owner after 2-3 weeks
@ -629,7 +628,7 @@ class Contact extends BaseObject
*/ */
public static function unmarkForArchival(array $contact) public static function unmarkForArchival(array $contact)
{ {
$condition = ['`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], NULL_DATE]; $condition = ['`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], DBA::NULL_DATETIME];
$exists = DBA::exists('contact', $condition); $exists = DBA::exists('contact', $condition);
// We don't need to update, we never marked this contact for archival // We don't need to update, we never marked this contact for archival
@ -646,7 +645,7 @@ class Contact extends BaseObject
} }
// It's a miracle. Our dead contact has inexplicably come back to life. // It's a miracle. Our dead contact has inexplicably come back to life.
$fields = ['term-date' => NULL_DATE, 'archive' => false]; $fields = ['term-date' => DBA::NULL_DATETIME, 'archive' => false];
DBA::update('contact', $fields, ['id' => $contact['id']]); DBA::update('contact', $fields, ['id' => $contact['id']]);
DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]); DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]);

View file

@ -257,10 +257,10 @@ class Event extends BaseObject
$event['created'] = DateTimeFormat::utc(defaults($arr, 'created' , 'now')); $event['created'] = DateTimeFormat::utc(defaults($arr, 'created' , 'now'));
$event['edited'] = DateTimeFormat::utc(defaults($arr, 'edited' , 'now')); $event['edited'] = DateTimeFormat::utc(defaults($arr, 'edited' , 'now'));
$event['start'] = DateTimeFormat::utc(defaults($arr, 'start' , NULL_DATE)); $event['start'] = DateTimeFormat::utc(defaults($arr, 'start' , DBA::NULL_DATETIME));
$event['finish'] = DateTimeFormat::utc(defaults($arr, 'finish' , NULL_DATE)); $event['finish'] = DateTimeFormat::utc(defaults($arr, 'finish' , DBA::NULL_DATETIME));
if ($event['finish'] < NULL_DATE) { if ($event['finish'] < DBA::NULL_DATETIME) {
$event['finish'] = NULL_DATE; $event['finish'] = DBA::NULL_DATETIME;
} }
$private = intval(defaults($arr, 'private', 0)); $private = intval(defaults($arr, 'private', 0));

View file

@ -176,7 +176,7 @@ class GContact
if (!isset($gcontact['network']) && ($gcnt["network"] != Protocol::STATUSNET)) { if (!isset($gcontact['network']) && ($gcnt["network"] != Protocol::STATUSNET)) {
$gcontact['network'] = $gcnt["network"]; $gcontact['network'] = $gcnt["network"];
} }
if ($gcontact['updated'] <= NULL_DATE) { if ($gcontact['updated'] <= DBA::NULL_DATETIME) {
$gcontact['updated'] = $gcnt["updated"]; $gcontact['updated'] = $gcnt["updated"];
} }
if (!isset($gcontact['server_url']) && (normalise_link($gcnt["server_url"]) != normalise_link($gcnt["url"]))) { if (!isset($gcontact['server_url']) && (normalise_link($gcnt["server_url"]) != normalise_link($gcnt["url"]))) {
@ -457,7 +457,7 @@ class GContact
intval($uid), intval($uid),
intval($uid), intval($uid),
intval($uid), intval($uid),
DBA::escape(NULL_DATE), DBA::NULL_DATETIME,
$sql_network, $sql_network,
intval($start), intval($start),
intval($limit) intval($limit)
@ -486,7 +486,7 @@ class GContact
intval($uid), intval($uid),
intval($uid), intval($uid),
intval($uid), intval($uid),
DBA::escape(NULL_DATE), DBA::NULL_DATETIME,
$sql_network, $sql_network,
intval($start), intval($start),
intval($limit) intval($limit)

View file

@ -774,7 +774,7 @@ class Profile
$profile['marital']['with'] = $a->profile['with']; $profile['marital']['with'] = $a->profile['with'];
} }
if (strlen($a->profile['howlong']) && $a->profile['howlong'] >= NULL_DATE) { if (strlen($a->profile['howlong']) && $a->profile['howlong'] >= DBA::NULL_DATETIME) {
$profile['howlong'] = Temporal::getRelativeDate($a->profile['howlong'], L10n::t('for %1$d %2$s')); $profile['howlong'] = Temporal::getRelativeDate($a->profile['howlong'], L10n::t('for %1$d %2$s'));
} }

View file

@ -21,7 +21,7 @@ class PushSubscriber
public static function publishFeed($uid, $default_priority = PRIORITY_HIGH) public static function publishFeed($uid, $default_priority = PRIORITY_HIGH)
{ {
$condition = ['push' => 0, 'uid' => $uid]; $condition = ['push' => 0, 'uid' => $uid];
DBA::update('push_subscriber', ['push' => 1, 'next_try' => NULL_DATE], $condition); DBA::update('push_subscriber', ['push' => 1, 'next_try' => DBA::NULL_DATETIME], $condition);
self::requeue($default_priority); self::requeue($default_priority);
} }
@ -114,10 +114,10 @@ class PushSubscriber
$days = round((time() - strtotime($subscriber['renewed'])) / (60 * 60 * 24)); $days = round((time() - strtotime($subscriber['renewed'])) / (60 * 60 * 24));
if ($days > 60) { if ($days > 60) {
DBA::update('push_subscriber', ['push' => -1, 'next_try' => NULL_DATE], ['id' => $id]); DBA::update('push_subscriber', ['push' => -1, 'next_try' => DBA::NULL_DATETIME], ['id' => $id]);
logger('Delivery error: Subscription ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as ended.', LOGGER_DEBUG); logger('Delivery error: Subscription ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as ended.', LOGGER_DEBUG);
} else { } else {
DBA::update('push_subscriber', ['push' => 0, 'next_try' => NULL_DATE], ['id' => $id]); DBA::update('push_subscriber', ['push' => 0, 'next_try' => DBA::NULL_DATETIME], ['id' => $id]);
logger('Delivery error: Giving up ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' for now.', LOGGER_DEBUG); logger('Delivery error: Giving up ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' for now.', LOGGER_DEBUG);
} }
} else { } else {
@ -146,7 +146,7 @@ class PushSubscriber
} }
// set last_update to the 'created' date of the last item, and reset push=0 // set last_update to the 'created' date of the last item, and reset push=0
$fields = ['push' => 0, 'next_try' => NULL_DATE, 'last_update' => $last_update]; $fields = ['push' => 0, 'next_try' => DBA::NULL_DATETIME, 'last_update' => $last_update];
DBA::update('push_subscriber', $fields, ['id' => $id]); DBA::update('push_subscriber', $fields, ['id' => $id]);
logger('Subscriber ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as vital', LOGGER_DEBUG); logger('Subscriber ' . $subscriber['callback_url'] . ' for ' . $subscriber['nickname'] . ' is marked as vital', LOGGER_DEBUG);
} }

View file

@ -8,6 +8,7 @@ use Friendica\Content\ContactSelector;
use Friendica\Content\Nav; use Friendica\Content\Nav;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Widget; use Friendica\Content\Widget;
use Friendica\Core\ACL;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
@ -15,11 +16,10 @@ use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model; use Friendica\Model;
use Friendica\Module\Login;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Core\ACL;
use Friendica\Module\Login;
/** /**
* Manages and show Contacts and their content * Manages and show Contacts and their content
@ -522,9 +522,9 @@ class Contact extends BaseModule
$insecure = L10n::t('Private communications are not available for this contact.'); $insecure = L10n::t('Private communications are not available for this contact.');
$last_update = (($contact['last-update'] <= NULL_DATE) ? L10n::t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A')); $last_update = (($contact['last-update'] <= DBA::NULL_DATETIME) ? L10n::t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A'));
if ($contact['last-update'] > NULL_DATE) { if ($contact['last-update'] > DBA::NULL_DATETIME) {
$last_update .= ' ' . (($contact['last-update'] <= $contact['success_update']) ? L10n::t('(Update was successful)') : L10n::t('(Update was not successful)')); $last_update .= ' ' . (($contact['last-update'] <= $contact['success_update']) ? L10n::t('(Update was successful)') : L10n::t('(Update was not successful)'));
} }
$lblsuggest = (($contact['network'] === Protocol::DFRN) ? L10n::t('Suggest friends') : ''); $lblsuggest = (($contact['network'] === Protocol::DFRN) ? L10n::t('Suggest friends') : '');
@ -536,7 +536,7 @@ class Contact extends BaseModule
// tabs // tabs
$tab_str = self::getTabsHTML($a, $contact, 3); $tab_str = self::getTabsHTML($a, $contact, 3);
$lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < DateTimeFormat::utcNow()) ? L10n::t('Communications lost with this contact!') : ''); $lost_contact = (($contact['archive'] && $contact['term-date'] > DBA::NULL_DATETIME && $contact['term-date'] < DateTimeFormat::utcNow()) ? L10n::t('Communications lost with this contact!') : '');
$fetch_further_information = null; $fetch_further_information = null;
if ($contact['network'] == Protocol::FEED) { if ($contact['network'] == Protocol::FEED) {

View file

@ -771,7 +771,7 @@ class Post extends BaseObject
* Hmmm, code depending on the presence of a particular addon? * Hmmm, code depending on the presence of a particular addon?
* This should be better if done by a hook * This should be better if done by a hook
*/ */
if (in_array('qcomment', $a->addons)) { if (Addon::isEnabled('qcomment')) {
$qc = ((local_user()) ? PConfig::get(local_user(), 'qcomment', 'words') : null); $qc = ((local_user()) ? PConfig::get(local_user(), 'qcomment', 'words') : null);
$qcomment = (($qc) ? explode("\n", $qc) : null); $qcomment = (($qc) ? explode("\n", $qc) : null);
} }

View file

@ -113,7 +113,7 @@ class PortableContact
$connect_url = ''; $connect_url = '';
$name = ''; $name = '';
$network = ''; $network = '';
$updated = NULL_DATE; $updated = DBA::NULL_DATETIME;
$location = ''; $location = '';
$about = ''; $about = '';
$keywords = ''; $keywords = '';
@ -317,7 +317,7 @@ class PortableContact
$contact = ["url" => $profile]; $contact = ["url" => $profile];
if ($gcontacts[0]["created"] <= NULL_DATE) { if ($gcontacts[0]["created"] <= DBA::NULL_DATETIME) {
$contact['created'] = DateTimeFormat::utcNow(); $contact['created'] = DateTimeFormat::utcNow();
} }
@ -522,7 +522,7 @@ class PortableContact
// Maybe there aren't any entries. Then check if it is a valid feed // Maybe there aren't any entries. Then check if it is a valid feed
if ($last_updated == "") { if ($last_updated == "") {
if ($xpath->query('/atom:feed')->length > 0) { if ($xpath->query('/atom:feed')->length > 0) {
$last_updated = NULL_DATE; $last_updated = DBA::NULL_DATETIME;
} }
} }
@ -931,7 +931,7 @@ class PortableContact
$gserver = DBA::selectFirst('gserver', [], ['nurl' => normalise_link($server_url)]); $gserver = DBA::selectFirst('gserver', [], ['nurl' => normalise_link($server_url)]);
if (DBA::isResult($gserver)) { if (DBA::isResult($gserver)) {
if ($gserver["created"] <= NULL_DATE) { if ($gserver["created"] <= DBA::NULL_DATETIME) {
$fields = ['created' => DateTimeFormat::utcNow()]; $fields = ['created' => DateTimeFormat::utcNow()];
$condition = ['nurl' => normalise_link($server_url)]; $condition = ['nurl' => normalise_link($server_url)];
DBA::update('gserver', $fields, $condition); DBA::update('gserver', $fields, $condition);
@ -954,12 +954,12 @@ class PortableContact
// See discussion under https://forum.friendi.ca/display/0b6b25a8135aabc37a5a0f5684081633 // See discussion under https://forum.friendi.ca/display/0b6b25a8135aabc37a5a0f5684081633
// It can happen that a zero date is in the database, but storing it again is forbidden. // It can happen that a zero date is in the database, but storing it again is forbidden.
if ($last_contact < NULL_DATE) { if ($last_contact < DBA::NULL_DATETIME) {
$last_contact = NULL_DATE; $last_contact = DBA::NULL_DATETIME;
} }
if ($last_failure < NULL_DATE) { if ($last_failure < DBA::NULL_DATETIME) {
$last_failure = NULL_DATE; $last_failure = DBA::NULL_DATETIME;
} }
if (!$force && !self::updateNeeded($gserver["created"], "", $last_failure, $last_contact)) { if (!$force && !self::updateNeeded($gserver["created"], "", $last_failure, $last_contact)) {
@ -976,8 +976,8 @@ class PortableContact
$register_policy = -1; $register_policy = -1;
$registered_users = 0; $registered_users = 0;
$last_contact = NULL_DATE; $last_contact = DBA::NULL_DATETIME;
$last_failure = NULL_DATE; $last_failure = DBA::NULL_DATETIME;
} }
logger("Server ".$server_url." is outdated or unknown. Start discovery. Force: ".$force." Created: ".$gserver["created"]." Failure: ".$last_failure." Contact: ".$last_contact, LOGGER_DEBUG); logger("Server ".$server_url." is outdated or unknown. Start discovery. Force: ".$force." Created: ".$gserver["created"]." Failure: ".$last_failure." Contact: ".$last_contact, LOGGER_DEBUG);
@ -1794,7 +1794,7 @@ class PortableContact
$connect_url = ''; $connect_url = '';
$name = ''; $name = '';
$network = ''; $network = '';
$updated = NULL_DATE; $updated = DBA::NULL_DATETIME;
$location = ''; $location = '';
$about = ''; $about = '';
$keywords = ''; $keywords = '';

View file

@ -11,6 +11,7 @@ use DateTimeZone;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Database\DBA;
require_once 'boot.php'; require_once 'boot.php';
require_once 'include/text.php'; require_once 'include/text.php';
@ -290,7 +291,7 @@ class Temporal
$abs = strtotime($localtime); $abs = strtotime($localtime);
if (is_null($posted_date) || $posted_date <= NULL_DATE || $abs === false) { if (is_null($posted_date) || $posted_date <= DBA::NULL_DATETIME || $abs === false) {
return L10n::t('never'); return L10n::t('never');
} }

View file

@ -7,6 +7,7 @@ namespace Friendica\Worker;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
@ -45,7 +46,7 @@ class Cron
logger('cron: start'); logger('cron: start');
// Fork the cron jobs in separate parts to avoid problems when one of them is crashing // Fork the cron jobs in separate parts to avoid problems when one of them is crashing
Addon::forkHooks($a->queue['priority'], "cron"); Hook::fork($a->queue['priority'], "cron");
// run queue delivery process in the background // run queue delivery process in the background
Worker::add(PRIORITY_NEGLIGIBLE, "Queue"); Worker::add(PRIORITY_NEGLIGIBLE, "Queue");
@ -203,7 +204,7 @@ class Cron
foreach ($contacts as $contact) { foreach ($contacts as $contact) {
if ($manual_id) { if ($manual_id) {
$contact['last-update'] = NULL_DATE; $contact['last-update'] = DBA::NULL_DATETIME;
} }
// Friendica and OStatus are checked once a day // Friendica and OStatus are checked once a day

View file

@ -108,7 +108,7 @@ class CronJobs
private static function expireAndRemoveUsers() private static function expireAndRemoveUsers()
{ {
// expire any expired regular accounts. Don't expire forums. // expire any expired regular accounts. Don't expire forums.
$condition = ["NOT `account_expired` AND `account_expires_on` > ? AND `account_expires_on` < UTC_TIMESTAMP() AND `page-flags` = 0", NULL_DATE]; $condition = ["NOT `account_expired` AND `account_expires_on` > ? AND `account_expires_on` < UTC_TIMESTAMP() AND `page-flags` = 0", DBA::NULL_DATETIME];
DBA::update('user', ['account_expired' => true], $condition); DBA::update('user', ['account_expired' => true], $condition);
// Remove any freshly expired account // Remove any freshly expired account

View file

@ -7,8 +7,8 @@
namespace Friendica\Worker; namespace Friendica\Worker;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Item; use Friendica\Model\Item;
@ -17,13 +17,13 @@ require_once 'include/dba.php';
class Expire class Expire
{ {
public static function execute($param = '', $hook_name = '') public static function execute($param = '', $hook_function = '')
{ {
$a = BaseObject::getApp(); $a = BaseObject::getApp();
require_once 'include/items.php'; require_once 'include/items.php';
Addon::loadHooks(); Hook::loadHooks();
if ($param == 'delete') { if ($param == 'delete') {
logger('Delete expired items', LOGGER_DEBUG); logger('Delete expired items', LOGGER_DEBUG);
@ -62,11 +62,11 @@ class Expire
logger('Expire items for user '.$user['uid'].' ('.$user['username'].') - done ', LOGGER_DEBUG); logger('Expire items for user '.$user['uid'].' ('.$user['username'].') - done ', LOGGER_DEBUG);
} }
return; return;
} elseif (!empty($hook_name) && ($param == 'hook') && is_array($a->hooks) && array_key_exists("expire", $a->hooks)) { } elseif ($param == 'hook' && !empty($hook_function)) {
foreach ($a->hooks["expire"] as $hook) { foreach (Hook::getByName('expire') as $hook) {
if ($hook[1] == $hook_name) { if ($hook[1] == $hook_function) {
logger("Calling expire hook '" . $hook[1] . "'", LOGGER_DEBUG); logger("Calling expire hook '" . $hook[1] . "'", LOGGER_DEBUG);
Addon::callSingleHook($a, $hook_name, $hook, $data); Hook::callSingle($a, 'expire', $hook, $data);
} }
} }
return; return;
@ -86,14 +86,11 @@ class Expire
DBA::close($r); DBA::close($r);
logger('expire: calling hooks'); logger('expire: calling hooks');
foreach (Hook::getByName('expire') as $hook) {
if (is_array($a->hooks) && array_key_exists('expire', $a->hooks)) {
foreach ($a->hooks['expire'] as $hook) {
logger("Calling expire hook for '" . $hook[1] . "'", LOGGER_DEBUG); logger("Calling expire hook for '" . $hook[1] . "'", LOGGER_DEBUG);
Worker::add(['priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true], Worker::add(['priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true],
'Expire', 'hook', $hook[1]); 'Expire', 'hook', $hook[1]);
} }
}
logger('expire: end'); logger('expire: end');

View file

@ -5,7 +5,7 @@
namespace Friendica\Worker; namespace Friendica\Worker;
use Friendica\Core\Addon; use Friendica\Core\Hook;
Class ForkHook Class ForkHook
{ {
@ -13,6 +13,6 @@ Class ForkHook
{ {
$a = \Friendica\BaseObject::getApp(); $a = \Friendica\BaseObject::getApp();
Addon::callSingleHook($a, $name, $hook, $data); Hook::callSingle($a, $name, $hook, $data);
} }
} }

View file

@ -7,10 +7,12 @@ namespace Friendica\Worker;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\Group; use Friendica\Model\Group;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\PushSubscriber; use Friendica\Model\PushSubscriber;
@ -20,7 +22,6 @@ use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon; use Friendica\Protocol\Salmon;
use Friendica\Model\Conversation;
require_once 'include/dba.php'; require_once 'include/dba.php';
require_once 'include/items.php'; require_once 'include/items.php';
@ -501,7 +502,7 @@ class Notifier
logger('notifier: calling hooks for ' . $cmd . ' ' . $item_id, LOGGER_DEBUG); logger('notifier: calling hooks for ' . $cmd . ' ' . $item_id, LOGGER_DEBUG);
if ($normal_mode) { if ($normal_mode) {
Addon::forkHooks($a->queue['priority'], 'notifier_normal', $target_item); Hook::fork($a->queue['priority'], 'notifier_normal', $target_item);
} }
Addon::callHooks('notifier_end',$target_item); Addon::callHooks('notifier_end',$target_item);

View file

@ -12,8 +12,8 @@ use Friendica\Core\Protocol;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Protocol\Email;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Email;
use Friendica\Protocol\PortableContact; use Friendica\Protocol\PortableContact;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network; use Friendica\Util\Network;
@ -121,7 +121,7 @@ class OnePoll
$hub_update = false; $hub_update = false;
} }
$last_update = (($contact['last-update'] <= NULL_DATE) $last_update = (($contact['last-update'] <= DBA::NULL_DATETIME)
? DateTimeFormat::utc('now - 7 days', DateTimeFormat::ATOM) ? DateTimeFormat::utc('now - 7 days', DateTimeFormat::ATOM)
: DateTimeFormat::utc($contact['last-update'], DateTimeFormat::ATOM) : DateTimeFormat::utc($contact['last-update'], DateTimeFormat::ATOM)
); );
@ -252,7 +252,7 @@ class OnePoll
self::updateContact($contact, $fields); self::updateContact($contact, $fields);
Contact::markForArchival($contact); Contact::markForArchival($contact);
} elseif ($contact['term-date'] > NULL_DATE) { } elseif ($contact['term-date'] > DBA::NULL_DATETIME) {
logger("$url back from the dead - removing mark for death"); logger("$url back from the dead - removing mark for death");
Contact::unmarkForArchival($contact); Contact::unmarkForArchival($contact);
} }

View file

@ -26,7 +26,7 @@ trait VFSTrait
$this->setConfigFile('config.ini.php'); $this->setConfigFile('config.ini.php');
$this->setConfigFile('settings.ini.php'); $this->setConfigFile('settings.ini.php');
$this->setConfigFile('local.ini.php'); $this->setConfigFile('local.ini.php');
$this->setConfigFile('dbstructure.json'); $this->setConfigFile('dbstructure.php');
} }
protected function setConfigFile($filename) protected function setConfigFile($filename)

View file

@ -20,7 +20,7 @@ require_once 'include/dba.php';
* This function is responsible for doing post update changes to the data * This function is responsible for doing post update changes to the data
* (not the structure) in the database. * (not the structure) in the database.
* *
* Database structure changes are done in src/Database/DBStructure.php * Database structure changes are done in config/dbstructure.php
* *
* If there is a need for a post process to a structure change, update this file * If there is a need for a post process to a structure change, update this file
* by adding a new function at the end with the number of the new DB_UPDATE_VERSION. * by adding a new function at the end with the number of the new DB_UPDATE_VERSION.
@ -31,8 +31,8 @@ require_once 'include/dba.php';
* You are currently on version 4711 and you are preparing changes that demand an update script. * You are currently on version 4711 and you are preparing changes that demand an update script.
* *
* 1. Create a function "update_4712()" here in the update.php * 1. Create a function "update_4712()" here in the update.php
* 2. Apply the needed structural changes in src/Database/DBStructure.php * 2. Apply the needed structural changes in config/dbStructure.php
* 3. Set DB_UPDATE_VERSION in boot.php to 4712. * 3. Set DB_UPDATE_VERSION in config/dbstructure.php to 4712.
* *
* If you need to run a script before the database update, name the function "pre_update_4712()" * If you need to run a script before the database update, name the function "pre_update_4712()"
*/ */