From 3474b407322092ebedb8ffb7a45afdbee0c486d0 Mon Sep 17 00:00:00 2001 From: rabuzarus <> Date: Fri, 10 Feb 2017 03:51:01 +0100 Subject: [PATCH 01/25] fix - pending contacts shouldn't be shown in contacts widgit and viewcontacts --- include/api.php | 4 ++-- include/identity.php | 5 ++++- include/text.php | 7 ++++--- mod/viewcontacts.php | 6 ++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/api.php b/include/api.php index ce7610312..d7fa1d587 100644 --- a/include/api.php +++ b/include/api.php @@ -626,7 +626,7 @@ use \Friendica\Core\Config; // count friends $r = q("SELECT count(*) as `count` FROM `contact` WHERE `uid` = %d AND `rel` IN ( %d, %d ) - AND `self`=0 AND NOT `blocked` AND `hidden`=0", + AND `self`=0 AND NOT `blocked` AND NOT `pending` AND `hidden`=0", intval($uinfo[0]['uid']), intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND) @@ -635,7 +635,7 @@ use \Friendica\Core\Config; $r = q("SELECT count(*) as `count` FROM `contact` WHERE `uid` = %d AND `rel` IN ( %d, %d ) - AND `self`=0 AND NOT `blocked` AND `hidden`=0", + AND `self`=0 AND NOT `blocked` AND NOT `pending` AND `hidden`=0", intval($uinfo[0]['uid']), intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FRIEND) diff --git a/include/identity.php b/include/identity.php index d3852b2c2..ab80c71ce 100644 --- a/include/identity.php +++ b/include/identity.php @@ -374,7 +374,10 @@ function profile_sidebar($profile, $block = 0) { if (dbm::is_result($r)) $updated = date("c", strtotime($r[0]['updated'])); - $r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `hidden` AND NOT `archive` + $r = q("SELECT COUNT(*) AS `total` FROM `contact` + WHERE `uid` = %d + AND NOT `self` AND NOT `blocked` AND NOT `pending` + AND NOT `hidden` AND NOT `archive` AND `network` IN ('%s', '%s', '%s', '')", intval($profile['uid']), dbesc(NETWORK_DFRN), diff --git a/include/text.php b/include/text.php index f77a4dec2..11248902b 100644 --- a/include/text.php +++ b/include/text.php @@ -875,7 +875,7 @@ function contact_block() { return $o; $r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `blocked` - AND NOT `hidden` AND NOT `archive` + AND NOT `pending` AND NOT `hidden` AND NOT `archive` AND `network` IN ('%s', '%s', '%s')", intval($a->profile['uid']), dbesc(NETWORK_DFRN), @@ -893,8 +893,9 @@ function contact_block() { // Splitting the query in two parts makes it much faster $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `blocked` - AND NOT `hidden` AND NOT `archive` - AND `network` IN ('%s', '%s', '%s') ORDER BY RAND() LIMIT %d", + AND NOT `pending` AND NOT `hidden` AND NOT `archive` + AND `network` IN ('%s', '%s', '%s') + ORDER BY RAND() LIMIT %d", intval($a->profile['uid']), dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), diff --git a/mod/viewcontacts.php b/mod/viewcontacts.php index 55afda9b6..5912f6cc7 100644 --- a/mod/viewcontacts.php +++ b/mod/viewcontacts.php @@ -48,7 +48,8 @@ function viewcontacts_content(App $a) { } $r = q("SELECT COUNT(*) AS `total` FROM `contact` - WHERE `uid` = %d AND (NOT `blocked` OR `pending`) AND NOT `hidden` AND NOT `archive` + WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` + AND NOT `hidden` AND NOT `archive` AND `network` IN ('%s', '%s', '%s')", intval($a->profile['uid']), dbesc(NETWORK_DFRN), @@ -59,7 +60,8 @@ function viewcontacts_content(App $a) { $a->set_pager_total($r[0]['total']); $r = q("SELECT * FROM `contact` - WHERE `uid` = %d AND (NOT `blocked` OR `pending`) AND NOT `hidden` AND NOT `archive` + WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` + AND NOT `hidden` AND NOT `archive` AND `network` IN ('%s', '%s', '%s') ORDER BY `name` ASC LIMIT %d, %d", intval($a->profile['uid']), From 40390cc5ece7f9a1e723dca19946b86fcac46a77 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Feb 2017 20:45:22 +0000 Subject: [PATCH 02/25] Diaspora Relay: Only accept postings from anyone when the relay is configured --- boot.php | 11 ++++ include/diaspora.php | 16 +++-- mod/_well_known.php | 135 ++++++++++++++++++++++--------------------- 3 files changed, 90 insertions(+), 72 deletions(-) diff --git a/boot.php b/boot.php index 56fb05435..e6fe08951 100644 --- a/boot.php +++ b/boot.php @@ -430,6 +430,17 @@ define('PRIORITY_LOW', 40); define('PRIORITY_NEGLIGIBLE',50); /* @}*/ +/** + * @name Social Relay settings + * + * See here: https://github.com/jaywink/social-relay + * and here: https://wiki.diasporafoundation.org/Relay_servers_for_public_posts + * @{ + */ +define('SR_SCOPE_NONE', ''); +define('SR_SCOPE_ALL', 'all'); +define('SR_SCOPE_TAGS', 'tags'); +/* @}*/ // Normally this constant is defined - but not if "pcntl" isn't installed if (!defined("SIGTERM")) diff --git a/include/diaspora.php b/include/diaspora.php index fdbc0479f..53f2e7ea7 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -8,6 +8,8 @@ * This will change in the future. */ +use \Friendica\Core\Config; + require_once("include/items.php"); require_once("include/bb2diaspora.php"); require_once("include/Scrape.php"); @@ -309,10 +311,6 @@ class Diaspora { return false; } - // Use a dummy importer to import the data for the public copy - $importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE); - $message_id = self::dispatch($importer,$msg); - // Now distribute it to the followers $r = q("SELECT `user`.* FROM `user` WHERE `user`.`uid` IN (SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s') @@ -320,7 +318,7 @@ class Diaspora { dbesc(NETWORK_DIASPORA), dbesc($msg["author"]) ); - if ($r) { + if (dbm::is_result($r)) { foreach ($r as $rr) { logger("delivering to: ".$rr["username"]); self::dispatch($rr,$msg); @@ -329,6 +327,14 @@ class Diaspora { logger("No subscribers for ".$msg["author"]." ".print_r($msg, true), LOGGER_DEBUG); } + $social_relay = (bool)Config::get('system', 'relay_subscribe', false); + + // Use a dummy importer to import the data for the public copy + if (dbm::is_result($r) OR $social_relay) { + $importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE); + $message_id = self::dispatch($importer,$msg); + } + return $message_id; } diff --git a/mod/_well_known.php b/mod/_well_known.php index 75948a008..622d7fd93 100644 --- a/mod/_well_known.php +++ b/mod/_well_known.php @@ -1,67 +1,68 @@ -argc > 1) { - switch($a->argv[1]) { - case "host-meta": - hostxrd_init($a); - break; - case "x-social-relay": - wk_social_relay($a); - break; - case "nodeinfo": - nodeinfo_wellknown($a); - break; - } - } - http_status_exit(404); - killme(); -} - -function wk_social_relay(App $a) { - - define('SR_SCOPE_ALL', 'all'); - define('SR_SCOPE_TAGS', 'tags'); - - $subscribe = (bool)get_config('system', 'relay_subscribe'); - - if ($subscribe) - $scope = get_config('system', 'relay_scope'); - else - $scope = ""; - - $tags = array(); - - if ($scope == SR_SCOPE_TAGS) { - - $server_tags = get_config('system', 'relay_server_tags'); - $tagitems = explode(",", $server_tags); - - foreach($tagitems AS $tag) - $tags[trim($tag, "# ")] = trim($tag, "# "); - - if (get_config('system', 'relay_user_tags')) { - $terms = q("SELECT DISTINCT(`term`) FROM `search`"); - - foreach($terms AS $term) { - $tag = trim($term["term"], "#"); - $tags[$tag] = $tag; - } - } - } - - $taglist = array(); - foreach($tags AS $tag) - $taglist[] = $tag; - - $relay = array("subscribe" => $subscribe, - "scope" => $scope, - "tags" => $taglist); - - header('Content-type: application/json; charset=utf-8'); - echo json_encode($relay, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); - exit; -} +argc > 1) { + switch($a->argv[1]) { + case "host-meta": + hostxrd_init($a); + break; + case "x-social-relay": + wk_social_relay($a); + break; + case "nodeinfo": + nodeinfo_wellknown($a); + break; + } + } + http_status_exit(404); + killme(); +} + +function wk_social_relay(App $a) { + + $subscribe = (bool)Config::get('system', 'relay_subscribe', false); + + if ($subscribe) { + $scope = Config::get('system', 'relay_scope', SR_SCOPE_ALL); + } else { + $scope = SR_SCOPE_NONE; + } + + $tags = array(); + + if ($scope == SR_SCOPE_TAGS) { + $server_tags = Config::get('system', 'relay_server_tags'); + $tagitems = explode(",", $server_tags); + + foreach($tagitems AS $tag) { + $tags[trim($tag, "# ")] = trim($tag, "# "); + } + + if (Config::get('system', 'relay_user_tags')) { + $terms = q("SELECT DISTINCT(`term`) FROM `search`"); + + foreach($terms AS $term) { + $tag = trim($term["term"], "#"); + $tags[$tag] = $tag; + } + } + } + + $taglist = array(); + foreach($tags AS $tag) { + $taglist[] = $tag; + } + + $relay = array("subscribe" => $subscribe, + "scope" => $scope, + "tags" => $taglist); + + header('Content-type: application/json; charset=utf-8'); + echo json_encode($relay, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + exit; +} From e5e6f4fd1967507410355305d36192efd0293ff7 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 11 Feb 2017 23:37:15 +0000 Subject: [PATCH 03/25] Better logging to analyze unwanted messages from Diaspora --- include/diaspora.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 53f2e7ea7..eca22092d 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -318,21 +318,22 @@ class Diaspora { dbesc(NETWORK_DIASPORA), dbesc($msg["author"]) ); + if (dbm::is_result($r)) { foreach ($r as $rr) { logger("delivering to: ".$rr["username"]); self::dispatch($rr,$msg); } } else { - logger("No subscribers for ".$msg["author"]." ".print_r($msg, true), LOGGER_DEBUG); - } + $social_relay = (bool)Config::get('system', 'relay_subscribe', false); - $social_relay = (bool)Config::get('system', 'relay_subscribe', false); - - // Use a dummy importer to import the data for the public copy - if (dbm::is_result($r) OR $social_relay) { - $importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE); - $message_id = self::dispatch($importer,$msg); + // Use a dummy importer to import the data for the public copy + if ($social_relay) { + $importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE); + $message_id = self::dispatch($importer,$msg); + } else { + logger("Unwanted message from ".$msg["author"]." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG); + } } return $message_id; From 7ba52288140c639889c2db41fc3f771da0146813 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 14 Feb 2017 21:13:00 +0000 Subject: [PATCH 04/25] Bugfix: Only delete spool files that are spool files --- include/spool_post.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/spool_post.php b/include/spool_post.php index d55b100ed..78384c23a 100644 --- a/include/spool_post.php +++ b/include/spool_post.php @@ -35,7 +35,13 @@ function spool_post_run($argv, $argc) { continue; } $arr = json_decode(file_get_contents($fullfile), true); + if (!is_array($arr)) { + continue; + } $result = item_store($arr); + if ($result == 0) { + continue; + } logger("Spool file ".$file." stored: ".$result, LOGGER_DEBUG); unlink($fullfile); } From 51a6903b4cc04cfb205c996ee7f0416a64196122 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 15 Feb 2017 07:55:30 +0100 Subject: [PATCH 05/25] fix for less file of quattro, regen CSS --- view/theme/quattro/dark/style.css | 2 +- view/theme/quattro/green/style.css | 2 +- view/theme/quattro/lilac/style.css | 2 +- view/theme/quattro/quattro.less | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/view/theme/quattro/dark/style.css b/view/theme/quattro/dark/style.css index 4a1f77881..3e8fe754b 100644 --- a/view/theme/quattro/dark/style.css +++ b/view/theme/quattro/dark/style.css @@ -1210,7 +1210,7 @@ section { .wall-item-container .wall-item-actions-social a { margin-right: 3em; } -.wall-item-container .wall-item-actions-social a .active { +.wall-item-container .wall-item-actions-social a.active { font-weight: bold; } .wall-item-container .wall-item-actions-tools { diff --git a/view/theme/quattro/green/style.css b/view/theme/quattro/green/style.css index 11fff105d..8eba0e4cf 100644 --- a/view/theme/quattro/green/style.css +++ b/view/theme/quattro/green/style.css @@ -1210,7 +1210,7 @@ section { .wall-item-container .wall-item-actions-social a { margin-right: 3em; } -.wall-item-container .wall-item-actions-social a .active { +.wall-item-container .wall-item-actions-social a.active { font-weight: bold; } .wall-item-container .wall-item-actions-tools { diff --git a/view/theme/quattro/lilac/style.css b/view/theme/quattro/lilac/style.css index 81564a0d2..b42453420 100644 --- a/view/theme/quattro/lilac/style.css +++ b/view/theme/quattro/lilac/style.css @@ -1210,7 +1210,7 @@ section { .wall-item-container .wall-item-actions-social a { margin-right: 3em; } -.wall-item-container .wall-item-actions-social a .active { +.wall-item-container .wall-item-actions-social a.active { font-weight: bold; } .wall-item-container .wall-item-actions-tools { diff --git a/view/theme/quattro/quattro.less b/view/theme/quattro/quattro.less index 469c075c4..6c0198688 100644 --- a/view/theme/quattro/quattro.less +++ b/view/theme/quattro/quattro.less @@ -576,7 +576,7 @@ section { } .wall-item-actions-social { float: left; margin-top: 0.5em; a { margin-right: 3em; - .active { font-weight: bold;} + &.active { font-weight: bold;} } } .wall-item-actions-tools { float: right; width: 15%; From 7e1f51b0f9fb6135eddd197be6fa4799b866fc64 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 15 Feb 2017 08:13:06 +0100 Subject: [PATCH 06/25] SV update to the strings --- view/lang/sv/messages.po | 7 ++++--- view/lang/sv/strings.php | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/view/lang/sv/messages.po b/view/lang/sv/messages.po index f3c786844..16d4ba89f 100644 --- a/view/lang/sv/messages.po +++ b/view/lang/sv/messages.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the Friendica package. # # Translators: +# Jonatan Nyberg , 2017 # Mike Macgirvin, 2010 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-12-19 07:46+0100\n" -"PO-Revision-Date: 2016-12-19 10:01+0000\n" -"Last-Translator: fabrixxm \n" +"PO-Revision-Date: 2017-02-13 20:15+0000\n" +"Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish (http://www.transifex.com/Friendica/friendica/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +21,7 @@ msgstr "" #: include/contact_widgets.php:6 msgid "Add New Contact" -msgstr "" +msgstr "Lägg till kontakt" #: include/contact_widgets.php:7 msgid "Enter address or web location" diff --git a/view/lang/sv/strings.php b/view/lang/sv/strings.php index 6a789c061..499ed9200 100644 --- a/view/lang/sv/strings.php +++ b/view/lang/sv/strings.php @@ -5,7 +5,7 @@ function string_plural_select_sv($n){ return ($n != 1);; }} ; -$a->strings["Add New Contact"] = ""; +$a->strings["Add New Contact"] = "Lägg till kontakt"; $a->strings["Enter address or web location"] = ""; $a->strings["Example: bob@example.com, http://example.com/barbara"] = "Exempel: adam@exempel.com, http://exempel.com/bertil"; $a->strings["Connect"] = "Skicka kontaktförfrågan"; From 90b5cbe71c898db9456b6469e949a94ecf804c05 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 15 Feb 2017 21:46:29 +0000 Subject: [PATCH 07/25] More analytics to analyze the reason for constantly changing temp paths --- boot.php | 76 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/boot.php b/boot.php index e6fe08951..504a524ed 100644 --- a/boot.php +++ b/boot.php @@ -1415,6 +1415,53 @@ class App { proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__))); } + + /** + * @brief Returns the system user that is executing the script + * + * This mostly returns something like "www-data". + * + * @return string system username + */ + static function systemuser() { + if (!function_exists('posix_getpwuid') OR !function_exists('posix_geteuid')) { + return ''; + } + + $processUser = posix_getpwuid(posix_geteuid()); + return $processUser['name']; + } + + /** + * @brief Checks if a given directory is usable for the system + * + * @return boolean the directory is usable + */ + static function directory_usable($directory) { + + if ($directory == '') { + logger("Directory is empty. This shouldn't happen.", LOGGER_DEBUG); + return false; + } + + if (!file_exists($directory)) { + logger('Path "'.$directory.'" does not exist for user '.self::systemuser(), LOGGER_DEBUG); + return false; + } + if (is_file($directory)) { + logger('Path "'.$directory.'" is a file for user '.self::systemuser(), LOGGER_DEBUG); + return false; + } + if (!is_dir($directory)) { + logger('Path "'.$directory.'" is not a directory for user '.self::systemuser(), LOGGER_DEBUG); + return false; + } + if (!is_writable($directory)) { + logger('Path "'.$temppath.'" is not writable for user '.self::systemuser(), LOGGER_DEBUG); + return false; + } + return true; + } } /** @@ -2319,8 +2366,9 @@ function get_itemcachepath() { return ""; $itemcache = get_config('system','itemcache'); - if (($itemcache != "") AND is_dir($itemcache) AND is_writable($itemcache)) + if (($itemcache != "") AND App::directory_usable($itemcache)) { return($itemcache); + } $temppath = get_temppath(); @@ -2330,7 +2378,7 @@ function get_itemcachepath() { mkdir($itemcache); } - if (is_dir($itemcache) AND is_writable($itemcache)) { + if (App::directory_usable($itemcache)) { set_config("system", "itemcache", $itemcache); return($itemcache); } @@ -2340,20 +2388,22 @@ function get_itemcachepath() { function get_lockpath() { $lockpath = get_config('system','lockpath'); - if (($lockpath != "") AND is_dir($lockpath) AND is_writable($lockpath)) + if (($lockpath != "") AND App::directory_usable($lockpath)) { return($lockpath); + } $temppath = get_temppath(); if ($temppath != "") { $lockpath = $temppath."/lock"; - if (!is_dir($lockpath)) + if (!is_dir($lockpath)) { mkdir($lockpath); - elseif (!is_writable($lockpath)) + } elseif (!App::directory_usable($lockpath)) { $lockpath = $temppath; + } - if (is_dir($lockpath) AND is_writable($lockpath)) { + if (App::directory_usable($lockpath)) { set_config("system", "lockpath", $lockpath); return($lockpath); } @@ -2368,7 +2418,7 @@ function get_lockpath() { */ function get_spoolpath() { $spoolpath = get_config('system','spoolpath'); - if (($spoolpath != "") AND is_dir($spoolpath) AND is_writable($spoolpath)) { + if (($spoolpath != "") AND App::directory_usable($spoolpath)) { return($spoolpath); } @@ -2379,11 +2429,11 @@ function get_spoolpath() { if (!is_dir($spoolpath)) { mkdir($spoolpath); - } elseif (!is_writable($spoolpath)) { + } elseif (!App::directory_usable($spoolpath)) { $spoolpath = $temppath; } - if (is_dir($spoolpath) AND is_writable($spoolpath)) { + if (App::directory_usable($spoolpath)) { set_config("system", "spoolpath", $spoolpath); return($spoolpath); } @@ -2395,16 +2445,18 @@ function get_temppath() { $a = get_app(); $temppath = get_config("system","temppath"); - if (($temppath != "") AND is_dir($temppath) AND is_writable($temppath)) + + if (($temppath != "") AND App::directory_usable($temppath)) { return($temppath); + } $temppath = sys_get_temp_dir(); - if (($temppath != "") AND is_dir($temppath) AND is_writable($temppath)) { + if (($temppath != "") AND App::directory_usable($temppath)) { $temppath .= "/".$a->get_hostname(); if (!is_dir($temppath)) mkdir($temppath); - if (is_dir($temppath) AND is_writable($temppath)) { + if (App::directory_usable($temppath)) { set_config("system", "temppath", $temppath); return($temppath); } From 3cdfaa4fad16aae720f9d92ee34564ad6211ec57 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 16 Feb 2017 07:06:11 -0500 Subject: [PATCH 08/25] [frio] Fix comment box not opening on focus, undefined on blur - Remove the callback system for commentOpenUI - Remove comments Fixes #3062 --- view/theme/frio/js/textedit.js | 46 ++++++++++++---------------------- view/theme/frio/js/theme.js | 45 +++++---------------------------- 2 files changed, 22 insertions(+), 69 deletions(-) diff --git a/view/theme/frio/js/textedit.js b/view/theme/frio/js/textedit.js index 9c5c1823d..9226646b7 100644 --- a/view/theme/frio/js/textedit.js +++ b/view/theme/frio/js/textedit.js @@ -81,39 +81,25 @@ function showHideCommentBox(id) { } function commentOpenUI(obj, id) { - $(document).unbind( "click.commentOpen", handler ); - - var handler = function() { - if (obj.value == '') { - $("#comment-edit-text-" + id).addClass("comment-edit-text-full").removeClass("comment-edit-text-empty"); - // Choose an arbitrary tab index that's greater than what we're using in jot (3 of them) - // The submit button gets tabindex + 1 - $("#comment-edit-text-" + id).attr('tabindex','9'); - $("#comment-edit-submit-" + id).attr('tabindex','10'); - $("#comment-edit-submit-wrapper-" + id).show(); - // initialize autosize for this comment - autosize($("#comment-edit-text-" + id + ".text-autosize")); - } - }; - - $(document).bind( "click.commentOpen", handler ); + $("#comment-edit-text-" + id).addClass("comment-edit-text-full").removeClass("comment-edit-text-empty"); + // Choose an arbitrary tab index that's greater than what we're using in jot (3 of them) + // The submit button gets tabindex + 1 + $("#comment-edit-text-" + id).attr('tabindex','9'); + $("#comment-edit-submit-" + id).attr('tabindex','10'); + $("#comment-edit-submit-wrapper-" + id).show(); + // initialize autosize for this comment + autosize($("#comment-edit-text-" + id + ".text-autosize")); } function commentCloseUI(obj, id) { - $(document).unbind( "click.commentClose", handler ); - - var handler = function() { - if (obj.value === '') { - $("#comment-edit-text-" + id).removeClass("comment-edit-text-full").addClass("comment-edit-text-empty"); - $("#comment-edit-text-" + id).removeAttr('tabindex'); - $("#comment-edit-submit-" + id).removeAttr('tabindex'); - $("#comment-edit-submit-wrapper-" + id).hide(); - // destroy the automatic textarea resizing - autosize.destroy($("#comment-edit-text-" + id + ".text-autosize")); - } - }; - - $(document).bind( "click.commentClose", handler ); + if (obj.value === '') { + $("#comment-edit-text-" + id).removeClass("comment-edit-text-full").addClass("comment-edit-text-empty"); + $("#comment-edit-text-" + id).removeAttr('tabindex'); + $("#comment-edit-submit-" + id).removeAttr('tabindex'); + $("#comment-edit-submit-wrapper-" + id).hide(); + // destroy the automatic textarea resizing + autosize.destroy($("#comment-edit-text-" + id + ".text-autosize")); + } } function jotTextOpenUI(obj) { diff --git a/view/theme/frio/js/theme.js b/view/theme/frio/js/theme.js index 8102e7ac9..1695165e6 100644 --- a/view/theme/frio/js/theme.js +++ b/view/theme/frio/js/theme.js @@ -10,7 +10,7 @@ $(document).ready(function(){ $("#back-to-top").fadeOut(); } }); - + // scroll body to 0px on click $("#back-to-top").click(function () { $("body,html").animate({ @@ -54,7 +54,7 @@ $(document).ready(function(){ } // make responsive tabmenu with flexmenu.js - // the menupoints which doesn't fit in the second nav bar will moved to a + // the menupoints which doesn't fit in the second nav bar will moved to a // dropdown menu. Look at common_tabs.tpl $("ul.tabs.flex-nav").flexMenu({ 'cutoff': 2, @@ -82,17 +82,17 @@ $(document).ready(function(){ return false; } }); - + if(checked == true) { $("a#item-delete-selected").fadeTo(400, 1); $("a#item-delete-selected").show(); } else { $("a#item-delete-selected").fadeTo(400, 0, function(){ $("a#item-delete-selected").hide(); - }); + }); } }); - + //$('ul.flex-nav').flexMenu(); // initialize the bootstrap tooltips @@ -128,7 +128,7 @@ $(document).ready(function(){ // append the new heading to the navbar $("#topbar-second > .container > #tabmenu").append(newText); - // try to get the value of the original search input to insert it + // try to get the value of the original search input to insert it // as value in the nav-search-input var searchValue = $("#search-wrapper .form-group-search input").val(); @@ -257,39 +257,6 @@ $(document).ready(function(){ }); }); -//function commentOpenUI(obj, id) { -// $(document).unbind( "click.commentOpen", handler ); -// -// var handler = function() { -// if(obj.value == '{{$comment}}') { -// obj.value = ''; -// $("#comment-edit-text-" + id).addClass("comment-edit-text-full").removeClass("comment-edit-text-empty"); -// // Choose an arbitrary tab index that's greater than what we're using in jot (3 of them) -// // The submit button gets tabindex + 1 -// $("#comment-edit-text-" + id).attr('tabindex','9'); -// $("#comment-edit-submit-" + id).attr('tabindex','10'); -// $("#comment-edit-submit-wrapper-" + id).show(); -// } -// }; -// -// $(document).bind( "click.commentOpen", handler ); -//} -// -//function commentCloseUI(obj, id) { -// $(document).unbind( "click.commentClose", handler ); -// -// var handler = function() { -// if(obj.value === '') { -// obj.value = '{{$comment}}'; -// $("#comment-edit-text-" + id).removeClass("comment-edit-text-full").addClass("comment-edit-text-empty"); -// $("#comment-edit-text-" + id).removeAttr('tabindex'); -// $("#comment-edit-submit-" + id).removeAttr('tabindex'); -// $("#comment-edit-submit-wrapper-" + id).hide(); -// } -// }; -// -// $(document).bind( "click.commentClose", handler ); -//} function openClose(theID) { var elem = document.getElementById(theID); From 531074a72f05e4936ae199bdbb831fe85a790ff4 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 16 Feb 2017 20:03:44 +0000 Subject: [PATCH 09/25] Handle the case when a contact is unknown. --- include/Contact.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/Contact.php b/include/Contact.php index 956e8e291..2aab828f8 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -730,6 +730,10 @@ function posts_from_contact_url(App $a, $contact_url) { $sql = "`item`.`uid` = %d"; } + if (!dbm::is_result($r)) { + return ''; + } + $author_id = intval($r[0]["author-id"]); if (get_config('system', 'old_pager')) { From 03653072a2898adc002f788eba904cd2cf445e97 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 16 Feb 2017 20:23:07 +0000 Subject: [PATCH 10/25] We have to delete spool files after posting in any case --- include/spool_post.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/spool_post.php b/include/spool_post.php index 78384c23a..d2c94881b 100644 --- a/include/spool_post.php +++ b/include/spool_post.php @@ -35,13 +35,19 @@ function spool_post_run($argv, $argc) { continue; } $arr = json_decode(file_get_contents($fullfile), true); + + // If it isn't an array then it is no spool file if (!is_array($arr)) { continue; } - $result = item_store($arr); - if ($result == 0) { + + // Skip if it doesn't seem to be an item array + if (!isset($arr['uid']) AND !isset($arr['uri']) AND !isset($arr['network'])) { continue; } + + $result = item_store($arr); + logger("Spool file ".$file." stored: ".$result, LOGGER_DEBUG); unlink($fullfile); } From 5e46b8315a2e8f26b67a255cfc967a817c0254cb Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Fri, 17 Feb 2017 10:14:38 +0100 Subject: [PATCH 11/25] DE translations --- view/lang/de/messages.po | 8 ++++---- view/lang/de/strings.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/view/lang/de/messages.po b/view/lang/de/messages.po index 665a0f964..a2d3c7ca6 100644 --- a/view/lang/de/messages.po +++ b/view/lang/de/messages.po @@ -28,7 +28,7 @@ # silke m , 2015 # Tobias Diekershoff , 2013-2016 # Tobias Diekershoff , 2011-2013 -# Tobias Diekershoff , 2016 +# Tobias Diekershoff , 2016-2017 # zottel , 2011-2012 # tschlotfeldt , 2011 msgid "" @@ -36,8 +36,8 @@ msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-12-19 07:46+0100\n" -"PO-Revision-Date: 2017-01-02 17:16+0000\n" -"Last-Translator: rabuzarus \n" +"PO-Revision-Date: 2017-02-17 07:07+0000\n" +"Last-Translator: Tobias Diekershoff \n" "Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -4667,7 +4667,7 @@ msgid "" "Shall your connection be bidirectional or not? \"Friend\" implies that you " "allow to read and you subscribe to their posts. \"Sharer\" means that you " "allow to read but you do not want to read theirs. Approve as: " -msgstr "Soll Deine Beziehung beidseitig sein oder nicht? \"Freund\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:" +msgstr "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:" #: mod/notifications.php:209 msgid "Friend" diff --git a/view/lang/de/strings.php b/view/lang/de/strings.php index 4d27608f6..a0dd93da5 100644 --- a/view/lang/de/strings.php +++ b/view/lang/de/strings.php @@ -1066,7 +1066,7 @@ $a->strings["Claims to be known to you: "] = "Behauptet Dich zu kennen: "; $a->strings["yes"] = "ja"; $a->strings["no"] = "nein"; $a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Fan/Admirer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr könnt gegenseitig die Beiträge des Anderen lesen dürft. \"Fan/Verehrer\", dass du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"; -$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Sharer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Freund\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"; +$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Sharer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"; $a->strings["Friend"] = "Kontakt"; $a->strings["Sharer"] = "Teilenden"; $a->strings["Fan/Admirer"] = "Fan/Verehrer"; From 99cfae63d7303365d0c4b2256c7194edb590fb7f Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 17 Feb 2017 22:32:33 -0500 Subject: [PATCH 12/25] Clean trailing whitespaces --- include/ParseUrl.php | 30 +++++++++++++++--------------- include/network.php | 26 +++++++++++++------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/ParseUrl.php b/include/ParseUrl.php index 549d705da..b85175a25 100644 --- a/include/ParseUrl.php +++ b/include/ParseUrl.php @@ -21,13 +21,13 @@ class ParseUrl { /** * @brief Search for chached embeddable data of an url otherwise fetch it - * + * * @param type $url The url of the page which should be scraped * @param type $no_guessing If true the parse doens't search for * preview pictures * @param type $do_oembed The false option is used by the function fetch_oembed() * to avoid endless loops - * + * * @return array which contains needed data for embedding * string 'url' => The url of the parsed page * string 'type' => Content type @@ -37,9 +37,9 @@ class ParseUrl { * if $no_geuessing = false * array'images' = Array of preview pictures * string 'keywords' => The tags which belong to the content - * + * * @see ParseUrl::getSiteinfo() for more information about scraping - * embeddable content + * embeddable content */ public static function getSiteinfoCached($url, $no_guessing = false, $do_oembed = true) { @@ -71,21 +71,21 @@ class ParseUrl { } /** * @brief Parse a page for embeddable content information - * + * * This method parses to url for meta data which can be used to embed * the content. If available it prioritizes Open Graph meta tags. * If this is not available it uses the twitter cards meta tags. * As fallback it uses standard html elements with meta informations * like \Awesome Title\ or * \ - * + * * @param type $url The url of the page which should be scraped * @param type $no_guessing If true the parse doens't search for * preview pictures * @param type $do_oembed The false option is used by the function fetch_oembed() * to avoid endless loops * @param type $count Internal counter to avoid endless loops - * + * * @return array which contains needed data for embedding * string 'url' => The url of the parsed page * string 'type' => Content type @@ -95,13 +95,13 @@ class ParseUrl { * if $no_geuessing = false * array'images' = Array of preview pictures * string 'keywords' => The tags which belong to the content - * + * * @todo https://developers.google.com/+/plugins/snippet/ * @verbatim * * * - * + * * *

