diff --git a/CHANGELOG b/CHANGELOG index a3a974eb62..a37ed76f59 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,64 @@ +Version 3.5.2 (2017-06-06) + Friendica Core: + Updates to the translations (DE, EN-GB, EN-US, ES, IT, PT-BR, RU) [translation teams] + Updates to the documentation [annando, beardyunixer, rabuzarus, tobiasd] + Updated the nginx example configuration [beardyunixer] + Code revision and refactoring [annando, hypolite, Quix0r, rebeka-catalina] + Background process is now done by the new worker process [annando] + Added support of Composer for dependencies [Hypolite] + Added support of Web app manifests [Rudloff] + Added basic robot.txt functionality if none exists [Shnoulle] + Added server blocklist [Hypolite, tobiasd] + Removed mcrypt dependency [annando] + Removed unused libraries [annando] + Removed Embedly integration [Hypolite] + Fixed a bug in the language detection for EN [Hypolite] + Fixed a bug in the probing mechanism on old PHP version [annando] + Improved API [annando, gerhard6380] + Improved Diaspora federation [annando] + Improved Mastodon federation [annando, Hypolite] + Improved import from OStatus threads [annando] + Improved the themes (frio, quattro) [fabrixxm, Hypolite, rabuzarus, Rudloff, strk, tobiasd] + Improved maintenance mode [annando] + Improved gcontact handling [annando] + Improved desktop notifications [rabuzarus] + Improved keyboard shortcuts for navigation [Rudloff] + Improved the installer [annando] + Improved openid handling [strk] + Improved php7 support [annando] + Improved display of notifications [annando] + Improved logging mechanism [beardyunixer] + Improved the worker [annando] + Behaviour clarification of the group filter / new tab [annando] + Old options for the pager and share element were removed [annando] + Support of PDO was added [annando] + Improved error logging for issues with the database [annando] + Improved compatibility to MySQL version 5.7+ [annando] + + Friendica Addons: + Updates to the translation (RU) [pztrm] + (core) Fix blocking issue for Communityhome [annando] + Pledgie addon was updated to remove cert problems [tobiasd] + Securemail now uses openpgp-php and phpseclib [fabrixxm] + Superblock Configuration [tobiasd] + Twitter Connector updated to use with new deletion method [annando] + + Closed Issues: + 1626, 1720, 2432, 2792, 2833, 2364, 2448, 2496, 2690, 2752, 2775, + 2803, 2956, 2957, 2961, 2971, 2995, 2999, 3011, 3053, 3107, 3114, + 3134, 3138, 3142, 3157, 3172, 3189, 3194, 3195, 3198, 3206, 3215, + 3217, 3220, 3237, 3242, 3255, 3256, 3260, 3268, 3273, 3274, 3285, + 3288, 3292, 3293, 3300, 3314, 3316, 3317, 3322, 3325, 3327, 3328, + 3331, 3334, 3336, 3346, 3347, 3358, 3359, 3383, 3387, 3401, 3406, + 3428, 3440, 3435, 3436, 3452 + Version 3.5.1 (2017-03-12) Friendica Core: Updates to the translations (BG, CA, CS, DE, EO, ES, FR, IS, IT, NL, PL, PT-BR, RU, SV) [translation teams] - Fix for a potential XSS vector [heluecht, thanks to Vít Šesták 'v6ak' for reporting the problem] + Fix for a potential XSS vector [annando, thanks to Vít Šesták 'v6ak' for reporting the problem] Fix for ghost request notifications on single user instances [Hypolite] Fix user language selection [tobiasd] - Fix a problem with communication to Diaspora with set posting locations [heluecht] + Fix a problem with communication to Diaspora with set posting locations [annando] Fix schema handling of direct links to a original posting [Rabuzarus] Fix a bug in notification handling [Rabuzarus] Adjustments for the Vagrant VM settings [silke, eelcomaljaars] @@ -12,22 +66,22 @@ Version 3.5.1 (2017-03-12) Improvements to the API and Friendica specific extensions [gerhard6380] Improvements to the Browser Notification functionality [Hypolite] Improvements to the themes [Hypolite, rabuzarus, rebeka-catalina, tobiasd] - Improvements to the database handling [heluecht] + Improvements to the database handling [annando] Improvements to the admin panel [tobiasd, Hypolite] - Improvements to the update process [heluecht] - Improvements to the handling of worker processes [heluecht] - Improvements to the performance [heluecht, Hypolite] + Improvements to the update process [annando] + Improvements to the handling of worker processes [annando] + Improvements to the performance [annando, Hypolite] Improvements to the documentation [Hypolite, tobiasd, rabuzarus, beardyunixer, eelcomaljaars] Improvements to the BBCode / Markdown conversation [Hypolite] - Improvements to the OStatus protocol implementation [heluecht] + Improvements to the OStatus protocol implementation [annando] Improvements to the installation wizzard [tobiasd] - Improvements to the Diaspora connectivity [heluecht, Hypolite] + Improvements to the Diaspora connectivity [annando, Hypolite] Work on PHP7 compatibility [ddorian1] Code cleanup [Hypolite, Quix0r] - Initial federation with Mastodon [heluecht] - The worker process can now also be started from the frontend [heluecht] - Deletion of postings is now done in the background [heluecht] - Extension of the DFRN transmitted information fields [heluecht] + Initial federation with Mastodon [annando] + The worker process can now also be started from the frontend [annando] + Deletion of postings is now done in the background [annando] + Extension of the DFRN transmitted information fields [annando] Translations of the core are now in /view/lang [Hypolite, tobiasd] Update of the fullCalendar library to 3.0.1 and adjusting the themes [rabuzarus] ping now works with JSON as well [Hypolite] @@ -46,16 +100,16 @@ Version 3.5.1 (2017-03-12) Updates to the translations (DE, ES, FR, IT, PT-BR) [translation teams] Improvements to the IFTTT addon [Hypolite] Improvements to the language filter addon [strk] - Improvements to the pump.io bridge [heluecht] - Improvements to the jappixmini addon [heluecht] - Improvements to the gpluspost addon [heluecht] - Improvements to the performance of the Twitter bridge when using workers [heluecht] - Diaspora Export addon is now working again [heluecht] + Improvements to the pump.io bridge [annando] + Improvements to the jappixmini addon [annando] + Improvements to the gpluspost addon [annando] + Improvements to the performance of the Twitter bridge when using workers [annando] + Diaspora Export addon is now working again [annando] Pledgie badge now uses https protocol for embedding [tobiasd] - Better posting loop prevention for the Google+/Twitter/GS connectors [heluecht] + Better posting loop prevention for the Google+/Twitter/GS connectors [annando] One can now configure the message for wppost bridged blog postings [tobiasd] - On some pages the result of the Rendertime is not shown anymore [heluecht] - Twitter-bridge now supports quotes and long posts when importing tweets [heluecht] + On some pages the result of the Rendertime is not shown anymore [annando] + Twitter-bridge now supports quotes and long posts when importing tweets [annando] Closed Issues 1019, 1163, 1612, 1613, 2103, 2177, 2252, 2260, 2403, 2991, 2614, @@ -67,48 +121,48 @@ Version 3.5.1 (2017-03-12) Version 3.5 (2016-09-13) Friendica Core: - NEW Optional local directory with possible federated contacts [heluecht] + NEW Optional local directory with possible federated contacts [annando] NEW Autocompletion for @-mentions and BBCode tags [rabuzarus] NEW Added a composer derived autoloader which allows composer autoloaders in addons/libraries [fabrixxm] - NEW theme: frio [rabuzarus, heluecht, fabrixxm] + NEW theme: frio [rabuzarus, annando, fabrixxm] Enhance .htaccess file (nerdoc, dissolve) Updates to the translations (DE, ES, IS, IT, RU) [translation teams] - Updates to the documentation [tobiasd, heluecht, mexcon, silke, rabuzarus, fabrixxm, Olivier Mehani, gerhard6380, ben utzer] - Extended the BBCode by [abstract] tag used for bridged postings to networks with limited character length [heluecht] - Code cleanup [heluecht, QuixOr] - Improvements to the API and Friendica specific extensions [heluecht, fabrixxm, gerhard6380] + Updates to the documentation [tobiasd, annando, mexcon, silke, rabuzarus, fabrixxm, Olivier Mehani, gerhard6380, ben utzer] + Extended the BBCode by [abstract] tag used for bridged postings to networks with limited character length [annando] + Code cleanup [annando, QuixOr] + Improvements to the API and Friendica specific extensions [annando, fabrixxm, gerhard6380] Improvements to the RSS/Atom feed import [mexcon] - Improvements to the communication with federated networks (Diaspora, Hubzilla, OStatus) [heluecht] - Improvements on the themes (quattro, vier, frost) [rabuzarus, fabrixxm, stieben, heluecht, Quix0r, tobiasd] + Improvements to the communication with federated networks (Diaspora, Hubzilla, OStatus) [annando] + Improvements on the themes (quattro, vier, frost) [rabuzarus, fabrixxm, stieben, annando, Quix0r, tobiasd] Improvements to the ACL dialog [fabrixxm, rabuzarus] - Improvements to the database structure and optimization of queries [heluecht] - Improvements to the UI (contacts, hotkeys, remember me, ARIA, code hightlighting) [rabuzarus, heluecht, tobiasd] - Improvements to the background process (poller, worker) [heluecht] - Improvements to the admin panel [tobiasd, heluecht, fabrixxm] - Improvements to the performance [heluecht] + Improvements to the database structure and optimization of queries [annando] + Improvements to the UI (contacts, hotkeys, remember me, ARIA, code hightlighting) [rabuzarus, annando, tobiasd] + Improvements to the background process (poller, worker) [annando] + Improvements to the admin panel [tobiasd, annando, fabrixxm] + Improvements to the performance [annando] Improvements to the installation wizzard (language selection, RINO version, check required PHP modules, default theme is now vier) [tobiasd] - Improvements to the relocation of nodes and accounts [heluecht] - Improvements to the DDoS detection [heluecht] - Improvements to the calendar/events module [heluecht, rabuzarus] + Improvements to the relocation of nodes and accounts [annando] + Improvements to the DDoS detection [annando] + Improvements to the calendar/events module [annando, rabuzarus] Improvements to OpenID login [strk] Improvements to the ShaShape font [andi] - Reworked the implementation of the DFRN, Diaspora protocols [heluecht] - Reworked the notifications code [fabrixxm, rabuzarus, heluecht] + Reworked the implementation of the DFRN, Diaspora protocols [annando] + Reworked the notifications code [fabrixxm, rabuzarus, annando] Reworked the p/config code [fabrixxm, rabuzarus] - Reworked XML generation [heluecht] - Removed now unused simplepie from library [heluecht] + Reworked XML generation [annando] + Removed now unused simplepie from library [annando] Friendica Addons Updated to the translations (DE, ES, IS, NL, PT BR), [translation teams] Piwik [tobiasd] - Twitter Connector [heluecht] - Pumpio Connector [heluecht] - Rendertime [heluecht] - wppost [heluecht] + Twitter Connector [annando] + Pumpio Connector [annando] + Rendertime [annando] + wppost [annando] showmore [rabuzarus] - fromgplus [heluecht] - app.net Connector [heluecht] - GNU Social Connector [heluecht] + fromgplus [annando] + app.net Connector [annando] + GNU Social Connector [annando] LDAP [Olivier Mehani] smileybutton [rabuzarus] retriver [mexon] diff --git a/VERSION b/VERSION index 445f311196..3fec5bc901 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.2-rc +3.5.3dev diff --git a/boot.php b/boot.php index 48381f5435..5f83cb3e40 100644 --- a/boot.php +++ b/boot.php @@ -38,9 +38,9 @@ require_once 'include/dbstructure.php'; define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_CODENAME', 'Asparagus'); -define ( 'FRIENDICA_VERSION', '3.5.2-rc' ); +define ( 'FRIENDICA_VERSION', '3.5.3dev' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); -define ( 'DB_UPDATE_VERSION', 1225 ); +define ( 'DB_UPDATE_VERSION', 1227 ); /** * @brief Constant with a HTML line break. @@ -457,6 +457,13 @@ if (!defined("SIGTERM")) { define("SIGTERM", 15); } +/** + * Depending on the PHP version this constant does exist - or not. + * See here: http://php.net/manual/en/curl.constants.php#117928 + */ +if (!defined('CURLE_OPERATION_TIMEDOUT')) { + define('CURLE_OPERATION_TIMEDOUT', CURLE_OPERATION_TIMEOUTED); +} /** * * Reverse the effect of magic_quotes_gpc if it is enabled. @@ -1375,7 +1382,7 @@ function get_server() { $server = get_config("system", "directory"); if ($server == "") { - $server = "http://dir.friendi.ca"; + $server = "http://dir.friendica.social"; } return($server); diff --git a/database.sql b/database.sql index 73547b3058..4a5946ef38 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ --- Friendica 3.5.2-dev (Asparagus) --- DB_UPDATE_VERSION 1221 +-- Friendica 3.5.2-rc (Asparagus) +-- DB_UPDATE_VERSION 1227 -- ------------------------------------------ @@ -193,7 +193,7 @@ CREATE TABLE IF NOT EXISTS `contact` ( -- CREATE TABLE IF NOT EXISTS `conv` ( `id` int(10) unsigned NOT NULL auto_increment, - `guid` varchar(64) NOT NULL DEFAULT '', + `guid` varchar(255) NOT NULL DEFAULT '', `recips` text, `uid` int(11) NOT NULL DEFAULT 0, `creator` varchar(255) NOT NULL DEFAULT '', @@ -270,7 +270,7 @@ CREATE TABLE IF NOT EXISTS `fcontact` ( `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), INDEX `addr` (`addr`(32)), - INDEX `url` (`url`) + UNIQUE INDEX `url` (`url`(190)) ) DEFAULT COLLATE utf8mb4_general_ci; -- @@ -355,7 +355,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` ( `generation` tinyint(3) NOT NULL DEFAULT 0, `server_url` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY(`id`), - INDEX `nurl` (`nurl`(64)), + UNIQUE INDEX `nurl` (`nurl`(190)), INDEX `name` (`name`(64)), INDEX `nick` (`nick`(32)), INDEX `addr` (`addr`(64)), @@ -425,7 +425,7 @@ CREATE TABLE IF NOT EXISTS `gserver` ( `last_contact` datetime DEFAULT '0001-01-01 00:00:00', `last_failure` datetime DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), - INDEX `nurl` (`nurl`(32)) + UNIQUE INDEX `nurl` (`nurl`(190)) ) DEFAULT COLLATE utf8mb4_general_ci; -- @@ -544,6 +544,7 @@ CREATE TABLE IF NOT EXISTS `item` ( INDEX `uid_parenturi` (`uid`,`parent-uri`(190)), INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`), INDEX `authorid_created` (`author-id`,`created`), + INDEX `ownerid` (`owner-id`), INDEX `uid_uri` (`uid`,`uri`(190)), INDEX `resource-id` (`resource-id`), INDEX `contactid_allowcid_allowpid_denycid_denygid` (`contact-id`,`allow_cid`(10),`allow_gid`(10),`deny_cid`(10),`deny_gid`(10)), @@ -589,7 +590,7 @@ CREATE TABLE IF NOT EXISTS `locks` ( CREATE TABLE IF NOT EXISTS `mail` ( `id` int(10) unsigned NOT NULL auto_increment, `uid` int(10) unsigned NOT NULL DEFAULT 0, - `guid` varchar(64) NOT NULL DEFAULT '', + `guid` varchar(255) NOT NULL DEFAULT '', `from-name` varchar(255) NOT NULL DEFAULT '', `from-photo` varchar(255) NOT NULL DEFAULT '', `from-url` varchar(255) NOT NULL DEFAULT '', @@ -608,7 +609,8 @@ CREATE TABLE IF NOT EXISTS `mail` ( INDEX `uid_seen` (`uid`,`seen`), INDEX `convid` (`convid`), INDEX `uri` (`uri`(64)), - INDEX `parent-uri` (`parent-uri`(64)) + INDEX `parent-uri` (`parent-uri`(64)), + INDEX `contactid` (`contact-id`) ) DEFAULT COLLATE utf8mb4_general_ci; -- @@ -746,6 +748,7 @@ CREATE TABLE IF NOT EXISTS `photo` ( `deny_cid` mediumtext, `deny_gid` mediumtext, PRIMARY KEY(`id`), + INDEX `contactid` (`contact-id`), INDEX `uid_contactid` (`uid`,`contact-id`), INDEX `uid_profile` (`uid`,`profile`), INDEX `uid_album_scale_created` (`uid`,`album`(32),`scale`,`created`), @@ -1019,6 +1022,9 @@ CREATE TABLE IF NOT EXISTS `thread` ( INDEX `uid_network_created` (`uid`,`network`,`created`), INDEX `uid_contactid_commented` (`uid`,`contact-id`,`commented`), INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`), + INDEX `contactid` (`contact-id`), + INDEX `ownerid` (`owner-id`), + INDEX `authorid` (`author-id`), INDEX `uid_created` (`uid`,`created`), INDEX `uid_commented` (`uid`,`commented`), INDEX `uid_wall_created` (`uid`,`wall`,`created`) @@ -1108,6 +1114,8 @@ CREATE TABLE IF NOT EXISTS `workerqueue` ( `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `pid` int(11) NOT NULL DEFAULT 0, `executed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', - PRIMARY KEY(`id`) + PRIMARY KEY(`id`), + INDEX `pid` (`pid`), + INDEX `priority_created` (`priority`,`created`) ) DEFAULT COLLATE utf8mb4_general_ci; diff --git a/doc/htconfig.md b/doc/htconfig.md index b424b5af68..7887184d88 100644 --- a/doc/htconfig.md +++ b/doc/htconfig.md @@ -14,7 +14,7 @@ Especially don't do that with undocumented values. The header of the section describes the category, the value is the parameter. Example: To set the directory value please add this line to your .htconfig.php: - $a->config['system']['directory'] = 'http://dir.friendi.ca'; + $a->config['system']['directory'] = 'http://dir.friendica.social'; ## jabber ## * **debug** (Boolean) - Enable debug level for the jabber account synchronisation. @@ -39,7 +39,7 @@ Example: To set the directory value please add this line to your .htconfig.php: * **default_service_class** - * **delivery_batch_count** - Number of deliveries per process. Default value is 1. (Disabled when using the worker) * **diaspora_test** (Boolean) - For development only. Disables the message transfer. -* **directory** - The path to global directory. If not set then "http://dir.friendi.ca" is used. +* **directory** - The path to global directory. If not set then "http://dir.friendica.social" is used. * **disable_email_validation** (Boolean) - Disables the check if a mail address is in a valid format and can be resolved via DNS. * **disable_url_validation** (Boolean) - Disables the DNS lookup of an URL. * **dlogfile - location of the developer log file diff --git a/include/NotificationsManager.php b/include/NotificationsManager.php index 7183393801..ad0ede6dbe 100644 --- a/include/NotificationsManager.php +++ b/include/NotificationsManager.php @@ -4,10 +4,12 @@ * @brief Methods for read and write notifications from/to database * or for formatting notifications */ + require_once 'include/html2plain.php'; require_once 'include/probe.php'; require_once 'include/datetime.php'; require_once 'include/bbcode.php'; +require_once 'include/Contact.php'; /** * @brief Methods for read and write notifications from/to database @@ -720,10 +722,12 @@ class NotificationsManager { $sql_extra = " AND `ignore` = 0 "; /// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact - $r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`, + $r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, + `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, + `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`, `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`, `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`, - `gcontact`.`network` AS `gnetwork` + `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr` FROM `intro` LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id` LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl` @@ -786,11 +790,7 @@ class NotificationsManager { // Normal connection requests } else { - // Probe the contact url to get missing data - $ret = probe_url($it["url"]); - - if ($it['gnetwork'] == "") - $it['gnetwork'] = $ret["network"]; + $it = $this->getMissingIntroData($it); // Don't show these data until you are connected. Diaspora is doing the same. if($it['gnetwork'] === NETWORK_DIASPORA) { @@ -815,7 +815,7 @@ class NotificationsManager { 'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), 'url' => $it['url'], 'zrl' => zrl($it['url']), - 'addr' => $ret['addr'], + 'addr' => $it['gaddr'], 'network' => $it['gnetwork'], 'knowyou' => $it['knowyou'], 'note' => $it['note'], @@ -827,4 +827,38 @@ class NotificationsManager { return $arr; } + + /** + * @brief Check for missing contact data and try to fetch the data from + * from other sources + * + * @param array $arr The input array with the intro data + * + * @return array The array with the intro data + */ + private function getMissingIntroData($arr) { + // If the network and the addr isn't available from the gcontact + // table entry, take the one of the contact table entry + if ($arr['gnetwork'] == "") { + $arr['gnetwork'] = $arr['network']; + } + if ($arr['gaddr'] == "") { + $arr['gaddr'] = $arr['addr']; + } + + // If the network and addr is still not available + // get the missing data data from other sources + if ($arr['gnetwork'] == "" || $arr['gaddr'] == "") { + $ret = get_contact_details_by_url($arr['url']); + + if ($arr['gnetwork'] == "" && $ret['network'] != "") { + $arr['gnetwork'] = $ret['network']; + } + if ($arr['gaddr'] == "" && $ret['addr'] != "") { + $arr['gaddr'] = $ret['addr']; + } + } + + return $arr; + } } diff --git a/include/api.php b/include/api.php index caf316d76a..5d962ecd03 100644 --- a/include/api.php +++ b/include/api.php @@ -2289,6 +2289,11 @@ $called_api = null; $statushtml = "

" . bbcode($item['title']) . "

\n" . $statushtml; } + // feeds without body should contain the link + if (($item['network'] == NETWORK_FEED) && (strlen($item['body']) == 0)) { + $statushtml .= bbcode($item['plink']); + } + $entities = api_get_entitities($statustext, $body); return array( diff --git a/include/dba_pdo.php b/include/dba_pdo.php index 4549d7a0ce..63f35739a3 100644 --- a/include/dba_pdo.php +++ b/include/dba_pdo.php @@ -49,12 +49,14 @@ class dba { function __construct($server,$user,$pass,$db,$install = false) { $a = get_app(); - # work around, to store the database - configuration in DDDBL - $objDataObjectPool = new DataObjectPool('Database-Definition'); - $objDataObjectPool->add('DEFAULT', array('CONNECTION' => "mysql:host=$server;dbname=$db", - 'USER' => $user, - 'PASS' => $pass, - 'DEFAULT' => true)); + // work around, to store the database - configuration in DDDBL + $objDataObjectPool = new DataObjectPool('Database-Definition'); + $objDataObjectPool->add('DEFAULT', array( + 'CONNECTION' => "mysql:host=$server;dbname=$db", + 'USER' => $user, + 'PASS' => $pass, + 'DEFAULT' => true + )); $stamp1 = microtime(true); @@ -63,35 +65,34 @@ class dba { $pass = trim($pass); $db = trim($db); - if (!(strlen($server) && strlen($user))){ + if (!(strlen($server) && strlen($user))) { $this->connected = false; $this->db = null; return; } - if ($install) { - if (strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) { - if (! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) { - $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server); - $this->connected = false; - $this->db = null; - return; - } + if ($install && strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) { + if (! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) { + $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server); + $this->connected = false; + $this->db = null; + return; } } - # etablish connection to database and store PDO object - DDDBL\connect(); - $this->db = DDDBL\getDB(); + // Establish connection to database and store PDO object + DDDBL\connect(); + $this->db = DDDBL\getDB(); - if (DDDBL\isConnected()) { - $this->connected = true; - } + if (DDDBL\isConnected()) { + $this->connected = true; + } if (! $this->connected) { $this->db = null; - if (! $install) + if (! $install) { system_unavailable(); + } } $a->save_timestamp($stamp1, "network"); @@ -104,44 +105,49 @@ class dba { public function q($sql, $onlyquery = false) { $a = get_app(); - $strHandler = (true === $onlyquery) ? 'PDOStatement' : 'MULTI'; + $strHandler = (true === $onlyquery) ? 'PDOStatement' : 'MULTI'; - $strQueryAlias = md5($sql); - $strSQLType = strtoupper(strstr($sql, ' ', true)); + $strQueryAlias = md5($sql); + $strSQLType = strtoupper(strstr($sql, ' ', true)); - $objPreparedQueryPool = new DataObjectPool('Query-Definition'); + $objPreparedQueryPool = new DataObjectPool('Query-Definition'); - # check if query do not exists till now, if so create its definition - if (!$objPreparedQueryPool->exists($strQueryAlias)) - $objPreparedQueryPool->add($strQueryAlias, array('QUERY' => $sql, - 'HANDLER' => $strHandler)); + // check if query do not exists till now, if so create its definition + if (!$objPreparedQueryPool->exists($strQueryAlias)) { + $objPreparedQueryPool->add($strQueryAlias, array( + 'QUERY' => $sql, + 'HANDLER' => $strHandler + )); + } - if ((! $this->db) || (! $this->connected)) + if ((! $this->db) || (! $this->connected)) { return false; + } $this->error = ''; $stamp1 = microtime(true); - try { - $r = DDDBL\get($strQueryAlias); + try { + $r = DDDBL\get($strQueryAlias); - # bad workaround to emulate the bizzare behavior of mysql_query - if (in_array($strSQLType, array('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'SET'))) - $result = true; - $intErrorCode = false; - - } catch (Exception $objException) { - $result = false; - $intErrorCode = $objPreparedQueryPool->get($strQueryAlias)->get('PDOStatement')->errorCode(); - } + // bad workaround to emulate the bizzare behavior of mysql_query + if (in_array($strSQLType, array('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'SET'))) { + $result = true; + } + $intErrorCode = false; + } catch (Exception $objException) { + $result = false; + $intErrorCode = $objPreparedQueryPool->get($strQueryAlias)->get('PDOStatement')->errorCode(); + } $stamp2 = microtime(true); $duration = (float)($stamp2-$stamp1); $a->save_timestamp($stamp1, "database"); - if (x($a->config,'system') && x($a->config['system'],'db_log')) { + /// @TODO really check $a->config for 'system'? it is very generic and should be there + if (x($a->config, 'system') && x($a->config['system'], 'db_log')) { if (($duration > $a->config["system"]["db_loglimit"])) { $duration = round($duration, 3); $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); @@ -152,24 +158,24 @@ class dba { } } - if ($intErrorCode) - $this->error = $intErrorCode; + if ($intErrorCode) { + $this->error = $intErrorCode; + } if (strlen($this->error)) { logger('dba: ' . $this->error); } if ($this->debug) { - $mesg = ''; - if ($result === false) + if ($result === false) { $mesg = 'false'; - elseif ($result === true) + } elseif ($result === true) { $mesg = 'true'; - else { - # this needs fixing, but is a bug itself - #$mesg = mysql_num_rows($result) . ' results' . EOL; + } else { + /// @TODO this needs fixing, but is a bug itself + // $mesg = mysql_num_rows($result) . ' results' . EOL; } $str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg @@ -179,46 +185,49 @@ class dba { logger('dba: ' . $str ); } - /** + /* * If dbfail.out exists, we will write any failed calls directly to it, * regardless of any logging that may or may nor be in effect. * These usually indicate SQL syntax errors that need to be resolved. */ - if (isset($result) AND ($result === false)) { logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error); - if (file_exists('dbfail.out')) + if (file_exists('dbfail.out')) { file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND); + } } - if (isset($result) AND (($result === true) || ($result === false))) + if (isset($result) AND (($result === true) || ($result === false))) { return $result; + } if ($onlyquery) { $this->result = $r; # this will store an PDOStatement Object in result - $this->result->execute(); # execute the Statement, to get its result + $this->result->execute(); # execute the Statement, to get its result return true; } //$a->save_timestamp($stamp1, "database"); - if ($this->debug) + if ($this->debug) { logger('dba: ' . printable(print_r($r, true))); - return($r); + } + + return $r; } public function qfetch() { + if (false === $this->result) { + return false; + } - if (false === $this->result) - return false; - - return $this->result->fetch(); - + return $this->result->fetch(); } public function qclose() { - if ($this->result) - return $this->result->closeCursor(); + if ($this->result) { + return $this->result->closeCursor(); + } } public function dbg($dbg) { @@ -227,17 +236,20 @@ class dba { public function escape($str) { if ($this->db && $this->connected) { - $strQuoted = $this->db->quote($str); - # this workaround is needed, because quote creates "'" and the beginning and the end - # of the string, which is correct. but until now the queries set this delimiter manually, - # so we must remove them from here and wait until everything uses prepared statements - return mb_substr($strQuoted, 1, mb_strlen($strQuoted) - 2); + $strQuoted = $this->db->quote($str); + /* + * this workaround is needed, because quote creates "'" and the beginning and the end + * of the string, which is correct. but until now the queries set this delimiter manually, + * so we must remove them from here and wait until everything uses prepared statements + */ + return mb_substr($strQuoted, 1, mb_strlen($strQuoted) - 2); } } - function __destruct() { - if ($this->db) - DDDBL\disconnect(); + public function __destruct() { + if ($this->db) { + DDDBL\disconnect(); + } } }} @@ -267,14 +279,13 @@ function dbesc($str) { return(str_replace("'","\\'",$str)); }} - - -// Function: q($sql,$args); -// Description: execute SQL query with printf style args. -// Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d", -// 'user', 1); - if (! function_exists('q')) { +/** + * Function: q($sql,$args); + * Description: execute SQL query with printf style args. + * Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d", + * 'user', 1); + */ function q($sql) { global $db; @@ -284,8 +295,9 @@ function q($sql) { if ($db && $db->connected) { $stmt = @vsprintf($sql,$args); // Disabled warnings //logger("dba: q: $stmt", LOGGER_ALL); - if ($stmt === false) + if ($stmt === false) { logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG); + } return $db->q($stmt); } @@ -300,34 +312,33 @@ function q($sql) { }} -/** - * - * Raw db query, no arguments - * - */ - if (! function_exists('dbq')) { +/** + * Raw db query, no arguments + */ function dbq($sql) { global $db; - if ($db && $db->connected) + if ($db && $db->connected) { $ret = $db->q($sql); - else + } else { $ret = false; + } return $ret; }} -// Caller is responsible for ensuring that any integer arguments to -// dbesc_array are actually integers and not malformed strings containing -// SQL injection vectors. All integer array elements should be specifically -// cast to int to avoid trouble. - - +/* + * Caller is responsible for ensuring that any integer arguments to + * dbesc_array are actually integers and not malformed strings containing + * SQL injection vectors. All integer array elements should be specifically + * cast to int to avoid trouble. + */ if (! function_exists('dbesc_array_cb')) { function dbesc_array_cb(&$item, $key) { - if (is_string($item)) + if (is_string($item)) { $item = dbesc($item); + } }} @@ -340,5 +351,5 @@ function dbesc_array(&$arr) { if (! function_exists('dba_timer')) { function dba_timer() { - return microtime(true); + return microtime(true); }} diff --git a/include/dbstructure.php b/include/dbstructure.php index 413395905d..156453d935 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -3,8 +3,8 @@ use Friendica\App; use Friendica\Core\Config; -require_once("boot.php"); -require_once("include/text.php"); +require_once "boot.php"; +require_once "include/text.php"; define('NEW_UPDATE_ROUTINE_VERSION', 1170); @@ -1742,6 +1742,8 @@ function db_definition() { ), "indexes" => array( "PRIMARY" => array("id"), + "pid" => array("pid"), + "priority_created" => array("priority", "created"), ) ); @@ -1766,7 +1768,7 @@ function dbstructure_run(&$argv, &$argc) { unset($db_host, $db_user, $db_pass, $db_data); } - if ($argc==2) { + if ($argc == 2) { switch ($argv[1]) { case "dryrun": update_structure(true, false); @@ -1776,7 +1778,7 @@ function dbstructure_run(&$argv, &$argc) { $build = get_config('system','build'); if (!x($build)) { - set_config('system','build',DB_UPDATE_VERSION); + set_config('system', 'build', DB_UPDATE_VERSION); $build = DB_UPDATE_VERSION; } @@ -1786,7 +1788,9 @@ function dbstructure_run(&$argv, &$argc) { // run any left update_nnnn functions in update.php for ($x = $stored; $x < $current; $x ++) { $r = run_update_function($x); - if (!$r) break; + if (!$r) { + break; + } } set_config('system','build',DB_UPDATE_VERSION); @@ -1813,7 +1817,7 @@ function dbstructure_run(&$argv, &$argc) { } -if (array_search(__file__,get_included_files())===0) { +if (array_search(__FILE__,get_included_files())===0) { dbstructure_run($_SERVER["argv"],$_SERVER["argc"]); killme(); } diff --git a/include/diaspora.php b/include/diaspora.php index 545edcc4bf..25f1aa03b8 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -3788,8 +3788,10 @@ class Diaspora { $message = self::construct_like($r[0], $contact); $message["author_signature"] = self::signature($contact, $message); - // We now store the signature more flexible to dynamically support new fields. - // This will break Diaspora compatibility with Friendica versions prior to 3.5. + /* + * Now store the signature more flexible to dynamically support new fields. + * This will break Diaspora compatibility with Friendica versions prior to 3.5. + */ q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')", intval($message_id), dbesc(json_encode($message)) @@ -3821,9 +3823,11 @@ class Diaspora { $message = self::construct_comment($item, $contact); $message["author_signature"] = self::signature($contact, $message); - // We now store the signature more flexible to dynamically support new fields. - // This will break Diaspora compatibility with Friendica versions prior to 3.5. - q("INSERT INTO `sign` (`iid`,`signed_text`) VALUES (%d,'%s')", + /* + * Now store the signature more flexible to dynamically support new fields. + * This will break Diaspora compatibility with Friendica versions prior to 3.5. + */ + q("INSERT INTO `sign` (`iid`, `signed_text`) VALUES (%d, '%s')", intval($message_id), dbesc(json_encode($message)) ); diff --git a/include/expire.php b/include/expire.php index 73bffb20dc..aa34cbaa5b 100644 --- a/include/expire.php +++ b/include/expire.php @@ -19,18 +19,17 @@ function expire_run(&$argv, &$argc){ } // make this optional as it could have a performance impact on large sites - - if (intval(get_config('system','optimize_items'))) { + if (intval(get_config('system', 'optimize_items'))) { q("OPTIMIZE TABLE `item`"); } logger('expire: start'); - $r = q("SELECT `uid`,`username`,`expire` FROM `user` WHERE `expire` != 0"); + $r = q("SELECT `uid`, `username`, `expire` FROM `user` WHERE `expire` != 0"); if (dbm::is_result($r)) { foreach ($r as $rr) { logger('Expire: ' . $rr['username'] . ' interval: ' . $rr['expire'], LOGGER_DEBUG); - item_expire($rr['uid'],$rr['expire']); + item_expire($rr['uid'], $rr['expire']); } } diff --git a/include/pgettext.php b/include/pgettext.php index 9b541e8e3c..756905a43a 100644 --- a/include/pgettext.php +++ b/include/pgettext.php @@ -12,15 +12,15 @@ use Friendica\Core\Config; -require_once("include/dba.php"); +require_once "include/dba.php"; -if(! function_exists('get_browser_language')) { +if (! function_exists('get_browser_language')) { /** * @brief get the prefered language from the HTTP_ACCEPT_LANGUAGE header */ function get_browser_language() { - if (x($_SERVER,'HTTP_ACCEPT_LANGUAGE')) { + if (x($_SERVER, 'HTTP_ACCEPT_LANGUAGE')) { // break up string into pieces (languages and q factors) preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse); @@ -29,11 +29,11 @@ function get_browser_language() { if (count($lang_parse[1])) { // go through the list of prefered languages and add a generic language // for sub-linguas (e.g. de-ch will add de) if not already in array - for ($i=0; $i3 ) { + if (strlen($lang_parse[1][$i])>3 ) { $dashpos = strpos($lang_parse[1][$i], '-'); - if (! in_array(substr($lang_parse[1][$i], 0, $dashpos), $lang_list ) ) { + if (!in_array(substr($lang_parse[1][$i], 0, $dashpos), $lang_list ) ) { $lang_list[] = strtolower(substr($lang_parse[1][$i], 0, $dashpos)); } } @@ -42,7 +42,7 @@ function get_browser_language() { } // check if we have translations for the preferred languages and pick the 1st that has - for ($i=0; $ilangsave = $lang; - if($language === $lang) + if ($language === $lang) { return; + } - if(isset($a->strings) && count($a->strings)) { + if (isset($a->strings) && count($a->strings)) { $a->stringsave = $a->strings; } $a->strings = array(); @@ -77,13 +78,15 @@ function push_lang($language) { function pop_lang() { global $lang, $a; - if($lang === $a->langsave) + if ($lang === $a->langsave) { return; + } - if(isset($a->stringsave)) + if (isset($a->stringsave)) { $a->strings = $a->stringsave; - else + } else { $a->strings = array(); + } $lang = $a->langsave; } @@ -91,7 +94,7 @@ function pop_lang() { // l -if(! function_exists('load_translation_table')) { +if (! function_exists('load_translation_table')) { /** * load string translation table for alternate language * @@ -106,15 +109,15 @@ function load_translation_table($lang) { // load enabled plugins strings $plugins = q("SELECT name FROM addon WHERE installed=1;"); if ($plugins!==false) { - foreach($plugins as $p) { + foreach ($plugins as $p) { $name = $p['name']; - if(file_exists("addon/$name/lang/$lang/strings.php")) { + if (file_exists("addon/$name/lang/$lang/strings.php")) { include("addon/$name/lang/$lang/strings.php"); } } } - if(file_exists("view/lang/$lang/strings.php")) { + if (file_exists("view/lang/$lang/strings.php")) { include("view/lang/$lang/strings.php"); } @@ -122,27 +125,27 @@ function load_translation_table($lang) { // translate string if translation exists -if(! function_exists('t')) { +if (! function_exists('t')) { function t($s) { $a = get_app(); - if(x($a->strings,$s)) { + if (x($a->strings,$s)) { $t = $a->strings[$s]; return is_array($t)?$t[0]:$t; } return $s; }} -if(! function_exists('tt')){ +if (! function_exists('tt')){ function tt($singular, $plural, $count){ global $lang; $a = get_app(); - if(x($a->strings,$singular)) { + if (x($a->strings,$singular)) { $t = $a->strings[$singular]; $f = 'string_plural_select_' . str_replace('-','_',$lang); - if(! function_exists($f)) + if (! function_exists($f)) $f = 'string_plural_select_default'; $k = $f($count); return is_array($t)?$t[$k]:$t; @@ -158,7 +161,7 @@ function tt($singular, $plural, $count){ // provide a fallback which will not collide with // a function defined in any language file -if(! function_exists('string_plural_select_default')) { +if (! function_exists('string_plural_select_default')) { function string_plural_select_default($n) { return ($n != 1); }} @@ -185,7 +188,7 @@ function get_available_languages() { $strings_file_paths[] = 'view/lang/en/strings.php'; } asort($strings_file_paths); - foreach($strings_file_paths as $strings_file_path) { + foreach ($strings_file_paths as $strings_file_path) { $path_array = explode('/', $strings_file_path); $langs[$path_array[2]] = $path_array[2]; } diff --git a/include/plugin.php b/include/plugin.php index 336b213aa3..9021f814b1 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -21,7 +21,7 @@ function uninstall_plugin($plugin){ ); @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if(function_exists($plugin . '_uninstall')) { + if (function_exists($plugin . '_uninstall')) { $func = $plugin . '_uninstall'; $func(); } @@ -37,12 +37,12 @@ if (! function_exists('install_plugin')){ function install_plugin($plugin) { // silently fail if plugin was removed - if(! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) + if (! file_exists('addon/' . $plugin . '/' . $plugin . '.php')) return false; logger("Addons: installing " . $plugin); $t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php'); @include_once('addon/' . $plugin . '/' . $plugin . '.php'); - if(function_exists($plugin . '_install')) { + if (function_exists($plugin . '_install')) { $func = $plugin . '_install'; $func(); @@ -58,7 +58,7 @@ function install_plugin($plugin) { // once most site tables have been updated. // This way the system won't fall over dead during the update. - if(file_exists('addon/' . $plugin . '/.hidden')) { + if (file_exists('addon/' . $plugin . '/.hidden')) { q("UPDATE `addon` SET `hidden` = 1 WHERE `name` = '%s'", dbesc($plugin) ); @@ -74,10 +74,10 @@ function install_plugin($plugin) { // reload all updated plugins -if(! function_exists('reload_plugins')) { +if (! function_exists('reload_plugins')) { function reload_plugins() { $plugins = get_config('system','addon'); - if(strlen($plugins)) { + if (strlen($plugins)) { $r = q("SELECT * FROM `addon` WHERE `installed` = 1"); if (dbm::is_result($r)) @@ -87,25 +87,25 @@ function reload_plugins() { $parr = explode(',',$plugins); - if(count($parr)) { - foreach($parr as $pl) { + if (count($parr)) { + foreach ($parr as $pl) { $pl = trim($pl); $fname = 'addon/' . $pl . '/' . $pl . '.php'; - if(file_exists($fname)) { + if (file_exists($fname)) { $t = @filemtime($fname); - foreach($installed as $i) { - if(($i['name'] == $pl) && ($i['timestamp'] != $t)) { + foreach ($installed as $i) { + if (($i['name'] == $pl) && ($i['timestamp'] != $t)) { logger('Reloading plugin: ' . $i['name']); @include_once($fname); - if(function_exists($pl . '_uninstall')) { + if (function_exists($pl . '_uninstall')) { $func = $pl . '_uninstall'; $func(); } - if(function_exists($pl . '_install')) { + if (function_exists($pl . '_install')) { $func = $pl . '_install'; $func(); } @@ -143,7 +143,7 @@ function plugin_enabled($plugin) { * @param int $priority A priority (defaults to 0) * @return mixed|bool */ -if(! function_exists('register_hook')) { +if (! function_exists('register_hook')) { function register_hook($hook,$file,$function,$priority=0) { $r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s' LIMIT 1", @@ -171,7 +171,7 @@ function register_hook($hook,$file,$function,$priority=0) { * @param string $function the name of the function that the hook called * @return array */ -if(! function_exists('unregister_hook')) { +if (! function_exists('unregister_hook')) { function unregister_hook($hook,$file,$function) { $r = q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'", @@ -183,7 +183,7 @@ function unregister_hook($hook,$file,$function) { }} -if(! function_exists('load_hooks')) { +if (! function_exists('load_hooks')) { function load_hooks() { $a = get_app(); $a->hooks = array(); @@ -191,7 +191,7 @@ function load_hooks() { if (dbm::is_result($r)) { foreach ($r as $rr) { - if(! array_key_exists($rr['hook'],$a->hooks)) + if (! array_key_exists($rr['hook'],$a->hooks)) $a->hooks[$rr['hook']] = array(); $a->hooks[$rr['hook']][] = array($rr['file'],$rr['function']); } @@ -245,13 +245,13 @@ function call_single_hook($a, $name, $hook, &$data = null) { //check if an app_menu hook exist for plugin $name. //Return true if the plugin is an app -if(! function_exists('plugin_is_app')) { +if (! function_exists('plugin_is_app')) { function plugin_is_app($name) { $a = get_app(); - 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') + 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; } } @@ -298,7 +298,7 @@ function get_plugin_info($plugin){ if ($r){ $ll = explode("\n", $m[0]); - foreach( $ll as $l ) { + foreach ( $ll as $l ) { $l = trim($l,"\t\n\r */"); if ($l!=""){ list($k,$v) = array_map("trim", explode(":",$l,2)); @@ -353,9 +353,9 @@ function get_theme_info($theme){ 'unsupported' => false ); - if(file_exists("view/theme/$theme/experimental")) + if (file_exists("view/theme/$theme/experimental")) $info['experimental'] = true; - if(file_exists("view/theme/$theme/unsupported")) + if (file_exists("view/theme/$theme/unsupported")) $info['unsupported'] = true; if (!is_file("view/theme/$theme/theme.php")) return $info; @@ -369,7 +369,7 @@ function get_theme_info($theme){ if ($r){ $ll = explode("\n", $m[0]); - foreach( $ll as $l ) { + foreach ( $ll as $l ) { $l = trim($l,"\t\n\r */"); if ($l!=""){ list($k,$v) = array_map("trim", explode(":",$l,2)); @@ -413,7 +413,7 @@ function get_theme_info($theme){ */ function get_theme_screenshot($theme) { $exts = array('.png','.jpg'); - foreach($exts as $ext) { + foreach ($exts as $ext) { if (file_exists('view/theme/' . $theme . '/screenshot' . $ext)) { return(App::get_baseurl() . '/view/theme/' . $theme . '/screenshot' . $ext); } @@ -512,11 +512,11 @@ function service_class_fetch($uid,$property) { $service_class = $r[0]['service_class']; } } - if(! x($service_class)) + if (! x($service_class)) return false; // everything is allowed $arr = get_config('service_class',$service_class); - if(! is_array($arr) || (! count($arr))) + if (! is_array($arr) || (! count($arr))) return false; return((array_key_exists($property,$arr)) ? $arr[$property] : false); @@ -525,12 +525,14 @@ function service_class_fetch($uid,$property) { function upgrade_link($bbcode = false) { $l = get_config('service_class','upgrade_link'); - if(! $l) + if (! $l) { return ''; - if($bbcode) + } + if ($bbcode) { $t = sprintf('[url=%s]' . t('Click here to upgrade.') . '[/url]', $l); - else + } else { $t = sprintf('' . t('Click here to upgrade.') . '', $l); + } return $t; } @@ -557,13 +559,15 @@ function upgrade_bool_message($bbcode = false) { */ function theme_include($file, $root = '') { // Make sure $root ends with a slash / if it's not blank - if($root !== '' && $root[strlen($root)-1] !== '/') + if ($root !== '' && $root[strlen($root)-1] !== '/') { $root = $root . '/'; + } $theme_info = $a->theme_info; - if(is_array($theme_info) AND array_key_exists('extends',$theme_info)) + if (is_array($theme_info) AND array_key_exists('extends',$theme_info)) { $parent = $theme_info['extends']; - else + } else { $parent = 'NOPATH'; + } $theme = current_theme(); $thname = $theme; $ext = substr($file,strrpos($file,'.')+1); @@ -572,12 +576,13 @@ function theme_include($file, $root = '') { "{$root}view/theme/$parent/$ext/$file", "{$root}view/$ext/$file", ); - foreach($paths as $p) { + foreach ($paths as $p) { // strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php) - if(strpos($p,'NOPATH') !== false) + if (strpos($p,'NOPATH') !== false) { continue; - if(file_exists($p)) + } elseif (file_exists($p)) { return $p; + } } return ''; } diff --git a/include/poller.php b/include/poller.php index 0c5bebbda5..0011559c69 100644 --- a/include/poller.php +++ b/include/poller.php @@ -23,7 +23,7 @@ function poller_run($argv, $argc){ $a = new App(dirname(__DIR__)); } - if(is_null($db)) { + if (is_null($db)) { @include(".htconfig.php"); require_once("include/dba.php"); $db = new dba($db_host, $db_user, $db_pass, $db_data); @@ -55,7 +55,7 @@ function poller_run($argv, $argc){ return; } - if(($argc <= 1) OR ($argv[1] != "no_cron")) { + if (($argc <= 1) OR ($argv[1] != "no_cron")) { poller_run_cron(); } @@ -79,22 +79,28 @@ function poller_run($argv, $argc){ // Check free memory if ($a->min_memory_reached()) { + logger('Memory limit reached, quitting.', LOGGER_DEBUG); return; } // Count active workers and compare them with a maximum value that depends on the load if (poller_too_much_workers()) { + logger('Active worker limit reached, quitting.', LOGGER_DEBUG); return; } if (!poller_execute($r[0])) { + logger('Process execution failed, quitting.', LOGGER_DEBUG); return; } // Quit the poller once every hour - if (time() > ($starttime + 3600)) + if (time() > ($starttime + 3600)) { + logger('Process lifetime reachted, quitting.', LOGGER_DEBUG); return; + } } + logger("Couldn't select a workerqueue entry, quitting.", LOGGER_DEBUG); } /** @@ -146,7 +152,6 @@ function poller_execute($queue) { if (function_exists($funcname)) { poller_exec_function($queue, $funcname, $argv); - dba::delete('workerqueue', array('id' => $queue["id"])); } else { logger("Function ".$funcname." does not exist"); @@ -361,8 +366,9 @@ function poller_kill_stale_workers() { // Kill long running processes // Check if the priority is in a valid range - if (!in_array($pid["priority"], array(PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW, PRIORITY_NEGLIGIBLE))) + if (!in_array($pid["priority"], array(PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW, PRIORITY_NEGLIGIBLE))) { $pid["priority"] = PRIORITY_MEDIUM; + } // Define the maximum durations $max_duration_defaults = array(PRIORITY_CRITICAL => 360, PRIORITY_HIGH => 10, PRIORITY_MEDIUM => 60, PRIORITY_LOW => 180, PRIORITY_NEGLIGIBLE => 360); @@ -400,6 +406,8 @@ function poller_too_much_workers() { $maxqueues = $queues; + $active = poller_active_workers(); + // Decrease the number of workers at higher load $load = current_load(); if ($load) { @@ -412,8 +420,6 @@ function poller_too_much_workers() { $slope = $maxworkers / pow($maxsysload, $exponent); $queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent)); - $active = 0; - // Create a list of queue entries grouped by their priority $listitem = array(); @@ -421,17 +427,15 @@ function poller_too_much_workers() { $processes = dba::p("SELECT COUNT(*) AS `running` FROM `process` WHERE NOT EXISTS (SELECT id FROM `workerqueue` WHERE `workerqueue`.`pid` = `process`.`pid`)"); if ($process = dba::fetch($processes)) { $listitem[0] = "0:".$process["running"]; - $active += $process["running"]; } dba::close($processes); // Now adding all processes with workerqueue entries $entries = dba::p("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` GROUP BY `priority`"); while ($entry = dba::fetch($entries)) { - $processes = dba::p("SELECT COUNT(*) AS `running` FROM `process` LEFT JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid` WHERE `priority` = ?", $entry["priority"]); + $processes = dba::p("SELECT COUNT(*) AS `running` FROM `process` INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid` WHERE `priority` = ?", $entry["priority"]); if ($process = dba::fetch($processes)) { $listitem[$entry["priority"]] = $entry["priority"].":".$process["running"]."/".$entry["entries"]; - $active += $process["running"]; } dba::close($processes); } @@ -465,8 +469,6 @@ function poller_too_much_workers() { $a = get_app(); $a->proc_run($args); } - } else { - $active = poller_active_workers(); } return($active >= $queues); @@ -540,16 +542,16 @@ function poller_passing_slow(&$highest_priority) { */ function poller_worker_process() { - dba::transaction(); - // Check if we should pass some low priority process $highest_priority = 0; if (poller_passing_slow($highest_priority)) { + dba::e('LOCK TABLES `workerqueue` WRITE'); + // Are there waiting processes with a higher priority than the currently highest? $r = q("SELECT * FROM `workerqueue` WHERE `executed` <= '%s' AND `priority` < %d - ORDER BY `priority`, `created` LIMIT 1 FOR UPDATE", + ORDER BY `priority`, `created` LIMIT 1", dbesc(NULL_DATE), intval($highest_priority)); if (dbm::is_result($r)) { @@ -558,18 +560,25 @@ function poller_worker_process() { // Give slower processes some processing time $r = q("SELECT * FROM `workerqueue` WHERE `executed` <= '%s' AND `priority` > %d - ORDER BY `priority`, `created` LIMIT 1 FOR UPDATE", + ORDER BY `priority`, `created` LIMIT 1", dbesc(NULL_DATE), intval($highest_priority)); if (dbm::is_result($r)) { return $r; } + } else { + dba::e('LOCK TABLES `workerqueue` WRITE'); } // If there is no result (or we shouldn't pass lower processes) we check without priority limit if (!dbm::is_result($r)) { - $r = q("SELECT * FROM `workerqueue` WHERE `executed` <= '%s' ORDER BY `priority`, `created` LIMIT 1 FOR UPDATE", dbesc(NULL_DATE)); + $r = q("SELECT * FROM `workerqueue` WHERE `executed` <= '%s' ORDER BY `priority`, `created` LIMIT 1", dbesc(NULL_DATE)); + } + + // We only unlock the tables here, when we got no data + if (!dbm::is_result($r)) { + dba::e('UNLOCK TABLES'); } return $r; @@ -578,7 +587,7 @@ function poller_worker_process() { /** * @brief Assigns a workerqueue entry to the current process * - * All the checks after the update are only needed with MyISAM. + * When we are sure that the table locks are working correctly, we can remove the checks from here * * @param array $queue Workerqueue entry * @@ -587,10 +596,12 @@ function poller_worker_process() { function poller_claim_process($queue) { $mypid = getmypid(); - if (!dba::update('workerqueue', array('executed' => datetime_convert(), 'pid' => $mypid), - array('id' => $queue["id"], 'pid' => 0))) { + $success = dba::update('workerqueue', array('executed' => datetime_convert(), 'pid' => $mypid), + array('id' => $queue["id"], 'pid' => 0)); + dba::e('UNLOCK TABLES'); + + if (!$success) { logger("Couldn't update queue entry ".$queue["id"]." - skip this execution", LOGGER_DEBUG); - dba::commit(); return false; } @@ -598,18 +609,14 @@ function poller_claim_process($queue) { $id = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `id` = %d", intval($queue["id"])); if (!$id) { logger("Queue item ".$queue["id"]." vanished - skip this execution", LOGGER_DEBUG); - dba::commit(); return false; } elseif ((strtotime($id[0]["executed"]) <= 0) OR ($id[0]["pid"] == 0)) { logger("Entry for queue item ".$queue["id"]." wasn't stored - skip this execution", LOGGER_DEBUG); - dba::commit(); return false; } elseif ($id[0]["pid"] != $mypid) { logger("Queue item ".$queue["id"]." is to be executed by process ".$id[0]["pid"]." and not by me (".$mypid.") - skip this execution", LOGGER_DEBUG); - dba::commit(); return false; } - dba::commit(); return true; } diff --git a/include/post_update.php b/include/post_update.php index 9d18b27b4f..af49bb555c 100644 --- a/include/post_update.php +++ b/include/post_update.php @@ -68,7 +68,7 @@ function post_update_1192() { } // Set the "gcontact-id" in the item table and add a new gcontact entry if needed - foreach($item_arr AS $item) { + foreach ($item_arr AS $item) { $gcontact_id = get_gcontact_id(array("url" => $item['author-link'], "network" => $item['network'], "photo" => $item['author-avatar'], "name" => $item['author-name'])); q("UPDATE `item` SET `gcontact-id` = %d WHERE `uid` = %d AND `author-link` = '%s' AND `gcontact-id` = 0", @@ -204,7 +204,7 @@ function post_update_1198() { } // Set the "gcontact-id" in the item table and add a new gcontact entry if needed - foreach($item_arr AS $item) { + foreach ($item_arr AS $item) { $author_id = get_contact($item["author-link"], 0); $owner_id = get_contact($item["owner-link"], 0); diff --git a/include/profile_selectors.php b/include/profile_selectors.php index 8d29fd0998..af6c0d96c4 100644 --- a/include/profile_selectors.php +++ b/include/profile_selectors.php @@ -8,8 +8,8 @@ function gender_selector($current="",$suffix="") { call_hooks('gender_selector', $select); $o .= ""; - foreach($select as $selection) { - if($selection !== 'NOTRANSLATION') { + foreach ($select as $selection) { + if ($selection !== 'NOTRANSLATION') { $selected = (($selection == $current) ? ' selected="selected" ' : ''); $o .= ""; } @@ -44,8 +44,8 @@ function marital_selector($current="",$suffix="") { call_hooks('marital_selector', $select); $o .= "