Shiny Trinket

* @@ -476,7 +476,7 @@ class ParseUrl { /** * @brief Convert tags from CSV to an array - * + * * @param string $string Tags * @return array with formatted Hashtags */ @@ -492,9 +492,9 @@ class ParseUrl { /** * @brief Add a hasht sign to a string - * + * * This method is used as callback function - * + * * @param string $tag The pure tag name * @param int $k Counter for internal use */ @@ -504,16 +504,16 @@ class ParseUrl { /** * @brief Add a scheme to an url - * + * * The src attribute of some html elements (e.g. images) * can miss the scheme so we need to add the correct * scheme - * + * * @param string $url The url which possibly does have * a missing scheme (a link to an image) * @param string $scheme The url with a correct scheme * (e.g. the url from the webpage which does contain the image) - * + * * @return string The url with a scheme */ private static function completeUrl($url, $scheme) { diff --git a/include/network.php b/include/network.php index b7839de21..7385c94a0 100644 --- a/include/network.php +++ b/include/network.php @@ -11,11 +11,11 @@ require_once('include/Probe.php'); /** * @brief Curl wrapper - * + * * If binary flag is true, return binary results. * Set the cookiejar argument to a string (e.g. "/tmp/friendica-cookies.txt") * to preserve cookies from one request to the next. - * + * * @param string $url URL to fetch * @param boolean $binary default false * TRUE if asked to return binary results (file download) @@ -23,7 +23,7 @@ require_once('include/Probe.php'); * @param integer $timeout Timeout in seconds, default system config value or 60 seconds * @param string $accept_content supply Accept: header with 'accept_content' as the value * @param string $cookiejar Path to cookie jar file - * + * * @return string The fetched content */ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_content=Null, $cookiejar = 0) { @@ -218,13 +218,13 @@ function z_fetch_url($url,$binary = false, &$redirects = 0, $opts=array()) { /** * @brief Post request to $url - * + * * @param string $url URL to post * @param mixed $params * @param string $headers HTTP headers * @param integer $redirects Recursion counter for internal use - default = 0 * @param integer $timeout The timeout in seconds, default system config value or 60 seconds - * + * * @return string The content */ function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0) { @@ -385,10 +385,10 @@ function http_status_exit($val, $description = array()) { /** * @brief Check URL to se if ts's real - * + * * Take a URL from the wild, prepend http:// if necessary * and check DNS to see if it's real (or check if is a valid IP address) - * + * * @param string $url The URL to be validated * @return boolean True if it's a valid URL, fals if something wrong with it */ @@ -415,7 +415,7 @@ function validate_url(&$url) { /** * @brief Checks that email is an actual resolvable internet address - * + * * @param string $addr The email address * @return boolean True if it's a valid email address, false if it's not */ @@ -436,10 +436,10 @@ function validate_email($addr) { /** * @brief Check if URL is allowed - * + * * Check $url against our list of allowed sites, * wildcards allowed. If allowed_sites is unset return true; - * + * * @param string $url URL which get tested * @return boolean True if url is allowed otherwise return false */ @@ -481,9 +481,9 @@ function allowed_url($url) { /** * @brief Check if email address is allowed to register here. - * + * * Compare against our list (wildcards allowed). - * + * * @param type $email * @return boolean False if not allowed, true if allowed * or if allowed list is not configured @@ -821,7 +821,7 @@ function short_link($url) { /** * @brief Encodes content to json - * + * * This function encodes an array to json format * and adds an application/json HTTP header to the output. * After finishing the process is getting killed. From 432587464ce16dff513ed2de340fa3437dbe45aa Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 17 Feb 2017 22:35:46 -0500 Subject: [PATCH 13/25] Fix Diaspora link attachment probe - Move analytics param stripping out of original_url - Remove HEAD curl request in ParseUrl::getSiteInfo - Replace original_url with strip_tracking_query_params in ParseUrl::getSiteInfo to prevent massive curl fest in border cases --- include/ParseUrl.php | 26 ++--------------------- include/network.php | 49 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/include/ParseUrl.php b/include/ParseUrl.php index b85175a25..3a2fe9d53 100644 --- a/include/ParseUrl.php +++ b/include/ParseUrl.php @@ -130,7 +130,7 @@ class ParseUrl { $url = trim($url, "'"); $url = trim($url, '"'); - $url = original_url($url); + $url = strip_tracking_query_params($url); $siteinfo["url"] = $url; $siteinfo["type"] = "link"; @@ -142,8 +142,7 @@ class ParseUrl { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); - curl_setopt($ch, CURLOPT_NOBODY, 1); - curl_setopt($ch, CURLOPT_TIMEOUT, 3); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent()); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); @@ -151,7 +150,6 @@ class ParseUrl { $header = curl_exec($ch); $curl_info = @curl_getinfo($ch); - $http_code = $curl_info["http_code"]; curl_close($ch); $a->save_timestamp($stamp1, "network"); @@ -197,26 +195,6 @@ class ParseUrl { } } - $stamp1 = microtime(true); - - // Now fetch the body as well - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_HEADER, 1); - curl_setopt($ch, CURLOPT_NOBODY, 0); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent()); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false)); - - $header = curl_exec($ch); - $curl_info = @curl_getinfo($ch); - $http_code = $curl_info["http_code"]; - curl_close($ch); - - $a->save_timestamp($stamp1, "network"); - // Fetch the first mentioned charset. Can be in body or header $charset = ""; if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches)) { diff --git a/include/network.php b/include/network.php index 7385c94a0..ecbe0e5c6 100644 --- a/include/network.php +++ b/include/network.php @@ -670,42 +670,69 @@ function fix_contact_ssl_policy(&$contact,$new_policy) { } } -function original_url($url, $depth=1, $fetchbody = false) { - - $a = get_app(); - - // Remove Analytics Data from Google and other tracking platforms +/** + * @brief Remove Google Analytics and other tracking platforms params from URL + * + * @param string $url + * @return string + */ +function strip_tracking_query_params($url) +{ $urldata = parse_url($url); if (is_string($urldata["query"])) { $query = $urldata["query"]; parse_str($query, $querydata); - if (is_array($querydata)) - foreach ($querydata AS $param=>$value) + if (is_array($querydata)) { + foreach ($querydata AS $param => $value) { if (in_array($param, array("utm_source", "utm_medium", "utm_term", "utm_content", "utm_campaign", "wt_mc", "pk_campaign", "pk_kwd", "mc_cid", "mc_eid", "fb_action_ids", "fb_action_types", "fb_ref", "awesm", "wtrid", "woo_campaign", "woo_source", "woo_medium", "woo_content", "woo_term"))) { - $pair = $param."=".urlencode($value); + $pair = $param . "=" . urlencode($value); $url = str_replace($pair, "", $url); // Second try: if the url isn't encoded completely - $pair = $param."=".str_replace(" ", "+", $value); + $pair = $param . "=" . str_replace(" ", "+", $value); $url = str_replace($pair, "", $url); // Third try: Maybey the url isn't encoded at all - $pair = $param."=".$value; + $pair = $param . "=" . $value; $url = str_replace($pair, "", $url); $url = str_replace(array("?&", "&&"), array("?", ""), $url); } + } + } - if (substr($url, -1, 1) == "?") + if (substr($url, -1, 1) == "?") { $url = substr($url, 0, -1); + } } + return $url; +} + +/** + * @brief Returns the original URL of the provided URL + * + * This function strips tracking query params and follows redirections, either + * through HTTP code or meta refresh tags. Stops after 10 redirections. + * + * @see ParseUrl::getSiteinfo + * + * @param string $url + * @param int $depth + * @param bool $fetchbody + * @return string + */ +function original_url($url, $depth = 1, $fetchbody = false) { + $a = get_app(); + + $url = strip_tracking_query_params($url); + if ($depth > 10) return($url); From 2c959b925d20898579d4562d8d42669682de0957 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 18 Feb 2017 20:35:31 -0500 Subject: [PATCH 14/25] Add param documentation --- include/network.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/network.php b/include/network.php index ecbe0e5c6..727d5e57e 100644 --- a/include/network.php +++ b/include/network.php @@ -673,8 +673,8 @@ function fix_contact_ssl_policy(&$contact,$new_policy) { /** * @brief Remove Google Analytics and other tracking platforms params from URL * - * @param string $url - * @return string + * @param string $url Any user-submitted URL that may contain tracking params + * @return string The same URL stripped of tracking parameters */ function strip_tracking_query_params($url) { From 58a444b4305bd8a1c2ab7ee172c3972e091cc964 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 18 Feb 2017 20:39:16 -0500 Subject: [PATCH 15/25] Add original_url() param documentation --- include/network.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/network.php b/include/network.php index 727d5e57e..03f65a519 100644 --- a/include/network.php +++ b/include/network.php @@ -721,12 +721,14 @@ function strip_tracking_query_params($url) * This function strips tracking query params and follows redirections, either * through HTTP code or meta refresh tags. Stops after 10 redirections. * + * @todo Remove the $fetchbody parameter that generates an extraneous HEAD request + * * @see ParseUrl::getSiteinfo * - * @param string $url - * @param int $depth - * @param bool $fetchbody - * @return string + * @param string $url A user-submitted URL + * @param int $depth The current redirection recursion level (internal) + * @param bool $fetchbody Wether to fetch the body or not after the HEAD requests + * @return string A canonical URL */ function original_url($url, $depth = 1, $fetchbody = false) { $a = get_app(); From 2bfc40d74cf67c68ced8c0b90b4667c46fdf583e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 19 Feb 2017 08:23:21 +0000 Subject: [PATCH 16/25] Bugfix for not createable spool path --- boot.php | 71 ++++++++++++++++++++++++++++-------------- include/items.php | 4 ++- include/spool_post.php | 14 +++++++++ 3 files changed, 65 insertions(+), 24 deletions(-) diff --git a/boot.php b/boot.php index 504a524ed..b8e926707 100644 --- a/boot.php +++ b/boot.php @@ -1457,7 +1457,7 @@ class App { return false; } if (!is_writable($directory)) { - logger('Path "'.$temppath.'" is not writable for user '.self::systemuser(), LOGGER_DEBUG); + logger('Path "'.$directory.'" is not writable for user '.self::systemuser(), LOGGER_DEBUG); return false; } return true; @@ -2367,7 +2367,7 @@ function get_itemcachepath() { $itemcache = get_config('system','itemcache'); if (($itemcache != "") AND App::directory_usable($itemcache)) { - return($itemcache); + return $itemcache; } $temppath = get_temppath(); @@ -2380,7 +2380,7 @@ function get_itemcachepath() { if (App::directory_usable($itemcache)) { set_config("system", "itemcache", $itemcache); - return($itemcache); + return $itemcache; } } return ""; @@ -2389,25 +2389,32 @@ function get_itemcachepath() { function get_lockpath() { $lockpath = get_config('system','lockpath'); if (($lockpath != "") AND App::directory_usable($lockpath)) { - return($lockpath); + // We have a lock path and it is usable + return $lockpath; } + // We don't have a working preconfigured lock path, so we take the temp path. $temppath = get_temppath(); if ($temppath != "") { + // To avoid any interferences with other systems we create our own directory $lockpath = $temppath."/lock"; - if (!is_dir($lockpath)) { mkdir($lockpath); - } elseif (!App::directory_usable($lockpath)) { - $lockpath = $temppath; } if (App::directory_usable($lockpath)) { + // The new path is usable, we are happy set_config("system", "lockpath", $lockpath); - return($lockpath); + return $lockpath; + } else { + // We can't create a subdirectory, strange. + // But the directory seems to work, so we use it but don't store it. + return $temppath; } } + + // Reaching this point means that the operating system is configured badly. return ""; } @@ -2419,50 +2426,68 @@ function get_lockpath() { function get_spoolpath() { $spoolpath = get_config('system','spoolpath'); if (($spoolpath != "") AND App::directory_usable($spoolpath)) { - return($spoolpath); + // We have a spool path and it is usable + return $spoolpath; } + // We don't have a working preconfigured spool path, so we take the temp path. $temppath = get_temppath(); if ($temppath != "") { + // To avoid any interferences with other systems we create our own directory $spoolpath = $temppath."/spool"; - if (!is_dir($spoolpath)) { mkdir($spoolpath); - } elseif (!App::directory_usable($spoolpath)) { - $spoolpath = $temppath; } if (App::directory_usable($spoolpath)) { + // The new path is usable, we are happy set_config("system", "spoolpath", $spoolpath); - return($spoolpath); + return $spoolpath; + } else { + // We can't create a subdirectory, strange. + // But the directory seems to work, so we use it but don't store it. + return $temppath; } } + + // Reaching this point means that the operating system is configured badly. return ""; } function get_temppath() { $a = get_app(); - $temppath = get_config("system","temppath"); + $temppath = get_config("system", "temppath"); if (($temppath != "") AND App::directory_usable($temppath)) { - return($temppath); + // We have a temp path and it is usable + return $temppath; } + // We don't have a working preconfigured temp path, so we take the system path. $temppath = sys_get_temp_dir(); - if (($temppath != "") AND App::directory_usable($temppath)) { - $temppath .= "/".$a->get_hostname(); - if (!is_dir($temppath)) - mkdir($temppath); - if (App::directory_usable($temppath)) { - set_config("system", "temppath", $temppath); - return($temppath); + // Check if it is usable + if (($temppath != "") AND App::directory_usable($temppath)) { + // To avoid any interferences with other systems we create our own directory + $new_temppath .= "/".$a->get_hostname(); + if (!is_dir($new_temppath)) + mkdir($new_temppath); + + if (App::directory_usable($new_temppath)) { + // The new path is usable, we are happy + set_config("system", "temppath", $new_temppath); + return $new_temppath; + } else { + // We can't create a subdirectory, strange. + // But the directory seems to work, so we use it but don't store it. + return $temppath; } } - return(""); + // Reaching this point means that the operating system is configured badly. + return ''; } /// @deprecated diff --git a/include/items.php b/include/items.php index 2b6fb9a1f..1e38e3fdb 100644 --- a/include/items.php +++ b/include/items.php @@ -857,7 +857,9 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa } // Now we store the data in the spool directory - $file = 'item-'.round(microtime(true) * 10000).".msg"; + // We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates + $file = 'item-'.round(microtime(true) * 10000).'-'.mt_rand().'.msg'; + $spool = get_spoolpath().'/'.$file; file_put_contents($spool, json_encode($arr)); logger("Item wasn't stored - Item was spooled into file ".$file, LOGGER_DEBUG); diff --git a/include/spool_post.php b/include/spool_post.php index d2c94881b..36bcab2a5 100644 --- a/include/spool_post.php +++ b/include/spool_post.php @@ -30,10 +30,24 @@ function spool_post_run($argv, $argc) { if (is_writable($path)){ if ($dh = opendir($path)) { while (($file = readdir($dh)) !== false) { + + // It is not named like a spool file, so we don't care. + if (substr($file, 0, 5) != "item-") { + continue; + } + $fullfile = $path."/".$file; + + // We don't care about directories either if (filetype($fullfile) != "file") { continue; } + + // We can't read or write the file? So we don't care about it. + if (!is_writable($fullfile) OR !is_readable($fullfile)) { + continue; + } + $arr = json_decode(file_get_contents($fullfile), true); // If it isn't an array then it is no spool file From 9251d2af6fe855fa14adaf87c05037e5ec5efc99 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 19 Feb 2017 10:13:40 +0000 Subject: [PATCH 17/25] Ensure that the spool path is set --- include/items.php | 9 ++++++--- include/spool_post.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/items.php b/include/items.php index 1e38e3fdb..24eb1b30f 100644 --- a/include/items.php +++ b/include/items.php @@ -860,9 +860,12 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa // We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates $file = 'item-'.round(microtime(true) * 10000).'-'.mt_rand().'.msg'; - $spool = get_spoolpath().'/'.$file; - file_put_contents($spool, json_encode($arr)); - logger("Item wasn't stored - Item was spooled into file ".$file, LOGGER_DEBUG); + $spoolpath = get_spoolpath(); + if ($spoolpath != "") { + $spool = $spoolpath.'/'.$file; + file_put_contents($spool, json_encode($arr)); + logger("Item wasn't stored - Item was spooled into file ".$file, LOGGER_DEBUG); + } return 0; } diff --git a/include/spool_post.php b/include/spool_post.php index 36bcab2a5..b4cce46b5 100644 --- a/include/spool_post.php +++ b/include/spool_post.php @@ -27,7 +27,7 @@ function spool_post_run($argv, $argc) { $path = get_spoolpath(); - if (is_writable($path)){ + if (($path != '') AND is_writable($path)){ if ($dh = opendir($path)) { while (($file = readdir($dh)) !== false) { From a32431e69350d94c73cbc473634d9aa329fb7f56 Mon Sep 17 00:00:00 2001 From: Eelco Maljaars Date: Sun, 19 Feb 2017 15:44:48 +0100 Subject: [PATCH 18/25] Added missing mbstring php module to xenial setup in vagrant --- util/vagrant_provision.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/vagrant_provision.sh b/util/vagrant_provision.sh index 100764cab..6b7f0b862 100644 --- a/util/vagrant_provision.sh +++ b/util/vagrant_provision.sh @@ -51,7 +51,7 @@ if [ $( lsb_release -c | cut -f 2 ) == "trusty" ]; then sudo service apache2 restart elif [ $( lsb_release -c | cut -f 2 ) == "xenial" ]; then echo ">>> Installing PHP7" - sudo apt-get install -y php libapache2-mod-php php-cli php-mysql php-curl php-gd + sudo apt-get install -y php libapache2-mod-php php-cli php-mysql php-curl php-gd php-mbstring sudo apt-get install -y imagemagick sudo apt-get install -y php-imagick sudo systemctl restart apache2 From 36265d984e9d2eaafe34f1bdada5ef860c483f56 Mon Sep 17 00:00:00 2001 From: Eelco Maljaars Date: Sun, 19 Feb 2017 15:53:29 +0100 Subject: [PATCH 19/25] Ran into an installation problem today that is linked to newer MySQL builds This commit expands the INSTALL.txt with notes when this problem arises and how it should be handled. In the end the database code should probably be fixed but this should help in the short term. --- INSTALL.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/INSTALL.txt b/INSTALL.txt index a9d42495b..a96c9fd5a 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -64,7 +64,7 @@ you wish to communicate with the Diaspora network. password, database name). - Friendica needs the permission to create and delete fields and tables in its own database. - + - Please check the additional notes if running on MySQ 5.7.17 or newer 4. If you know in advance that it will be impossible for the web server to write or create files in your web directory, create an empty file called @@ -291,3 +291,21 @@ This is obvious as soon as you notice that the friendica-cron uses proc_open to execute php-scripts that also use proc_open, but it took me quite some time to find that out. I hope this saves some time for other people using suhosin with function blacklists. + +######################################################################## +Unable to create alle mysql tables on MySQL 5.7.17 or newer +####################################################################### + +If the setup fails to create all the database tables and/or manual +creation from the command line failes, with this error : + +ERROR 1067 (42000) at line XX: Invalid default value for 'created' + +You need to adjust your my.cnf and add the following setting under +the [mysqld] setion : + +sql_mode = ''; + +After that, restart mysql and try again. + + From 38aea0aeacbc85ad4b1e561a123af240fe6e4b29 Mon Sep 17 00:00:00 2001 From: Eelco Maljaars Date: Sun, 19 Feb 2017 16:36:40 +0100 Subject: [PATCH 20/25] Typos fixed --- INSTALL.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index a96c9fd5a..4c57064f6 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -293,16 +293,16 @@ find that out. I hope this saves some time for other people using suhosin with function blacklists. ######################################################################## -Unable to create alle mysql tables on MySQL 5.7.17 or newer +Unable to create all mysql tables on MySQL 5.7.17 or newer ####################################################################### If the setup fails to create all the database tables and/or manual -creation from the command line failes, with this error : +creation from the command line fails, with this error: ERROR 1067 (42000) at line XX: Invalid default value for 'created' You need to adjust your my.cnf and add the following setting under -the [mysqld] setion : +the [mysqld] section : sql_mode = ''; From cec79ddf2bb9dc01c70dbad97b3efedaf9ecb139 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 21 Feb 2017 05:23:37 +0000 Subject: [PATCH 21/25] See issue 3157: Fulltext is now disabled --- mod/network.php | 7 ++++--- mod/search.php | 9 +++++---- view/templates/admin_site.tpl | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mod/network.php b/mod/network.php index ad0347ba0..23cf098b6 100644 --- a/mod/network.php +++ b/mod/network.php @@ -574,9 +574,10 @@ function network_content(App $a, $update = 0) { $sql_order = "`item`.`id`"; $order_mode = "id"; } else { - if (get_config('system','use_fulltext_engine')) - $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); - else + // Disabled until final decision what to do with this + //if (get_config('system','use_fulltext_engine')) + // $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); + //else $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); $sql_order = "`item`.`id`"; $order_mode = "id"; diff --git a/mod/search.php b/mod/search.php index df604e367..7d588aa4d 100644 --- a/mod/search.php +++ b/mod/search.php @@ -203,11 +203,12 @@ function search_content(App $a) { } else { logger("Start fulltext search for '".$search."'", LOGGER_DEBUG); - if (get_config('system','use_fulltext_engine')) { - $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); - } else { + // Disabled until finally is decided how to proceed with this + //if (get_config('system','use_fulltext_engine')) { + // $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); + //} else { $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); - } + //} $r = q("SELECT %s FROM `item` %s diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index 531614932..2edfddb88 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -147,7 +147,7 @@

{{$performance}}

- {{include file="field_checkbox.tpl" field=$use_fulltext_engine}} + {{include file="field_checkbox.tpl" field=$only_tag_search}} {{include file="field_input.tpl" field=$itemcache}} {{include file="field_input.tpl" field=$itemcache_duration}} From 32660b64a751cab1d3c3ea260adeb59cae40c359 Mon Sep 17 00:00:00 2001 From: Eelco Maljaars Date: Tue, 21 Feb 2017 15:59:12 +0100 Subject: [PATCH 22/25] Added note about MySQL sql_mode on newer versions of MySQL --- doc/Install.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/Install.md b/doc/Install.md index e494c1edf..168468df0 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -69,6 +69,16 @@ Create an empty database and note the access details (hostname, username, passwo Friendica needs the permission to create and delete fields and tables in its own database. +With newer releases of MySQL (5.7.17 or newer), you might need to set the sql_mode +to '' (blank). Use this setting when the installer is unable to create all the needed +tables due to a timestamp format problem. In this case find the [mysqld] section +in your my.cnf file and add the line : + +sql_mode = '' + +Restart mysql and you should be fine. + + ###Run the installer Point your web browser to the new site and follow the instructions. From d9d4a0ccc44f5d8914692ccf49cb5f2d8869c060 Mon Sep 17 00:00:00 2001 From: Eelco Maljaars Date: Tue, 21 Feb 2017 19:32:03 +0100 Subject: [PATCH 23/25] Document reformat as requested - 1 sentence per line --- doc/Install.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/Install.md b/doc/Install.md index 168468df0..6c4d79287 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -69,10 +69,9 @@ Create an empty database and note the access details (hostname, username, passwo Friendica needs the permission to create and delete fields and tables in its own database. -With newer releases of MySQL (5.7.17 or newer), you might need to set the sql_mode -to '' (blank). Use this setting when the installer is unable to create all the needed -tables due to a timestamp format problem. In this case find the [mysqld] section -in your my.cnf file and add the line : +With newer releases of MySQL (5.7.17 or newer), you might need to set the sql_mode to '' (blank). +Use this setting when the installer is unable to create all the needed tables due to a timestamp format problem. +In this case find the [mysqld] section in your my.cnf file and add the line : sql_mode = '' From 79c2234cc19265d27c440d59b647831c30473d32 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 22 Feb 2017 07:21:36 +0100 Subject: [PATCH 24/25] EN quickstart had some dead links in it, DE version is ok --- doc/Quick-Start-andfinally.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/doc/Quick-Start-andfinally.md b/doc/Quick-Start-andfinally.md index 97afd8140..e76eb7278 100644 --- a/doc/Quick-Start-andfinally.md +++ b/doc/Quick-Start-andfinally.md @@ -5,17 +5,8 @@ Here are some more things to help get you started: **Groups** -- New Here - a group for people new to Friendica - - Friendica Support - problems? This is the place to ask. -- Public Stream - a place to talk about anything to anyone. - -- Let's Talk a group for finding people and groups who share similar interests. - -- Local Friendica a page for local Friendica groups - - **Documentation** - Connecting to more networks From 4de6ef1610b62b58183621d3b49c64f1b1106dd0 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 22 Feb 2017 09:37:00 +0100 Subject: [PATCH 25/25] make it a code block --- doc/Install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Install.md b/doc/Install.md index 6c4d79287..9a194254a 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -73,7 +73,7 @@ With newer releases of MySQL (5.7.17 or newer), you might need to set the sql_mo Use this setting when the installer is unable to create all the needed tables due to a timestamp format problem. In this case find the [mysqld] section in your my.cnf file and add the line : -sql_mode = '' + sql_mode = '' Restart mysql and you should be fine.