From d99a96ef4979e9c5840f7a7534f8c327434e5cb9 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Mon, 30 Jan 2017 00:55:38 +0000 Subject: [PATCH 01/41] Global is an integer, do not set it to an empty string --- include/bbcode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bbcode.php b/include/bbcode.php index 74dde2fdf4..ab928bf12f 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1164,7 +1164,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal $Text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&\;(.*?)\>/ism', '<$1$2=$3&$4>', $Text); // sanitizes src attributes (only relative redir URIs or http URLs) - $Text = preg_replace('#<([^>]*?)(src)="(?!http|redir)(.*?)"(.*?)>#ism', '<$1$2=""$4 class="invalid-src" title="' . t('Invalid source protocol') . '">', $Text); + $Text = preg_replace('#<([^>]*?)(src)="(?!http|redir|cid)(.*?)"(.*?)>#ism', '<$1$2=""$4 class="invalid-src" title="' . t('Invalid source protocol') . '">', $Text); // sanitize href attributes (only whitelisted protocols URLs) // default value for backward compatibility From ce10a9aa7f97424caa3f2db5d5fd54a2da850ca3 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Mon, 30 Jan 2017 15:48:12 +0000 Subject: [PATCH 02/41] Break out list of acceptable protocols in "src" attribute into separate variable similar to "href" attributes --- include/bbcode.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/bbcode.php b/include/bbcode.php index ab928bf12f..0f1a705faa 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1163,8 +1163,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal // fix any escaped ampersands that may have been converted into links $Text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&\;(.*?)\>/ism', '<$1$2=$3&$4>', $Text); - // sanitizes src attributes (only relative redir URIs or http URLs) - $Text = preg_replace('#<([^>]*?)(src)="(?!http|redir|cid)(.*?)"(.*?)>#ism', '<$1$2=""$4 class="invalid-src" title="' . t('Invalid source protocol') . '">', $Text); + // sanitizes src attributes (http and redir URLs for displaying in a web page, cid used for inline images in emails) + $allowed_src_protocols = array('http', 'redir', 'cid'); + $Text = preg_replace('#<([^>]*?)(src)="(?!' . implode('|', $allowed_src_protocols) . ')(.*?)"(.*?)>#ism', + '<$1$2=""$4 class="invalid-src" title="' . t('Invalid source protocol') . '">', $Text); // sanitize href attributes (only whitelisted protocols URLs) // default value for backward compatibility From 96aadb23f8beb2b0ae453d9f4ba6bf9fc86ba1cd Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Tue, 31 Jan 2017 03:44:32 +0000 Subject: [PATCH 03/41] Change $allowed_src_protocols to static --- include/bbcode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bbcode.php b/include/bbcode.php index 0f1a705faa..489ef8b2e3 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1164,7 +1164,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal $Text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&\;(.*?)\>/ism', '<$1$2=$3&$4>', $Text); // sanitizes src attributes (http and redir URLs for displaying in a web page, cid used for inline images in emails) - $allowed_src_protocols = array('http', 'redir', 'cid'); + static $allowed_src_protocols = array('http', 'redir', 'cid'); $Text = preg_replace('#<([^>]*?)(src)="(?!' . implode('|', $allowed_src_protocols) . ')(.*?)"(.*?)>#ism', '<$1$2=""$4 class="invalid-src" title="' . t('Invalid source protocol') . '">', $Text); From 2424cb78d1abc9e0527f68b90b03556b1fb61cd5 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 31 Jan 2017 19:39:09 +0000 Subject: [PATCH 04/41] Only process feed and dfrn items when they aren't already stored --- include/dfrn.php | 60 ++++++++++++++++++++++++++-------------------- include/feed.php | 42 ++++++++++++++++---------------- include/poller.php | 10 ++++++++ 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/include/dfrn.php b/include/dfrn.php index 702fbb15fe..903db9b601 100644 --- a/include/dfrn.php +++ b/include/dfrn.php @@ -391,7 +391,7 @@ class dfrn { * * @return object XML root object */ - private function add_header($doc, $owner, $authorelement, $alternatelink = "", $public = false) { + private static function add_header($doc, $owner, $authorelement, $alternatelink = "", $public = false) { if ($alternatelink == "") $alternatelink = $owner['url']; @@ -462,7 +462,7 @@ class dfrn { * * @return object XML author object */ - private function add_author($doc, $owner, $authorelement, $public) { + private static function add_author($doc, $owner, $authorelement, $public) { // Is the profile hidden or shouldn't be published in the net? Then add the "hide" element $r = q("SELECT `id` FROM `profile` INNER JOIN `user` ON `user`.`uid` = `profile`.`uid` @@ -591,7 +591,7 @@ class dfrn { * * @return object XML author object */ - private function add_entry_author($doc, $element, $contact_url, $item) { + private static function add_entry_author($doc, $element, $contact_url, $item) { $contact = get_contact_details_by_url($contact_url, $item["uid"]); @@ -631,7 +631,7 @@ class dfrn { * * @return object XML activity object */ - private function create_activity($doc, $element, $activity) { + private static function create_activity($doc, $element, $activity) { if($activity) { $entry = $doc->createElement($element); @@ -685,7 +685,7 @@ class dfrn { * * @return object XML attachment object */ - private function get_attachment($doc, $root, $item) { + private static function get_attachment($doc, $root, $item) { $arr = explode('[/attach],',$item['attach']); if(count($arr)) { foreach($arr as $r) { @@ -720,7 +720,7 @@ class dfrn { * * @return object XML entry object */ - private function entry($doc, $type, $item, $owner, $comment = false, $cid = 0) { + private static function entry($doc, $type, $item, $owner, $comment = false, $cid = 0) { $mentioned = array(); @@ -1103,7 +1103,7 @@ class dfrn { * @param string $birthday Birthday of the contact * */ - private function birthday_event($contact, $birthday) { + private static function birthday_event($contact, $birthday) { // Check for duplicates $r = q("SELECT `id` FROM `event` WHERE `uid` = %d AND `cid` = %d AND `start` = '%s' AND `type` = '%s' LIMIT 1", @@ -1146,7 +1146,7 @@ class dfrn { * * @return Returns an array with relevant data of the author */ - private function fetchauthor($xpath, $context, $importer, $element, $onlyfetch, $xml = "") { + private static function fetchauthor($xpath, $context, $importer, $element, $onlyfetch, $xml = "") { $author = array(); $author["name"] = $xpath->evaluate($element."/atom:name/text()", $context)->item(0)->nodeValue; @@ -1358,7 +1358,7 @@ class dfrn { * * @return string XML string */ - private function transform_activity($xpath, $activity, $element) { + private static function transform_activity($xpath, $activity, $element) { if (!is_object($activity)) return ""; @@ -1403,7 +1403,7 @@ class dfrn { * @param object $mail mail elements * @param array $importer Record of the importer user mixed with contact of the content */ - private function process_mail($xpath, $mail, $importer) { + private static function process_mail($xpath, $mail, $importer) { logger("Processing mails"); @@ -1454,7 +1454,7 @@ class dfrn { * @param object $suggestion suggestion elements * @param array $importer Record of the importer user mixed with contact of the content */ - private function process_suggestion($xpath, $suggestion, $importer) { + private static function process_suggestion($xpath, $suggestion, $importer) { $a = get_app(); logger("Processing suggestions"); @@ -1556,7 +1556,7 @@ class dfrn { * @param object $relocation relocation elements * @param array $importer Record of the importer user mixed with contact of the content */ - private function process_relocation($xpath, $relocation, $importer) { + private static function process_relocation($xpath, $relocation, $importer) { logger("Processing relocations"); @@ -1685,7 +1685,7 @@ class dfrn { * @param array $importer Record of the importer user mixed with contact of the content * @param int $entrytype Is it a toplevel entry, a comment or a relayed comment? */ - private function update_content($current, $item, $importer, $entrytype) { + private static function update_content($current, $item, $importer, $entrytype) { $changed = false; if (edited_timestamp_is_newer($current, $item)) { @@ -1737,7 +1737,7 @@ class dfrn { * * @return int Is it a toplevel entry, a comment or a relayed comment? */ - private function get_entry_type($importer, $item) { + private static function get_entry_type($importer, $item) { if ($item["parent-uri"] != $item["uri"]) { $community = false; @@ -1803,7 +1803,7 @@ class dfrn { * @param array $importer Record of the importer user mixed with contact of the content * @param int $posted_id The record number of item record that was just posted */ - private function do_poke($item, $importer, $posted_id) { + private static function do_poke($item, $importer, $posted_id) { $verb = urldecode(substr($item["verb"],strpos($item["verb"], "#")+1)); if(!$verb) return; @@ -1858,7 +1858,7 @@ class dfrn { * * @return bool Should the processing of the entries be continued? */ - private function process_verbs($entrytype, $importer, &$item, &$is_like) { + private static function process_verbs($entrytype, $importer, &$item, &$is_like) { logger("Process verb ".$item["verb"]." and object-type ".$item["object-type"]." for entrytype ".$entrytype, LOGGER_DEBUG); @@ -1958,7 +1958,7 @@ class dfrn { * @param object $links link elements * @param array $item the item record */ - private function parse_links($links, &$item) { + private static function parse_links($links, &$item) { $rel = ""; $href = ""; $type = ""; @@ -2001,7 +2001,7 @@ class dfrn { * @param object $entry entry elements * @param array $importer Record of the importer user mixed with contact of the content */ - private function process_entry($header, $xpath, $entry, $importer) { + private static function process_entry($header, $xpath, $entry, $importer) { logger("Processing entries"); @@ -2010,6 +2010,20 @@ class dfrn { // Get the uri $item["uri"] = $xpath->query("atom:id/text()", $entry)->item(0)->nodeValue; + $item["edited"] = $xpath->query("atom:updated/text()", $entry)->item(0)->nodeValue; + + $current = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", + dbesc($item["uri"]), + intval($importer["importer_uid"]) + ); + + // Is there an existing item? + if (dbm::is_result($current) AND edited_timestamp_is_newer($current[0], $item) AND + (datetime_convert("UTC","UTC",$item["edited"]) < $current[0]["edited"])) { + logger("Item ".$item["uri"]." already existed.", LOGGER_DEBUG); + return; + } + // Fetch the owner $owner = self::fetchauthor($xpath, $entry, $importer, "dfrn:owner", true); @@ -2027,7 +2041,6 @@ class dfrn { $item["title"] = $xpath->query("atom:title/text()", $entry)->item(0)->nodeValue; $item["created"] = $xpath->query("atom:published/text()", $entry)->item(0)->nodeValue; - $item["edited"] = $xpath->query("atom:updated/text()", $entry)->item(0)->nodeValue; $item["body"] = $xpath->query("dfrn:env/text()", $entry)->item(0)->nodeValue; $item["body"] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$item["body"]); @@ -2215,18 +2228,13 @@ class dfrn { } } - $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", - dbesc($item["uri"]), - intval($importer["importer_uid"]) - ); - if (!self::process_verbs($entrytype, $importer, $item, $is_like)) { logger("Exiting because 'process_verbs' told us so", LOGGER_DEBUG); return; } // Update content if 'updated' changes - if (dbm::is_result($r)) { + if (dbm::is_result($current)) { if (self::update_content($r[0], $item, $importer, $entrytype)) logger("Item ".$item["uri"]." was updated.", LOGGER_DEBUG); else @@ -2311,7 +2319,7 @@ class dfrn { * @param object $deletion deletion elements * @param array $importer Record of the importer user mixed with contact of the content */ - private function process_deletion($xpath, $deletion, $importer) { + private static function process_deletion($xpath, $deletion, $importer) { logger("Processing deletions"); diff --git a/include/feed.php b/include/feed.php index 579ff7caae..e0fef50dbb 100644 --- a/include/feed.php +++ b/include/feed.php @@ -177,18 +177,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) { foreach (array_reverse($entrylist) AS $entry) { $item = array_merge($header, $author); - $item["title"] = $xpath->evaluate('atom:title/text()', $entry)->item(0)->nodeValue; - - if ($item["title"] == "") - $item["title"] = $xpath->evaluate('title/text()', $entry)->item(0)->nodeValue; - - if ($item["title"] == "") - $item["title"] = $xpath->evaluate('rss:title/text()', $entry)->item(0)->nodeValue; - - $alternate = $xpath->query("atom:link[@rel='alternate']", $entry)->item(0)->attributes; - if (!is_object($alternate)) - $alternate = $xpath->query("atom:link", $entry)->item(0)->attributes; - if (is_object($alternate)) foreach($alternate AS $attributes) if ($attributes->name == "href") @@ -212,6 +200,27 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) { $item["parent-uri"] = $item["uri"]; + if (!$simulate) { + $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `network` IN ('%s', '%s')", + intval($importer["uid"]), dbesc($item["uri"]), dbesc(NETWORK_FEED), dbesc(NETWORK_DFRN)); + if ($r) { + logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG); + continue; + } + } + + $item["title"] = $xpath->evaluate('atom:title/text()', $entry)->item(0)->nodeValue; + + if ($item["title"] == "") + $item["title"] = $xpath->evaluate('title/text()', $entry)->item(0)->nodeValue; + + if ($item["title"] == "") + $item["title"] = $xpath->evaluate('rss:title/text()', $entry)->item(0)->nodeValue; + + $alternate = $xpath->query("atom:link[@rel='alternate']", $entry)->item(0)->attributes; + if (!is_object($alternate)) + $alternate = $xpath->query("atom:link", $entry)->item(0)->attributes; + $published = $xpath->query('atom:published/text()', $entry)->item(0)->nodeValue; if ($published == "") @@ -250,15 +259,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) { if ($creator != "") $item["author-name"] = $creator; - if (!$simulate) { - $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `network` IN ('%s', '%s')", - intval($importer["uid"]), dbesc($item["uri"]), dbesc(NETWORK_FEED), dbesc(NETWORK_DFRN)); - if ($r) { - logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG); - continue; - } - } - /// @TODO ? // Ausland // diff --git a/include/poller.php b/include/poller.php index e8bfb88389..16198580f3 100644 --- a/include/poller.php +++ b/include/poller.php @@ -206,6 +206,16 @@ function poller_exec_function($queue, $funcname, $argv) { $duration = number_format(microtime(true) - $stamp, 3); + if ($duration > 3600) { + logger("Prio ".$queue["priority"].": ".$queue["parameter"]." - longer than 1 hour (".round($duration/60, 3).")", LOGGER_DEBUG); + } elseif ($duration > 600) { + logger("Prio ".$queue["priority"].": ".$queue["parameter"]." - longer than 10 minutes (".round($duration/60, 3).")", LOGGER_DEBUG); + } elseif ($duration > 300) { + logger("Prio ".$queue["priority"].": ".$queue["parameter"]." - longer than 5 minutes (".round($duration/60, 3).")", LOGGER_DEBUG); + } elseif ($duration > 120) { + logger("Prio ".$queue["priority"].": ".$queue["parameter"]." - longer than 2 minutes (".round($duration/60, 3).")", LOGGER_DEBUG); + } + logger("Process ".$mypid." - Prio ".$queue["priority"]." - ID ".$queue["id"].": ".$funcname." - done in ".$duration." seconds."); // Write down the performance values into the log From 7324a661f1e6fdf6320b5a4846980b7493254617 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 1 Feb 2017 00:15:37 +0000 Subject: [PATCH 05/41] Optimized timeouts during network operations --- include/dfrn.php | 8 +- include/network.php | 2 + include/onepoll.php | 211 ++++++++++++++++++++++++------------------- include/socgraph.php | 22 ++++- 4 files changed, 148 insertions(+), 95 deletions(-) diff --git a/include/dfrn.php b/include/dfrn.php index 903db9b601..fbf6aea561 100644 --- a/include/dfrn.php +++ b/include/dfrn.php @@ -913,7 +913,13 @@ class dfrn { logger('dfrn_deliver: ' . $url); - $xml = fetch_url($url); + $ret = z_fetch_url($url); + + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return(-1); // timed out + } + + $xml = $ret['body']; $curl_stat = $a->get_curl_code(); if(! $curl_stat) diff --git a/include/network.php b/include/network.php index b7839de218..60b05bc774 100644 --- a/include/network.php +++ b/include/network.php @@ -141,6 +141,8 @@ function z_fetch_url($url,$binary = false, &$redirects = 0, $opts=array()) { logger('fetch_url error fetching '.$url.': '.curl_error($ch), LOGGER_NORMAL); } + $ret['errno'] = curl_errno($ch); + $base = $s; $curl_info = @curl_getinfo($ch); diff --git a/include/onepoll.php b/include/onepoll.php index 5219d9f3bd..552fea36fa 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -15,11 +15,11 @@ function RemoveReply($subject) { function onepoll_run(&$argv, &$argc){ global $a, $db; - if(is_null($a)) { + if (is_null($a)) { $a = new App; } - 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); @@ -48,21 +48,25 @@ function onepoll_run(&$argv, &$argc){ $force = false; $restart = false; - if(($argc > 1) && (intval($argv[1]))) + if (($argc > 1) && (intval($argv[1]))) { $contact_id = intval($argv[1]); + } - if(($argc > 2) && ($argv[2] == "force")) + if (($argc > 2) && ($argv[2] == "force")) { $force = true; + } - if(! $contact_id) { + if (! $contact_id) { logger('onepoll: no contact'); return; } // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") - if (App::is_already_running('onepoll'.$contact_id, '', 540)) + if (App::callstack() != "poller_run") { + if (App::is_already_running('onepoll'.$contact_id, '', 540)) { return; + } + } $d = datetime_convert(); @@ -83,8 +87,9 @@ function onepoll_run(&$argv, &$argc){ intval($contact_id) ); - if(! count($contacts)) + if (! count($contacts)) { return; + } $contact = $contacts[0]; @@ -94,9 +99,11 @@ function onepoll_run(&$argv, &$argc){ where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY", intval($contact['id']) ); - if (dbm::is_result($r)) - if (!$r[0]['total']) + if (dbm::is_result($r)) { + if (!$r[0]['total']) { poco_load($contact['id'],$importer_uid,0,$contact['poco']); + } + } } /// @TODO Check why we don't poll the Diaspora feed at the moment (some guid problem in the items?) @@ -127,24 +134,24 @@ function onepoll_run(&$argv, &$argc){ $t = $contact['last-update']; - if($contact['subhub']) { + if ($contact['subhub']) { $poll_interval = get_config('system','pushpoll_frequency'); $contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3); $hub_update = false; - if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) - $hub_update = true; - } - else + if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) { + $hub_update = true; + } + } else { $hub_update = false; - + } $importer_uid = $contact['uid']; $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` INNER JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1", intval($importer_uid) ); - if (! dbm::is_result($r)) { + if (!dbm::is_result($r)) { return; } @@ -158,7 +165,7 @@ function onepoll_run(&$argv, &$argc){ ); // Update the contact entry - if(($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) || ($contact['network'] === NETWORK_DFRN)) { + if (($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) || ($contact['network'] === NETWORK_DFRN)) { if (!poco_reachable($contact['url'])) { logger("Skipping probably dead contact ".$contact['url']); return; @@ -167,40 +174,50 @@ function onepoll_run(&$argv, &$argc){ if (!update_contact($contact["id"])) { mark_for_death($contact); return; - } else + } else { unmark_for_death($contact); + } } - if($contact['network'] === NETWORK_DFRN) { + if ($contact['network'] === NETWORK_DFRN) { $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']); - if(intval($contact['duplex']) && $contact['dfrn-id']) + if (intval($contact['duplex']) && $contact['dfrn-id']) { $idtosend = '0:' . $orig_id; - if(intval($contact['duplex']) && $contact['issued-id']) + } + if (intval($contact['duplex']) && $contact['issued-id']) { $idtosend = '1:' . $orig_id; + } // they have permission to write to us. We already filtered this in the contact query. $perm = 'rw'; // But this may be our first communication, so set the writable flag if it isn't set already. - if(! intval($contact['writable'])) + if (! intval($contact['writable'])) { q("update contact set writable = 1 where id = %d", intval($contact['id'])); - + } $url = $contact['poll'] . '?dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=data&last_update=' . $last_update . '&perm=' . $perm ; - $handshake_xml = fetch_url($url); + $ret = z_fetch_url($url); + + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return; + } + + $handshake_xml = $ret['body']; + $html_code = $a->get_curl_code(); logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA); - if((! strlen($handshake_xml)) || ($html_code >= 400) || (! $html_code)) { + if ((! strlen($handshake_xml)) || ($html_code >= 400) || (! $html_code)) { logger("poller: $url appears to be dead - marking for death "); // dead connection - might be a transient event, or this might @@ -219,7 +236,7 @@ function onepoll_run(&$argv, &$argc){ return; } - if(! strstr($handshake_xml,'<')) { + if (! strstr($handshake_xml,'<')) { logger('poller: response from ' . $url . ' did not contain XML.'); mark_for_death($contact); @@ -235,7 +252,7 @@ function onepoll_run(&$argv, &$argc){ $res = parse_xml_string($handshake_xml); - if(intval($res->status) == 1) { + if (intval($res->status) == 1) { logger("poller: $url replied status 1 - marking for death "); // we may not be friends anymore. Will keep trying for one month. @@ -248,18 +265,16 @@ function onepoll_run(&$argv, &$argc){ intval($contact['id']) ); mark_for_death($contact); - } - else { - if($contact['term-date'] != '0000-00-00 00:00:00') { - logger("poller: $url back from the dead - removing mark for death"); - unmark_for_death($contact); - } + } elseif ($contact['term-date'] != '0000-00-00 00:00:00') { + logger("poller: $url back from the dead - removing mark for death"); + unmark_for_death($contact); } - if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) + if ((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) { return; + } - if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) { + if (((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) { q("update contact set poco = '%s' where id = %d", dbesc(str_replace('/profile/','/poco/', $contact['url'])), intval($contact['id']) @@ -273,21 +288,21 @@ function onepoll_run(&$argv, &$argc){ $final_dfrn_id = ''; - if(($contact['duplex']) && strlen($contact['prvkey'])) { + if (($contact['duplex']) && strlen($contact['prvkey'])) { openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']); openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']); - } - else { + } else { openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']); openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']); } $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.')); - if(strpos($final_dfrn_id,':') == 1) + if (strpos($final_dfrn_id,':') == 1) { $final_dfrn_id = substr($final_dfrn_id,2); + } - if($final_dfrn_id != $orig_id) { + if ($final_dfrn_id != $orig_id) { logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id); // did not decode properly - cannot trust this site return; @@ -299,10 +314,9 @@ function onepoll_run(&$argv, &$argc){ $xml = post_url($contact['poll'],$postvars); - } - elseif(($contact['network'] === NETWORK_OSTATUS) + } elseif (($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) - || ($contact['network'] === NETWORK_FEED) ) { + || ($contact['network'] === NETWORK_FEED)) { // Upgrading DB fields from an older Friendica version // Will only do this once per notify-enabled OStatus contact @@ -311,10 +325,11 @@ function onepoll_run(&$argv, &$argc){ $stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0); // Contacts from OStatus are always writable - if($contact['network'] === NETWORK_OSTATUS) + if ($contact['network'] === NETWORK_OSTATUS) { $stat_writeable = 1; + } - if($stat_writeable != $contact['writable']) { + if ($stat_writeable != $contact['writable']) { q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d", intval($stat_writeable), intval($contact['id']) @@ -323,19 +338,26 @@ function onepoll_run(&$argv, &$argc){ // Are we allowed to import from this person? - if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly']) + if ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly']) { return; + } $cookiejar = tempnam(get_temppath(), 'cookiejar-onepoll-'); - $xml = fetch_url($contact['poll'], false, $redirects, 0, Null, $cookiejar); + $ret = z_fetch_url($contact['poll'], false, $redirects, array('cookiejar' => $cookiejar)); + + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return; + } + + $xml = $ret['body']; + unlink($cookiejar); - } - elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) { + } elseif ($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) { logger("Mail: Fetching", LOGGER_DEBUG); $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1); - if($mail_disabled) + if ($mail_disabled) return; logger("Mail: Enabled", LOGGER_DEBUG); @@ -347,38 +369,38 @@ function onepoll_run(&$argv, &$argc){ $mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1", intval($importer_uid) ); - if(count($x) && count($mailconf)) { + if (count($x) && count($mailconf)) { $mailbox = construct_mailbox_name($mailconf[0]); $password = ''; openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']); $mbox = email_connect($mailbox,$mailconf[0]['user'],$password); unset($password); logger("Mail: Connect to " . $mailconf[0]['user']); - if($mbox) { + if ($mbox) { q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc(datetime_convert()), intval($mailconf[0]['id']), intval($importer_uid) ); logger("Mail: Connected to " . $mailconf[0]['user']); - } else + } else { logger("Mail: Connection error ".$mailconf[0]['user']." ".print_r(imap_errors(), true)); + } } - if($mbox) { + if ($mbox) { $msgs = email_poll($mbox,$contact['addr']); - if(count($msgs)) { + if (count($msgs)) { logger("Mail: Parsing ".count($msgs)." mails for ".$mailconf[0]['user'], LOGGER_DEBUG); $metas = email_msg_meta($mbox,implode(',',$msgs)); - if(count($metas) != count($msgs)) { + if (count($metas) != count($msgs)) { logger("onepoll: for " . $mailconf[0]['user'] . " there are ". count($msgs) . " messages but received " . count($metas) . " metas", LOGGER_DEBUG); - } - else { + } else { $msgs = array_combine($msgs, $metas); - foreach($msgs as $msg_uid => $meta) { + foreach ($msgs as $msg_uid => $meta) { logger("Mail: Parsing mail ".$msg_uid, LOGGER_DATA); $datarray = array(); @@ -400,7 +422,7 @@ function onepoll_run(&$argv, &$argc){ // Only delete when mails aren't automatically moved or deleted if (($mailconf[0]['action'] != 1) AND ($mailconf[0]['action'] != 3)) - if($meta->deleted && ! $r[0]['deleted']) { + if ($meta->deleted && ! $r[0]['deleted']) { q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($r[0]['id']) @@ -434,13 +456,13 @@ function onepoll_run(&$argv, &$argc){ // $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : ''); $raw_refs = ((property_exists($meta,'references')) ? str_replace("\t",'',$meta->references) : ''); - if(! trim($raw_refs)) + if (! trim($raw_refs)) $raw_refs = ((property_exists($meta,'in_reply_to')) ? str_replace("\t",'',$meta->in_reply_to) : ''); $raw_refs = trim($raw_refs); // Don't allow a blank reference in $refs_arr - if($raw_refs) { + if ($raw_refs) { $refs_arr = explode(' ', $raw_refs); - if(count($refs_arr)) { + if (count($refs_arr)) { for($x = 0; $x < count($refs_arr); $x ++) $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'"; } @@ -456,12 +478,13 @@ function onepoll_run(&$argv, &$argc){ // Decoding the header $subject = imap_mime_header_decode($meta->subject); $datarray['title'] = ""; - foreach($subject as $subpart) - if ($subpart->charset != "default") + foreach ($subject as $subpart) { + if ($subpart->charset != "default") { $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text); - else + } else { $datarray['title'] .= $subpart->text; - + } + } $datarray['title'] = notags(trim($datarray['title'])); //$datarray['title'] = notags(trim($meta->subject)); @@ -476,7 +499,7 @@ function onepoll_run(&$argv, &$argc){ $datarray['title'] = RemoveReply($datarray['title']); // If it seems to be a reply but a header couldn't be found take the last message with matching subject - if(!x($datarray,'parent-uri') and $reply) { + if (!x($datarray,'parent-uri') and $reply) { $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d AND `network` = '%s' ORDER BY `created` DESC LIMIT 1", dbesc(protect_sprintf($datarray['title'])), intval($importer_uid), @@ -485,12 +508,12 @@ function onepoll_run(&$argv, &$argc){ $datarray['parent-uri'] = $r[0]['parent-uri']; } - if(! x($datarray,'parent-uri')) + if (! x($datarray,'parent-uri')) $datarray['parent-uri'] = $datarray['uri']; $r = email_get_msg($mbox,$msg_uid, $reply); - if(! $r) { + if (! $r) { logger("Mail: can't fetch msg ".$msg_uid." for ".$mailconf[0]['user']); continue; } @@ -502,23 +525,26 @@ function onepoll_run(&$argv, &$argc){ // some mailing lists have the original author as 'from' - add this sender info to msg body. /// @TODO Adding a gravatar for the original author would be cool - if(! stristr($meta->from,$contact['addr'])) { + if (! stristr($meta->from,$contact['addr'])) { $from = imap_mime_header_decode($meta->from); $fromdecoded = ""; - foreach($from as $frompart) - if ($frompart->charset != "default") + foreach ($from as $frompart) { + if ($frompart->charset != "default") { $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text); - else + } else { $fromdecoded .= $frompart->text; + } + } $fromarr = imap_rfc822_parse_adrlist($fromdecoded, $a->get_hostname()); $frommail = $fromarr[0]->mailbox."@".$fromarr[0]->host; - if (isset($fromarr[0]->personal)) + if (isset($fromarr[0]->personal)) { $fromname = $fromarr[0]->personal; - else + } else { $fromname = $frommail; + } //$datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body']; @@ -538,9 +564,9 @@ function onepoll_run(&$argv, &$argc){ $datarray['uid'] = $importer_uid; $datarray['contact-id'] = $contact['id']; - if($datarray['parent-uri'] === $datarray['uri']) + if ($datarray['parent-uri'] === $datarray['uri']) $datarray['private'] = 1; - if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) { + if (($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) { $datarray['private'] = 1; $datarray['allow_cid'] = '<' . $contact['id'] . '>'; } @@ -574,24 +600,24 @@ function onepoll_run(&$argv, &$argc){ } } } - } else + } else { logger("Mail: no mails for ".$mailconf[0]['user']); + } logger("Mail: closing connection for ".$mailconf[0]['user']); imap_close($mbox); } - } - elseif($contact['network'] === NETWORK_FACEBOOK) { + } elseif ($contact['network'] === NETWORK_FACEBOOK) { // This is picked up by the Facebook plugin on a cron hook. // Ignored here. - } elseif($contact['network'] === NETWORK_PUMPIO) { + } elseif ($contact['network'] === NETWORK_PUMPIO) { // This is picked up by the pump.io plugin on a cron hook. // Ignored here. } - if($xml) { + if ($xml) { logger('poller: received xml : ' . $xml, LOGGER_DATA); - if(! strstr($xml,'<')) { + if (! strstr($xml,'<')) { logger('poller: post_handshake: response from ' . $url . ' did not contain XML.'); $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), @@ -611,10 +637,10 @@ function onepoll_run(&$argv, &$argc){ consume_feed($xml,$importer,$contact,$hub,1,2); $hubmode = 'subscribe'; - if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly']) + if ($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly']) $hubmode = 'unsubscribe'; - if(($contact['network'] === NETWORK_OSTATUS || $contact['network'] == NETWORK_FEED) && (! $contact['hub-verify'])) + if (($contact['network'] === NETWORK_OSTATUS || $contact['network'] == NETWORK_FEED) && (! $contact['hub-verify'])) $hub_update = true; if ($force) @@ -622,14 +648,15 @@ function onepoll_run(&$argv, &$argc){ logger("Contact ".$contact['id']." returned hub: ".$hub." Network: ".$contact['network']." Relation: ".$contact['rel']." Update: ".$hub_update); - if((strlen($hub)) && ($hub_update) && (($contact['rel'] != CONTACT_IS_FOLLOWER) || $contact['network'] == NETWORK_FEED) ) { + if ((strlen($hub)) && ($hub_update) && (($contact['rel'] != CONTACT_IS_FOLLOWER) || $contact['network'] == NETWORK_FEED) ) { logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']); $hubs = explode(',', $hub); - if(count($hubs)) { - foreach($hubs as $h) { + if (count($hubs)) { + foreach ($hubs as $h) { $h = trim($h); - if(! strlen($h)) + if (! strlen($h)) { continue; + } subscribe_to_hub($h,$importer,$contact,$hubmode); } } @@ -671,7 +698,7 @@ function onepoll_run(&$argv, &$argc){ return; } -if (array_search(__file__,get_included_files())===0){ +if (array_search(__file__,get_included_files())===0) { onepoll_run($_SERVER["argv"],$_SERVER["argc"]); killme(); } diff --git a/include/socgraph.php b/include/socgraph.php index 32c151c043..312b1b73f9 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -732,14 +732,32 @@ function poco_check_server($server_url, $network = "", $force = false) { $orig_last_failure = $last_failure; // Check if the page is accessible via SSL. + $orig_server_url = $server_url; $server_url = str_replace("http://", "https://", $server_url); - $serverret = z_fetch_url($server_url."/.well-known/host-meta"); + + // We set the timeout to 20 seconds since this operation should be done in no time if the server was vital + $serverret = z_fetch_url($server_url."/.well-known/host-meta", false, $redirects, array('timeout' => 20)); + + // Quit if there is a timeout. + // But we want to make sure to only quit if we are mostly sure that this server url fits. + if (($orig_server_url == $server_url) AND ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + logger("Connection to server ".$server_url." timed out.", LOGGER_DEBUG); + return false; + } // Maybe the page is unencrypted only? $xmlobj = @simplexml_load_string($serverret["body"],'SimpleXMLElement',0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); if (!$serverret["success"] OR ($serverret["body"] == "") OR (@sizeof($xmlobj) == 0) OR !is_object($xmlobj)) { $server_url = str_replace("https://", "http://", $server_url); - $serverret = z_fetch_url($server_url."/.well-known/host-meta"); + + // We set the timeout to 20 seconds since this operation should be done in no time if the server was vital + $serverret = z_fetch_url($server_url."/.well-known/host-meta", false, $redirects, array('timeout' => 20)); + + // Quit if there is a timeout + if ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT) { + logger("Connection to server ".$server_url." timed out.", LOGGER_DEBUG); + return false; + } $xmlobj = @simplexml_load_string($serverret["body"],'SimpleXMLElement',0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); } From 7a89d06465a69ad211aabdd5e2778506a7b2f81e Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 1 Feb 2017 08:43:18 +0000 Subject: [PATCH 06/41] Make sure that we only quit when we are sure we can --- include/socgraph.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/socgraph.php b/include/socgraph.php index 312b1b73f9..19b94205ad 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -690,7 +690,7 @@ function poco_check_server($server_url, $network = "", $force = false) { return false; $servers = q("SELECT * FROM `gserver` WHERE `nurl` = '%s'", dbesc(normalise_link($server_url))); - if ($servers) { + if (dbm::is_result($servers)) { if ($servers[0]["created"] == "0000-00-00 00:00:00") q("UPDATE `gserver` SET `created` = '%s' WHERE `nurl` = '%s'", @@ -740,7 +740,8 @@ function poco_check_server($server_url, $network = "", $force = false) { // Quit if there is a timeout. // But we want to make sure to only quit if we are mostly sure that this server url fits. - if (($orig_server_url == $server_url) AND ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + if (dbm::is_result($servers) AND ($orig_server_url == $server_url) AND + ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT)) { logger("Connection to server ".$server_url." timed out.", LOGGER_DEBUG); return false; } From ef0fb5148c9ce2e718aecc3d2d8a6fabd7340a1a Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 1 Feb 2017 21:35:01 +0000 Subject: [PATCH 07/41] Some more timeout checks --- include/Probe.php | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/include/Probe.php b/include/Probe.php index 0b3c664129..026ae33e6a 100644 --- a/include/Probe.php +++ b/include/Probe.php @@ -60,7 +60,12 @@ class Probe { $xrd_timeout = Config::get('system','xrd_timeout', 20); $redirects = 0; - $xml = fetch_url($ssl_url, false, $redirects, $xrd_timeout, "application/xrd+xml"); + $ret = z_fetch_url($ssl_url, false, $redirects, array('timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml')); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $xml = $ret['body']; + $xrd = parse_xml_string($xml, false); if (!is_object($xrd)) { @@ -430,7 +435,12 @@ class Probe { $xrd_timeout = Config::get('system','xrd_timeout', 20); $redirects = 0; - $data = fetch_url($url, false, $redirects, $xrd_timeout, "application/xrd+xml"); + $ret = z_fetch_url($url, false, $redirects, array('timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml')); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $data = $ret['body']; + $xrd = parse_xml_string($data, false); if (!is_object($xrd)) { @@ -482,9 +492,14 @@ class Probe { * @return array noscrape data */ private function poll_noscrape($noscrape, $data) { - $content = fetch_url($noscrape); - if (!$content) + $ret = z_fetch_url($noscrape); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { return false; + } + $content = $ret['body']; + if (!$content) { + return false; + } $json = json_decode($content, true); if (!is_array($json)) @@ -663,10 +678,14 @@ class Probe { * @return array hcard data */ private function poll_hcard($hcard, $data, $dfrn = false) { - - $content = fetch_url($hcard); - if (!$content) + $ret = z_fetch_url($hcard); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { return false; + } + $content = $ret['body']; + if (!$content) { + return false; + } $doc = new DOMDocument(); if (!@$doc->loadHTML($content)) @@ -1035,7 +1054,11 @@ class Probe { * @return array feed data */ private function feed($url, $probe = true) { - $feed = fetch_url($url); + $ret = z_fetch_url($url); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $feed = $ret['body']; $feed_data = feed_import($feed, $dummy1, $dummy2, $dummy3, true); if (!$feed_data) { From 9a19ae7ce1b73f935d5d2e41a852fdb51f7e54da Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 2 Feb 2017 05:52:45 +0000 Subject: [PATCH 08/41] The queue now works with the cache - whoch should speed it up --- include/Probe.php | 21 +++++++++++++++++---- include/queue.php | 46 ++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/include/Probe.php b/include/Probe.php index 026ae33e6a..1b6feb107f 100644 --- a/include/Probe.php +++ b/include/Probe.php @@ -69,7 +69,11 @@ class Probe { $xrd = parse_xml_string($xml, false); if (!is_object($xrd)) { - $xml = fetch_url($url, false, $redirects, $xrd_timeout, "application/xrd+xml"); + $ret = z_fetch_url($url, false, $redirects, array('timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml')); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $xml = $ret['body']; $xrd = parse_xml_string($xml, false); } if (!is_object($xrd)) @@ -878,8 +882,13 @@ class Probe { $pubkey = substr($pubkey, strpos($pubkey, ',') + 1); else $pubkey = substr($pubkey, 5); - } elseif (normalise_link($pubkey) == 'http://') - $pubkey = fetch_url($pubkey); + } elseif (normalise_link($pubkey) == 'http://') { + $ret = z_fetch_url($pubkey); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $pubkey = $ret['body']; + } $key = explode(".", $pubkey); @@ -899,7 +908,11 @@ class Probe { return false; // Fetch all additional data from the feed - $feed = fetch_url($data["poll"]); + $ret = z_fetch_url($data["poll"]); + if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { + return false; + } + $feed = $ret['body']; $feed_data = feed_import($feed,$dummy1,$dummy2, $dummy3, true); if (!$feed_data) return false; diff --git a/include/queue.php b/include/queue.php index bcd32985db..3ccceb4750 100644 --- a/include/queue.php +++ b/include/queue.php @@ -5,15 +5,16 @@ use \Friendica\Core\Config; require_once("boot.php"); require_once('include/queue_fn.php'); require_once('include/dfrn.php'); +require_once('include/cache.php'); function queue_run(&$argv, &$argc){ global $a, $db; - if(is_null($a)){ + if (is_null($a)){ $a = new App; } - 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); @@ -42,9 +43,8 @@ function queue_run(&$argv, &$argc){ else $queue_id = 0; - $deadguys = array(); - $deadservers = array(); - $serverlist = array(); + $cachekey_deadguy = 'queue_run:deadguy:'; + $cachekey_server = 'queue_run:server:'; if (!$queue_id) { @@ -133,26 +133,32 @@ function queue_run(&$argv, &$argc){ remove_queue_item($q_item['id']); continue; } - if(in_array($c[0]['notify'],$deadguys)) { - logger('queue: skipping known dead url: ' . $c[0]['notify']); + + $dead = Cache::get($cachekey_deadguy.$c[0]['notify']); + + if (!is_null($dead) AND $dead) { + logger('queue: skipping known dead url: '.$c[0]['notify']); update_queue_time($q_item['id']); continue; } $server = poco_detect_server($c[0]['url']); - if (($server != "") AND !in_array($server, $serverlist)) { - logger("Check server ".$server." (".$c[0]["network"].")"); - if (!poco_check_server($server, $c[0]["network"], true)) - $deadservers[] = $server; + if ($server != "") { + $vital = Cache::get($cachekey_server.$server); - $serverlist[] = $server; - } + if (is_null($vital)) { + logger("Check server ".$server." (".$c[0]["network"].")"); - if (($server != "") AND in_array($server, $deadservers)) { - logger('queue: skipping known dead server: '.$server); - update_queue_time($q_item['id']); - continue; + $vital = poco_check_server($server, $c[0]["network"], true); + Cache::set($cachekey_server.$server, $vital, CACHE_QUARTER_HOUR); + } + + if (!is_null($vital) AND !$vital) { + logger('queue: skipping dead server: '.$server); + update_queue_time($q_item['id']); + continue; + } } $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` @@ -178,7 +184,7 @@ function queue_run(&$argv, &$argc){ if($deliver_status == (-1)) { update_queue_time($q_item['id']); - $deadguys[] = $contact['notify']; + Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); } else remove_queue_item($q_item['id']); @@ -190,7 +196,7 @@ function queue_run(&$argv, &$argc){ if($deliver_status == (-1)) { update_queue_time($q_item['id']); - $deadguys[] = $contact['notify']; + Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); } else remove_queue_item($q_item['id']); } @@ -202,7 +208,7 @@ function queue_run(&$argv, &$argc){ if($deliver_status == (-1)) { update_queue_time($q_item['id']); - $deadguys[] = $contact['notify']; + Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); } else remove_queue_item($q_item['id']); From 9c4a53e38027f6a8649763507ed395fde1e0cca9 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 4 Feb 2017 16:16:15 +0000 Subject: [PATCH 09/41] Optimized query for nodeinfo, better way to analyze posting problems with DFRN --- include/delivery.php | 2 +- include/dfrn.php | 20 ++++++++++---------- include/queue.php | 43 +++++++++++++++++++++++-------------------- mod/nodeinfo.php | 7 ++++--- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/include/delivery.php b/include/delivery.php index 5000a1edb9..8ccb19cedc 100644 --- a/include/delivery.php +++ b/include/delivery.php @@ -398,7 +398,7 @@ function delivery_run(&$argv, &$argc){ logger('notifier: dfrn_delivery to '.$contact["url"].' with guid '.$target_item["guid"].' returns '.$deliver_status); - if ($deliver_status == (-1)) { + if ($deliver_status < 0) { logger('notifier: delivery failed: queuing message'); add_to_queue($contact['id'],NETWORK_DFRN,$atom); diff --git a/include/dfrn.php b/include/dfrn.php index fbf6aea561..30057001cd 100644 --- a/include/dfrn.php +++ b/include/dfrn.php @@ -916,14 +916,14 @@ class dfrn { $ret = z_fetch_url($url); if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { - return(-1); // timed out + return -2; // timed out } $xml = $ret['body']; $curl_stat = $a->get_curl_code(); if(! $curl_stat) - return(-1); // timed out + return -3; // timed out logger('dfrn_deliver: ' . $xml, LOGGER_DATA); @@ -1023,24 +1023,24 @@ class dfrn { $key = Crypto::createNewRandomKey(); } catch (CryptoTestFailed $ex) { logger('Cannot safely create a key'); - return -1; + return -4; } catch (CannotPerformOperation $ex) { logger('Cannot safely create a key'); - return -1; + return -5; } try { $data = Crypto::encrypt($postvars['data'], $key); } catch (CryptoTestFailed $ex) { logger('Cannot safely perform encryption'); - return -1; + return -6; } catch (CannotPerformOperation $ex) { logger('Cannot safely perform encryption'); - return -1; + return -7; } break; default: logger("rino: invalid requested verision '$rino_remote_version'"); - return -1; + return -8; } $postvars['rino'] = $rino_remote_version; @@ -1074,16 +1074,16 @@ class dfrn { logger('dfrn_deliver: ' . "SENDING: " . print_r($postvars,true), LOGGER_DATA); - $xml = post_url($contact['notify'],$postvars); + $xml = post_url($contact['notify'], $postvars); logger('dfrn_deliver: ' . "RECEIVED: " . $xml, LOGGER_DATA); $curl_stat = $a->get_curl_code(); if((! $curl_stat) || (! strlen($xml))) - return(-1); // timed out + return -9; // timed out if(($curl_stat == 503) && (stristr($a->get_curl_headers(),'retry-after'))) - return(-1); + return -10; if(strpos($xml,' 1) + if ($argc > 1) { $queue_id = intval($argv[1]); - else + } else { $queue_id = 0; + } $cachekey_deadguy = 'queue_run:deadguy:'; $cachekey_server = 'queue_run:server:'; @@ -64,7 +65,7 @@ function queue_run(&$argv, &$argc){ foreach ($r as $rr) { logger('queue: deliverq'); proc_run(PRIORITY_HIGH,'include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']); - if($interval) { + if ($interval) { time_sleep_until(microtime(true) + (float) $interval); } } @@ -111,10 +112,10 @@ function queue_run(&$argv, &$argc){ // queue_predeliver hooks may have changed the queue db details, // so check again if this entry still needs processing - if($queue_id) + if ($queue_id) { $qi = q("SELECT * FROM `queue` WHERE `id` = %d LIMIT 1", intval($queue_id)); - elseif (get_config("system", "worker")) { + } elseif (get_config("system", "worker")) { logger('Call queue for id '.$q_item['id']); proc_run(PRIORITY_LOW, "include/queue.php", $q_item['id']); continue; @@ -122,8 +123,9 @@ function queue_run(&$argv, &$argc){ $qi = q("SELECT * FROM `queue` WHERE `id` = %d AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ", intval($q_item['id'])); - if(! count($qi)) + if (!dbm::is_result($qi)) { continue; + } $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", @@ -182,36 +184,37 @@ function queue_run(&$argv, &$argc){ logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); $deliver_status = dfrn::deliver($owner,$contact,$data); - if($deliver_status == (-1)) { + if ($deliver_status < 0) { update_queue_time($q_item['id']); Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); - } else + } else { remove_queue_item($q_item['id']); - + } break; case NETWORK_OSTATUS: - if($contact['notify']) { + if ($contact['notify']) { logger('queue: slapdelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); $deliver_status = slapper($owner,$contact['notify'],$data); - if($deliver_status == (-1)) { + if ($deliver_status == (-1)) { update_queue_time($q_item['id']); Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); - } else + } else { remove_queue_item($q_item['id']); + } } break; case NETWORK_DIASPORA: - if($contact['notify']) { + if ($contact['notify']) { logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); $deliver_status = Diaspora::transmit($owner,$contact,$data,$public,true); - if($deliver_status == (-1)) { + if ($deliver_status == (-1)) { update_queue_time($q_item['id']); Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); - } else + } else { remove_queue_item($q_item['id']); - + } } break; @@ -219,15 +222,15 @@ function queue_run(&$argv, &$argc){ $params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false); call_hooks('queue_deliver', $a, $params); - if($params['result']) + if ($params['result']) { remove_queue_item($q_item['id']); - else + } else { update_queue_time($q_item['id']); - + } break; } - logger('Deliver status '.$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>'); + logger('Deliver status '.(int)$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>'); } return; diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php index e084b25da3..6f20494757 100644 --- a/mod/nodeinfo.php +++ b/mod/nodeinfo.php @@ -228,9 +228,10 @@ function nodeinfo_cron() { logger("local_posts: ".$local_posts, LOGGER_DEBUG); - $posts = qu("SELECT COUNT(*) AS `local_comments` FROM `item` - INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `contact`.`self` and `item`.`id` != `item`.`parent` AND `item`.`network` IN ('%s', '%s', '%s')", + $posts = qu("SELECT COUNT(*) FROM `contact` + INNER JOIN `item` ON `item`.`contact-id` = `contact`.`id` AND `item`.`uid` = `contact`.`uid` AND + `item`.`id` != `item`.`parent` AND `item`.`network` IN ('%s', '%s', '%s') + WHERE `contact`.`self`", dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN)); if (!is_array($posts)) From f5a634abbcad08131abbefa8442f622ba1b40b14 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Feb 2017 19:23:46 +0000 Subject: [PATCH 10/41] Changed server detection. --- include/socgraph.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/socgraph.php b/include/socgraph.php index 19b94205ad..689a39614a 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -765,7 +765,7 @@ function poco_check_server($server_url, $network = "", $force = false) { if (!$serverret["success"] OR ($serverret["body"] == "") OR (sizeof($xmlobj) == 0) OR !is_object($xmlobj)) { // Workaround for bad configured servers (known nginx problem) - if ($serverret["debug"]["http_code"] != "403") { + if (!in_array($serverret["debug"]["http_code"], array("403", "404"))) { $last_failure = datetime_convert(); $failure = true; } From 39386ded36c666ff072be92cdead1a79eddd1b89 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 27 Feb 2017 21:26:37 +0000 Subject: [PATCH 11/41] "old_share" is removed --- include/api.php | 22 +++++++++------------- mod/admin.php | 3 --- mod/share.php | 26 ++++++++------------------ view/templates/admin_site.tpl | 1 - 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/include/api.php b/include/api.php index d7fa1d5875..701e527cc8 100644 --- a/include/api.php +++ b/include/api.php @@ -1686,20 +1686,16 @@ use \Friendica\Core\Config; ); if ($r[0]['body'] != "") { - if (!intval(get_config('system','old_share'))) { - if (strpos($r[0]['body'], "[/share]") !== false) { - $pos = strpos($r[0]['body'], "[share"); - $post = substr($r[0]['body'], $pos); - } else { - $post = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); - - $post .= $r[0]['body']; - $post .= "[/share]"; - } - $_REQUEST['body'] = $post; - } else - $_REQUEST['body'] = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8')."[url=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/url] \n".$r[0]['body']; + if (strpos($r[0]['body'], "[/share]") !== false) { + $pos = strpos($r[0]['body'], "[share"); + $post = substr($r[0]['body'], $pos); + } else { + $post = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); + $post .= $r[0]['body']; + $post .= "[/share]"; + } + $_REQUEST['body'] = $post; $_REQUEST['profile_uid'] = api_user(); $_REQUEST['type'] = 'wall'; $_REQUEST['api_source'] = true; diff --git a/mod/admin.php b/mod/admin.php index 1475130834..5cfeeb376f 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -649,7 +649,6 @@ function admin_page_site_post(App $a) { $diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False); $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0); $force_ssl = ((x($_POST,'force_ssl')) ? True : False); - $old_share = ((x($_POST,'old_share')) ? True : False); $hide_help = ((x($_POST,'hide_help')) ? True : False); $suppress_language = ((x($_POST,'suppress_language')) ? True : False); $suppress_tags = ((x($_POST,'suppress_tags')) ? True : False); @@ -805,7 +804,6 @@ function admin_page_site_post(App $a) { set_config('config','private_addons', $private_addons); set_config('system','force_ssl', $force_ssl); - set_config('system','old_share', $old_share); set_config('system','hide_help', $hide_help); set_config('system','use_fulltext_engine', $use_fulltext_engine); set_config('system','itemcache', $itemcache); @@ -996,7 +994,6 @@ function admin_page_site(App $a) { '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile), '$ssl_policy' => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices), '$force_ssl' => array('force_ssl', t("Force SSL"), get_config('system','force_ssl'), t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")), - '$old_share' => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")), '$hide_help' => array('hide_help', t("Hide help entry from navigation menu"), get_config('system','hide_help'), t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")), '$singleuser' => array('singleuser', t("Single user instance"), get_config('system','singleuser'), t("Make this instance multi-user or single-user for the named user"), $user_names), '$maximagesize' => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), diff --git a/mod/share.php b/mod/share.php index 928ccdef26..36a4d5945f 100644 --- a/mod/share.php +++ b/mod/share.php @@ -15,28 +15,18 @@ function share_init(App $a) { if(! dbm::is_result($r) || ($r[0]['private'] == 1)) killme(); - if (!intval(get_config('system','old_share'))) { - if (strpos($r[0]['body'], "[/share]") !== false) { - $pos = strpos($r[0]['body'], "[share"); - $o = substr($r[0]['body'], $pos); - } else { - $o = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); - - if($r[0]['title']) - $o .= '[b]'.$r[0]['title'].'[/b]'."\n"; - $o .= $r[0]['body']; - $o.= "[/share]"; - } + if (strpos($r[0]['body'], "[/share]") !== false) { + $pos = strpos($r[0]['body'], "[share"); + $o = substr($r[0]['body'], $pos); } else { - $o = ''; + $o = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); - $o .= "\xE2\x99\xb2" . ' [url=' . $r[0]['author-link'] . ']' . $r[0]['author-name'] . '[/url]' . "\n"; if($r[0]['title']) - $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; - $o .= $r[0]['body'] . "\n" ; - - $o .= (($r[0]['plink']) ? '[url=' . $r[0]['plink'] . ']' . t('link') . '[/url]' . "\n" : ''); + $o .= '[b]'.$r[0]['title'].'[/b]'."\n"; + $o .= $r[0]['body']; + $o.= "[/share]"; } + echo $o; killme(); } diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index 2edfddb885..e778b7ad49 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -56,7 +56,6 @@ {{include file="field_select.tpl" field=$theme_mobile}} {{include file="field_select.tpl" field=$ssl_policy}} {{if $ssl_policy.2 == 1}}{{include file="field_checkbox.tpl" field=$force_ssl}}{{/if}} - {{include file="field_checkbox.tpl" field=$old_share}} {{include file="field_checkbox.tpl" field=$hide_help}} {{include file="field_select.tpl" field=$singleuser}}
From 997e94555b1511b907662f688207f17d4ad868e2 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 27 Feb 2017 21:46:37 +0000 Subject: [PATCH 12/41] The old pager is removed --- include/Contact.php | 30 ++---------------------------- mod/admin.php | 3 --- mod/community.php | 27 +-------------------------- mod/network.php | 19 +------------------ mod/profile.php | 25 ++----------------------- view/templates/admin_site.tpl | 1 - 6 files changed, 6 insertions(+), 99 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 2aab828f8a..9e3e6e010d 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -675,15 +675,6 @@ function posts_from_gcontact(App $a, $gcontact_id) { else $sql = "`item`.`uid` = %d"; - if(get_config('system', 'old_pager')) { - $r = q("SELECT COUNT(*) AS `total` FROM `item` - WHERE `gcontact-id` = %d and $sql", - intval($gcontact_id), - intval(local_user())); - - $a->set_pager_total($r[0]['total']); - } - $r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`, `author-name` AS `name`, `owner-avatar` AS `photo`, `owner-link` AS `url`, `owner-avatar` AS `thumb` @@ -699,11 +690,7 @@ function posts_from_gcontact(App $a, $gcontact_id) { $o = conversation($a,$r,'community',false); - if(!get_config('system', 'old_pager')) { - $o .= alt_pager($a,count($r)); - } else { - $o .= paginate($a); - } + $o .= alt_pager($a,count($r)); return $o; } @@ -736,15 +723,6 @@ function posts_from_contact_url(App $a, $contact_url) { $author_id = intval($r[0]["author-id"]); - if (get_config('system', 'old_pager')) { - $r = q("SELECT COUNT(*) AS `total` FROM `item` - WHERE `author-id` = %d and $sql", - intval($author_id), - intval(local_user())); - - $a->set_pager_total($r[0]['total']); - } - $r = q(item_query()." AND `item`.`author-id` = %d AND ".$sql. " ORDER BY `item`.`created` DESC LIMIT %d, %d", intval($author_id), @@ -755,11 +733,7 @@ function posts_from_contact_url(App $a, $contact_url) { $o = conversation($a,$r,'community',false); - if (!get_config('system', 'old_pager')) { - $o .= alt_pager($a,count($r)); - } else { - $o .= paginate($a); - } + $o .= alt_pager($a,count($r)); return $o; } diff --git a/mod/admin.php b/mod/admin.php index 1475130834..d91b2d0a5f 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -662,7 +662,6 @@ function admin_page_site_post(App $a) { $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : ''); $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : ''); $proxy_disabled = ((x($_POST,'proxy_disabled')) ? True : False); - $old_pager = ((x($_POST,'old_pager')) ? True : False); $only_tag_search = ((x($_POST,'only_tag_search')) ? True : False); $rino = ((x($_POST,'rino')) ? intval($_POST['rino']) : 0); $embedly = ((x($_POST,'embedly')) ? notags(trim($_POST['embedly'])) : ''); @@ -815,7 +814,6 @@ function admin_page_site_post(App $a) { set_config('system','temppath', $temppath); set_config('system','basepath', $basepath); set_config('system','proxy_disabled', $proxy_disabled); - set_config('system','old_pager', $old_pager); set_config('system','only_tag_search', $only_tag_search); set_config('system','worker', $worker); set_config('system','worker_queues', $worker_queues); @@ -1061,7 +1059,6 @@ function admin_page_site(App $a) { '$temppath' => array('temppath', t("Temp path"), get_config('system','temppath'), t("If you have a restricted system where the webserver can't access the system temp path, enter another path here.")), '$basepath' => array('basepath', t("Base path to installation"), get_config('system','basepath'), t("If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot.")), '$proxy_disabled' => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")), - '$old_pager' => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")), '$only_tag_search' => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")), '$relocate_url' => array('relocate_url', t("New base url"), App::get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")), diff --git a/mod/community.php b/mod/community.php index 7c92ff462f..91b09bba9a 100644 --- a/mod/community.php +++ b/mod/community.php @@ -48,27 +48,6 @@ function community_content(App $a, $update = 0) { // Only public posts can be shown // OR your own posts if you are a logged in member - if(get_config('system', 'old_pager')) { - $r = qu("SELECT COUNT(distinct(`item`.`uri`)) AS `total` - FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - INNER JOIN `user` ON `user`.`uid` = `item`.`uid` AND `user`.`hidewall` = 0 - WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 - AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' - AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' - AND `item`.`private` = 0 AND `item`.`wall` = 1" - ); - - if (dbm::is_result($r)) - $a->set_pager_total($r[0]['total']); - - if(! $r[0]['total']) { - info( t('No results.') . EOL); - return $o; - } - - } - $r = community_getitems($a->pager['start'], $a->pager['itemspage']); if (! dbm::is_result($r)) { @@ -107,11 +86,7 @@ function community_content(App $a, $update = 0) { $o .= conversation($a,$s,'community',$update); - if(!get_config('system', 'old_pager')) { - $o .= alt_pager($a,count($r)); - } else { - $o .= paginate($a); - } + $o .= alt_pager($a,count($r)); return $o; } diff --git a/mod/network.php b/mod/network.php index 23cf098b65..284bf3d961 100644 --- a/mod/network.php +++ b/mod/network.php @@ -599,21 +599,6 @@ function network_content(App $a, $update = 0) { $pager_sql = ''; } else { - if(get_config('system', 'old_pager')) { - $r = qu("SELECT COUNT(*) AS `total` - FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = $sql_table.`contact-id` - AND (NOT `contact`.`blocked` OR `contact`.`pending`) - WHERE $sql_table.`uid` = %d AND $sql_table.`visible` AND NOT $sql_table.`deleted` - $sql_extra2 $sql_extra3 - $sql_extra $sql_nets ", - intval($_SESSION['uid']) - ); - - if (dbm::is_result($r)) { - $a->set_pager_total($r[0]['total']); - } - } - // check if we serve a mobile device and get the user settings // accordingly if ($a->is_mobile) { @@ -793,10 +778,8 @@ function network_content(App $a, $update = 0) { if (!$update) { if (get_pconfig(local_user(),'system','infinite_scroll')) { $o .= scroll_loader(); - } elseif (!get_config('system', 'old_pager')) { - $o .= alt_pager($a,count($items)); } else { - $o .= paginate($a); + $o .= alt_pager($a,count($items)); } } diff --git a/mod/profile.php b/mod/profile.php index 5dd8293c7f..ab7b7cff76 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -240,23 +240,6 @@ function profile_content(App $a, $update = 0) { $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); } - if(get_config('system', 'old_pager')) { - $r = q("SELECT COUNT(*) AS `total` - FROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid` - $sql_post_table INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0 - and `thread`.`moderated` = 0 - AND `thread`.`wall` = 1 - $sql_extra $sql_extra2 ", - intval($a->profile['profile_uid']) - ); - - if (dbm::is_result($r)) { - $a->set_pager_total($r[0]['total']); - } - } - // check if we serve a mobile device and get the user settings // accordingly if ($a->is_mobile) { @@ -328,12 +311,8 @@ function profile_content(App $a, $update = 0) { $o .= conversation($a,$items,'profile',$update); - if(! $update) { - if(!get_config('system', 'old_pager')) { - $o .= alt_pager($a,count($items)); - } else { - $o .= paginate($a); - } + if (!$update) { + $o .= alt_pager($a,count($items)); } return $o; diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index 2edfddb885..7434993705 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -153,7 +153,6 @@ {{include file="field_input.tpl" field=$itemcache_duration}} {{include file="field_input.tpl" field=$max_comments}} {{include file="field_checkbox.tpl" field=$proxy_disabled}} - {{include file="field_checkbox.tpl" field=$old_pager}}

{{$worker_title}}

From cc86d8ea14e4c1a6c57945ee248a659a1003df58 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 27 Feb 2017 23:59:05 +0000 Subject: [PATCH 13/41] Language data won't be displayed anymore (it was experimental stuff) --- mod/admin.php | 3 --- object/Item.php | 27 --------------------------- view/templates/admin_site.tpl | 1 - 3 files changed, 31 deletions(-) diff --git a/mod/admin.php b/mod/admin.php index 1475130834..4b8182dfee 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -651,7 +651,6 @@ function admin_page_site_post(App $a) { $force_ssl = ((x($_POST,'force_ssl')) ? True : False); $old_share = ((x($_POST,'old_share')) ? True : False); $hide_help = ((x($_POST,'hide_help')) ? True : False); - $suppress_language = ((x($_POST,'suppress_language')) ? True : False); $suppress_tags = ((x($_POST,'suppress_tags')) ? True : False); $use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False); $itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : ''); @@ -734,7 +733,6 @@ function admin_page_site_post(App $a) { set_config('config','sitename',$sitename); set_config('config','hostname',$hostname); set_config('config','sender_email', $sender_email); - set_config('system','suppress_language',$suppress_language); set_config('system','suppress_tags',$suppress_tags); set_config('system','shortcut_icon',$shortcut_icon); set_config('system','touch_icon',$touch_icon); @@ -1052,7 +1050,6 @@ function admin_page_site(App $a) { '$nodeinfo' => array('nodeinfo', t("Publish server information"), get_config('system','nodeinfo'), t("If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See the-federation.info for details.")), '$use_fulltext_engine' => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")), - '$suppress_language' => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")), '$suppress_tags' => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")), '$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")), '$itemcache_duration' => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")), diff --git a/object/Item.php b/object/Item.php index d95af3419a..b693520b93 100644 --- a/object/Item.php +++ b/object/Item.php @@ -287,32 +287,6 @@ class Item extends BaseObject { localize_item($item); - if ($item["postopts"] and !get_config("system", "suppress_language")) { - //$langdata = explode(";", $item["postopts"]); - //$langstr = substr($langdata[0], 5)." (".round($langdata[1]*100, 1)."%)"; - $langstr = ""; - if (substr($item["postopts"], 0, 5) == "lang=") { - $postopts = substr($item["postopts"], 5); - - $languages = explode(":", $postopts); - - if (sizeof($languages) == 1) { - $languages = array(); - $languages[] = $postopts; - } - - foreach ($languages as $language) { - $langdata = explode(";", $language); - if ($langstr != "") { - $langstr .= ", "; - } - - //$langstr .= $langdata[0]." (".round($langdata[1]*100, 1)."%)"; - $langstr .= round($langdata[1]*100, 1)."% ".$langdata[0]; - } - } - } - $body = prepare_body($item,true); list($categories, $folders) = get_cats_and_terms($item); @@ -420,7 +394,6 @@ class Item extends BaseObject { 'previewing' => ($conv->is_preview() ? ' preview ' : ''), 'wait' => t('Please wait'), 'thread_level' => $thread_level, - 'postopts' => $langstr, 'edited' => $edited, 'network' => $item["item_network"], 'network_name' => network_to_name($item['item_network'], $profile_link), diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index 2edfddb885..9c02131f06 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -132,7 +132,6 @@ {{include file="field_input.tpl" field=$lockpath}} {{include file="field_input.tpl" field=$temppath}} {{include file="field_input.tpl" field=$basepath}} - {{include file="field_checkbox.tpl" field=$suppress_language}} {{include file="field_checkbox.tpl" field=$suppress_tags}} {{include file="field_checkbox.tpl" field=$nodeinfo}} {{include file="field_input.tpl" field=$embedly}} From a3cd804ff12e4cca5e2adc2b750378007bca4146 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 1 Mar 2017 23:23:14 -0500 Subject: [PATCH 14/41] Fix default paginate.tpl Adding missing curly braces --- view/templates/paginate.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/templates/paginate.tpl b/view/templates/paginate.tpl index 21d56509aa..fcd580b071 100644 --- a/view/templates/paginate.tpl +++ b/view/templates/paginate.tpl @@ -2,7 +2,7 @@ {{if $pager}} {{if $pager.prev}}{{$pager.prev.text}}{{/if}} - {{if $pager.first}}{{$pager.first.text}}{{/if}} + {{if $pager.first}}{{$pager.first.text}}{{/if}} {{foreach $pager.pages as $p}}{{$p.text}}{{/foreach}} From 07aefe61bfeab5046f74a7f7940963011c81baf5 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 1 Mar 2017 23:26:49 -0500 Subject: [PATCH 15/41] Update paginate_data() - Formatting: Normalize quotes, spaces, braces - Add "disabled" CSS class to links previously ommitted - Add "previous" and "next" CSS classes to minimal pager links - Add main pager CSS class depending on type --- include/text.php | 89 ++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/include/text.php b/include/text.php index 11248902ba..580bd95fc7 100644 --- a/include/text.php +++ b/include/text.php @@ -268,90 +268,89 @@ function hex2bin($s) { }} -if(! function_exists('paginate_data')) { /** - * Automatica pagination data. + * @brief Paginator function. Pushes relevant links in a pager array structure. + * + * Links are generated depending on the current page and the total number of items. + * Inactive links (like "first" and "prev" on page 1) are given the "disabled" class. + * Current page link is given the "active" CSS class * * @param App $a App instance - * @param int $count [optional] item count (used with alt pager) + * @param int $count [optional] item count (used with minimal pager) * @return Array data for pagination template */ -function paginate_data(App $a, $count=null) { - $stripped = preg_replace('/([&?]page=[0-9]*)/','',$a->query_string); +function paginate_data(App $a, $count = null) { + $stripped = preg_replace('/([&?]page=[0-9]*)/', '', $a->query_string); - $stripped = str_replace('q=','',$stripped); - $stripped = trim($stripped,'/'); + $stripped = str_replace('q=', '', $stripped); + $stripped = trim($stripped, '/'); $pagenum = $a->pager['page']; - if (($a->page_offset != "") AND !preg_match('/[?&].offset=/', $stripped)) - $stripped .= "&offset=".urlencode($a->page_offset); + if (($a->page_offset != '') AND !preg_match('/[?&].offset=/', $stripped)) { + $stripped .= '&offset=' . urlencode($a->page_offset); + } $url = $stripped; $data = array(); - function _l(&$d, $name, $url, $text, $class="") { - if (!strpos($url, "?")) { - if ($pos = strpos($url, "&")) - $url = substr($url, 0, $pos)."?".substr($url, $pos + 1); + function _l(&$d, $name, $url, $text, $class = '') { + if (strpos($url, '?') === false && ($pos = strpos($url, '&')) !== false) { + $url = substr($url, 0, $pos) . '?' . substr($url, $pos + 1); } - $d[$name] = array('url'=>$url, 'text'=>$text, 'class'=>$class); + $d[$name] = array('url' => $url, 'text' => $text, 'class' => $class); } - if (!is_null($count)){ - // alt pager - if($a->pager['page']>1) - _l($data, "prev", $url.'&page='.($a->pager['page'] - 1), t('newer')); - if($count>0) - _l($data, "next", $url.'&page='.($a->pager['page'] + 1), t('older')); + if (!is_null($count)) { + // minimal pager (newer / older) + $data['class'] = 'pager'; + _l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), t('newer'), 'previous' . ($a->pager['page'] == 1 ? ' disabled' : '')); + _l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), t('older'), 'next' . ($count <= 0 ? ' disabled' : '')); } else { - // full pager - if($a->pager['total'] > $a->pager['itemspage']) { - if($a->pager['page'] != 1) - _l($data, "prev", $url.'&page='.($a->pager['page'] - 1), t('prev')); - - _l($data, "first", $url."&page=1", t('first')); - + // full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last) + $data['class'] = 'pagination'; + if ($a->pager['total'] > $a->pager['itemspage']) { + _l($data, 'first', $url . '&page=1', t('first'), $a->pager['page'] == 1 ? 'disabled' : ''); + _l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), t('prev'), $a->pager['page'] == 1 ? 'disabled' : ''); $numpages = $a->pager['total'] / $a->pager['itemspage']; $numstart = 1; $numstop = $numpages; - if($numpages > 14) { + if ($numpages > 14) { $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); } $pages = array(); - for($i = $numstart; $i <= $numstop; $i++){ - if($i == $a->pager['page']) - _l($pages, $i, "#", $i, "current"); - else - _l($pages, $i, $url."&page=$i", $i, "n"); + for ($i = $numstart; $i <= $numstop; $i++) { + if ($i == $a->pager['page']) { + _l($pages, $i, '#', $i, 'current active'); + } else { + _l($pages, $i, $url . '&page='. $i, $i, 'n'); + } } - if(($a->pager['total'] % $a->pager['itemspage']) != 0) { - if($i == $a->pager['page']) - _l($pages, $i, "#", $i, "current"); - else - _l($pages, $i, $url."&page=$i", $i, "n"); + if (($a->pager['total'] % $a->pager['itemspage']) != 0) { + if ($i == $a->pager['page']) { + _l($pages, $i, '#', $i, 'current active'); + } else { + _l($pages, $i, $url . '&page=' . $i, $i, 'n'); + } } $data['pages'] = $pages; $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages); - _l($data, "last", $url."&page=$lastpage", t('last')); - - if(($a->pager['total'] - ($a->pager['itemspage'] * $a->pager['page'])) > 0) - _l($data, "next", $url."&page=".($a->pager['page'] + 1), t('next')); - + _l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), t('next'), $a->pager['page'] == $lastpage ? 'disabled' : ''); + _l($data, 'last', $url . '&page=' . $lastpage, t('last'), $a->pager['page'] == $lastpage ? 'disabled' : ''); } } - return $data; -}} + return $data; +} if(! function_exists('paginate')) { /** From 21cad46d19f4a049b9d4d69a0a569e023c652b6d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 1 Mar 2017 23:40:34 -0500 Subject: [PATCH 16/41] Backward compatibility for theme other than frio - Add .pager .disabled CSS rule --- view/theme/duepuntozero/style.css | 3 +++ view/theme/frost-mobile/style.css | 3 +++ view/theme/frost/style.css | 3 +++ view/theme/quattro/green/style.css | 3 +++ view/theme/quattro/lilac/style.css | 3 +++ view/theme/quattro/quattro.less | 3 +++ view/theme/smoothly/style.css | 4 ++++ view/theme/vier/style.css | 4 ++++ 8 files changed, 26 insertions(+) diff --git a/view/theme/duepuntozero/style.css b/view/theme/duepuntozero/style.css index c1e8067443..8e2c5d4478 100644 --- a/view/theme/duepuntozero/style.css +++ b/view/theme/duepuntozero/style.css @@ -1552,6 +1552,9 @@ blockquote.shared_content { clear:left; } +.pager .disabled { + display: none; +} .pager_first, .pager_last, diff --git a/view/theme/frost-mobile/style.css b/view/theme/frost-mobile/style.css index c005e838f1..7c5d2c7609 100644 --- a/view/theme/frost-mobile/style.css +++ b/view/theme/frost-mobile/style.css @@ -1909,6 +1909,9 @@ input#profile-jot-email { -webkit-border-radius: 10px; } +.pager .disabled { + display: none; +} .pager_first, .pager_last, diff --git a/view/theme/frost/style.css b/view/theme/frost/style.css index 46eb650ec1..9b65da9c8c 100644 --- a/view/theme/frost/style.css +++ b/view/theme/frost/style.css @@ -1866,6 +1866,9 @@ input#dfrn-url { -webkit-border-radius: 10px; } +.pager .disabled { + display: none; +} .pager_first, .pager_last, diff --git a/view/theme/quattro/green/style.css b/view/theme/quattro/green/style.css index 8eba0e4cf7..af5cfcedf0 100644 --- a/view/theme/quattro/green/style.css +++ b/view/theme/quattro/green/style.css @@ -2481,6 +2481,9 @@ footer { margin-top: 25px; clear: both; } +.pager .disabled { + display: none; +} /** * ADMIN */ diff --git a/view/theme/quattro/lilac/style.css b/view/theme/quattro/lilac/style.css index b424534206..0c17b00331 100644 --- a/view/theme/quattro/lilac/style.css +++ b/view/theme/quattro/lilac/style.css @@ -2481,6 +2481,9 @@ footer { margin-top: 25px; clear: both; } +.pager .disabled { + display: none; +} /** * ADMIN */ diff --git a/view/theme/quattro/quattro.less b/view/theme/quattro/quattro.less index 6c01986888..53bb7e38a6 100644 --- a/view/theme/quattro/quattro.less +++ b/view/theme/quattro/quattro.less @@ -1675,6 +1675,9 @@ footer { height: 100px; display: table-row; } margin-top: 25px; clear: both; } +.pager .disabled { + display: none; +} /** * ADMIN diff --git a/view/theme/smoothly/style.css b/view/theme/smoothly/style.css index e91eccfe17..ec52277bdd 100644 --- a/view/theme/smoothly/style.css +++ b/view/theme/smoothly/style.css @@ -396,6 +396,10 @@ ul.menu-popup li a:hover { margin: 4px; } +.pager .disabled { + display: none; +} + .pager_current { background-color: #1873a2; color: #ffffff; diff --git a/view/theme/vier/style.css b/view/theme/vier/style.css index 8454c7e0ae..32617867cb 100644 --- a/view/theme/vier/style.css +++ b/view/theme/vier/style.css @@ -247,6 +247,10 @@ div.pager { float: left; } +.pager .disabled { + display: none; +} + .hide-comments-outer { margin-left: 80px; margin-bottom: 5px; From 57ce6cf5daaff5d1d4433b9a8059f5dea7b68bf5 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 1 Mar 2017 23:41:54 -0500 Subject: [PATCH 17/41] Improve pagination on frio theme - Add pager class discrimination - Change links order to first / prev / 1 / ... / 10 / next / last - Enable dynamic pagination coloring - Prevent click on disabled links --- view/theme/frio/css/style.css | 20 ++++++++++++++++++++ view/theme/frio/templates/paginate.tpl | 13 +++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 view/theme/frio/templates/paginate.tpl diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index df9585d070..ea4db0d532 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2515,3 +2515,23 @@ body .tread-wrapper .hovercard:hover .hover-card-content a { section .profile-match-wrapper { float: left; } + +/* Pagination improvements */ + +.pagination > li > a, +.pagination > li > span { + color: $link_color; +} +.pagination>.active>a, +.pagination>.active>a:focus, +.pagination>.active>a:hover, +.pagination>.active>span, +.pagination>.active>span:focus, +.pagination>.active>span:hover { + background-color: $link_color; + border-color: $link_color; +} + +.disabled > a { + pointer-events: none; +} \ No newline at end of file diff --git a/view/theme/frio/templates/paginate.tpl b/view/theme/frio/templates/paginate.tpl new file mode 100644 index 0000000000..a9c3ae480d --- /dev/null +++ b/view/theme/frio/templates/paginate.tpl @@ -0,0 +1,13 @@ +{{if $pager}} +
+ {{if $pager.first}}
  • {{$pager.first.text}}
  • {{/if}} + + {{if $pager.prev}}
  • {{$pager.prev.text}}
  • {{/if}} + + {{foreach $pager.pages as $p}}
  • {{$p.text}}
  • {{/foreach}} + + {{if $pager.next}}
  • {{$pager.next.text}}
  • {{/if}} + + {{if $pager.last}} 
  • {{$pager.last.text}}
  • {{/if}} +
    +{{/if}} From ebdc9667f796de83c6b4da2247d11f8658725a1b Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 2 Mar 2017 11:30:41 -0500 Subject: [PATCH 18/41] Improve readability - Move CSS block above the temporary block - Add template description --- view/theme/frio/css/style.css | 20 +++++++++----------- view/theme/frio/templates/paginate.tpl | 1 + 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index ea4db0d532..34bcb833db 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2508,16 +2508,7 @@ body .tread-wrapper .hovercard:hover .hover-card-content a { color: $link_color !important; } -/* - * some temporary workarounds until this will solved - * elsewhere (e.g. new templates) - */ -section .profile-match-wrapper { - float: left; -} - /* Pagination improvements */ - .pagination > li > a, .pagination > li > span { color: $link_color; @@ -2531,7 +2522,14 @@ section .profile-match-wrapper { background-color: $link_color; border-color: $link_color; } - .disabled > a { pointer-events: none; -} \ No newline at end of file +} + +/* + * some temporary workarounds until this will solved + * elsewhere (e.g. new templates) + */ +section .profile-match-wrapper { + float: left; +} diff --git a/view/theme/frio/templates/paginate.tpl b/view/theme/frio/templates/paginate.tpl index a9c3ae480d..ab65cdd406 100644 --- a/view/theme/frio/templates/paginate.tpl +++ b/view/theme/frio/templates/paginate.tpl @@ -1,3 +1,4 @@ +{{* Pager template, uses output of paginate_data() in include/text.php *}} {{if $pager}}
    {{if $pager.first}}
  • {{$pager.first.text}}
  • {{/if}} From 024908a3ece9f94c615072dd026b6ec1b5cda6e3 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 2 Mar 2017 19:00:22 -0500 Subject: [PATCH 19/41] Delete frio obsolete Colors.php library --- view/theme/frio/php/Colors.php | 292 --------------------------------- 1 file changed, 292 deletions(-) delete mode 100644 view/theme/frio/php/Colors.php diff --git a/view/theme/frio/php/Colors.php b/view/theme/frio/php/Colors.php deleted file mode 100644 index d6ba15fbc1..0000000000 --- a/view/theme/frio/php/Colors.php +++ /dev/null @@ -1,292 +0,0 @@ - 1) - $opacity = 1.0; - $output = 'rgba('.implode(",",$rgb).','.$opacity.')'; - } else { - $output = 'rgb('.implode(",",$rgb).')'; - } - - //Return rgb(a) color string - return $output; - } - - function hex2rgb( $colour ) { - if ( $colour[0] == '#' ) { - $colour = substr( $colour, 1 ); - } - if ( strlen( $colour ) == 6 ) { - list( $r, $g, $b ) = array( $colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5] ); - } elseif ( strlen( $colour ) == 3 ) { - list( $r, $g, $b ) = array( $colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2] ); - } else { - return false; - } - $r = hexdec( $r ); - $g = hexdec( $g ); - $b = hexdec( $b ); - return array( 'red' => $r, 'green' => $g, 'blue' => $b ); - } - - - function rgbToHsl( $r, $g, $b ) { - $oldR = $r; - $oldG = $g; - $oldB = $b; - $r /= 255; - $g /= 255; - $b /= 255; - $max = max( $r, $g, $b ); - $min = min( $r, $g, $b ); - $h; - $s; - $l = ( $max + $min ) / 2; - $d = $max - $min; - - if( $d == 0 ){ - $h = $s = 0; // achromatic - } else { - $s = $d / ( 1 - abs( 2 * $l - 1 ) ); - switch( $max ){ - case $r: - $h = 60 * fmod( ( ( $g - $b ) / $d ), 6 ); - if ($b > $g) { - $h += 360; - } - break; - case $g: - $h = 60 * ( ( $b - $r ) / $d + 2 ); - break; - case $b: - $h = 60 * ( ( $r - $g ) / $d + 4 ); - break; - } - } - - return array( round( $h, 2 ), round( $s, 2 ), round( $l, 2 ) ); - } - function hslToRgb( $h, $s, $l ){ - $r = ""; - $g = ""; - $b = ""; - - $c = ( 1 - abs( 2 * $l - 1 ) ) * $s; - $x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) ); - $m = $l - ( $c / 2 ); - if ( $h < 60 ) { - $r = $c; - $g = $x; - $b = 0; - } else if ( $h < 120 ) { - $r = $x; - $g = $c; - $b = 0; - } else if ( $h < 180 ) { - $r = 0; - $g = $c; - $b = $x; - } else if ( $h < 240 ) { - $r = 0; - $g = $x; - $b = $c; - } else if ( $h < 300 ) { - $r = $x; - $g = 0; - $b = $c; - } else { - $r = $c; - $g = 0; - $b = $x; - } - - $r = ( $r + $m ) * 255; - $g = ( $g + $m ) * 255; - $b = ( $b + $m ) * 255; - - return array( floor( $r ), floor( $g ), floor( $b ) ); - } - - /* - * Som more example code - this needs to be deletet if we don't need it in - * the future - */ - - function HTMLToRGB($htmlCode) - { - if($htmlCode[0] == '#') - $htmlCode = substr($htmlCode, 1); - - if (strlen($htmlCode) == 3) - { - $htmlCode = $htmlCode[0] . $htmlCode[0] . $htmlCode[1] . $htmlCode[1] . $htmlCode[2] . $htmlCode[2]; - } - - $r = hexdec($htmlCode[0] . $htmlCode[1]); - $g = hexdec($htmlCode[2] . $htmlCode[3]); - $b = hexdec($htmlCode[4] . $htmlCode[5]); - - return $b + ($g << 0x8) + ($r << 0x10); - } - - function RGBToHTML($RGB) - { - $r = 0xFF & ($RGB >> 0x10); - $g = 0xFF & ($RGB >> 0x8); - $b = 0xFF & $RGB; - - $r = dechex($r); - $g = dechex($g); - $b = dechex($b); - - return "#" . str_pad($r, 2, "0", STR_PAD_LEFT) . str_pad($g, 2, "0", STR_PAD_LEFT) . str_pad($b, 2, "0", STR_PAD_LEFT); - } - - function ChangeLuminosity($RGB, $LuminosityPercent) - { - $HSL = RGBToHSL($RGB); - $NewHSL = (int)(((float)$LuminosityPercent / 100) * 255) + (0xFFFF00 & $HSL); - return HSLToRGB($NewHSL); - } - - function RGBToHSL($RGB) - { - $r = 0xFF & ($RGB >> 0x10); - $g = 0xFF & ($RGB >> 0x8); - $b = 0xFF & $RGB; - - $r = ((float)$r) / 255.0; - $g = ((float)$g) / 255.0; - $b = ((float)$b) / 255.0; - - $maxC = max($r, $g, $b); - $minC = min($r, $g, $b); - - $l = ($maxC + $minC) / 2.0; - - if($maxC == $minC) - { - $s = 0; - $h = 0; - } - else - { - if($l < .5) - { - $s = ($maxC - $minC) / ($maxC + $minC); - } - else - { - $s = ($maxC - $minC) / (2.0 - $maxC - $minC); - } - if($r == $maxC) - $h = ($g - $b) / ($maxC - $minC); - if($g == $maxC) - $h = 2.0 + ($b - $r) / ($maxC - $minC); - if($b == $maxC) - $h = 4.0 + ($r - $g) / ($maxC - $minC); - - $h = $h / 6.0; - } - - $h = (int)round(255.0 * $h); - $s = (int)round(255.0 * $s); - $l = (int)round(255.0 * $l); - - $HSL = $l + ($s << 0x8) + ($h << 0x10); - return $HSL; - } - - function HSLToRGB($HSL) - { - $h = 0xFF & ($HSL >> 0x10); - $s = 0xFF & ($HSL >> 0x8); - $l = 0xFF & $HSL; - - $h = ((float)$h) / 255.0; - $s = ((float)$s) / 255.0; - $l = ((float)$l) / 255.0; - - if($s == 0) - { - $r = $l; - $g = $l; - $b = $l; - } - else - { - if($l < .5) - { - $t2 = $l * (1.0 + $s); - } - else - { - $t2 = ($l + $s) - ($l * $s); - } - $t1 = 2.0 * $l - $t2; - - $rt3 = $h + 1.0/3.0; - $gt3 = $h; - $bt3 = $h - 1.0/3.0; - - if($rt3 < 0) $rt3 += 1.0; - if($rt3 > 1) $rt3 -= 1.0; - if($gt3 < 0) $gt3 += 1.0; - if($gt3 > 1) $gt3 -= 1.0; - if($bt3 < 0) $bt3 += 1.0; - if($bt3 > 1) $bt3 -= 1.0; - - if(6.0 * $rt3 < 1) $r = $t1 + ($t2 - $t1) * 6.0 * $rt3; - elseif(2.0 * $rt3 < 1) $r = $t2; - elseif(3.0 * $rt3 < 2) $r = $t1 + ($t2 - $t1) * ((2.0/3.0) - $rt3) * 6.0; - else $r = $t1; - - if(6.0 * $gt3 < 1) $g = $t1 + ($t2 - $t1) * 6.0 * $gt3; - elseif(2.0 * $gt3 < 1) $g = $t2; - elseif(3.0 * $gt3 < 2) $g = $t1 + ($t2 - $t1) * ((2.0/3.0) - $gt3) * 6.0; - else $g = $t1; - - if(6.0 * $bt3 < 1) $b = $t1 + ($t2 - $t1) * 6.0 * $bt3; - elseif(2.0 * $bt3 < 1) $b = $t2; - elseif(3.0 * $bt3 < 2) $b = $t1 + ($t2 - $t1) * ((2.0/3.0) - $bt3) * 6.0; - else $b = $t1; - } - - $r = (int)round(255.0 * $r); - $g = (int)round(255.0 * $g); - $b = (int)round(255.0 * $b); - - $RGB = $b + ($g << 0x8) + ($r << 0x10); - return $RGB; - } -} \ No newline at end of file From 3ea830e22152e2d2ded6cad28599e22061406bbe Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 3 Mar 2017 21:45:36 -0500 Subject: [PATCH 20/41] Strip @hubzilla.server part from guid for autoscrolling purpuses --- view/theme/frio/js/mod_display.js | 3 ++- view/theme/frio/templates/wall_thread.tpl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/view/theme/frio/js/mod_display.js b/view/theme/frio/js/mod_display.js index 86608821e5..ed126d60cd 100644 --- a/view/theme/frio/js/mod_display.js +++ b/view/theme/frio/js/mod_display.js @@ -4,8 +4,9 @@ // Catch the GUID from the URL var itemGuid = window.location.pathname.split("/").pop(); +var itemGuidSafe = itemGuid.replace(/%.*/, ''); $(window).load(function(){ // Scroll to the Item by its GUID - scrollToItem('item-'+itemGuid); + scrollToItem('item-' + itemGuidSafe); }); diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl index e71dc7b84c..1977f541c2 100644 --- a/view/theme/frio/templates/wall_thread.tpl +++ b/view/theme/frio/templates/wall_thread.tpl @@ -68,9 +68,9 @@ as the value of $top_child_total (this is done at the end of this file) {{* Use a different div container in dependence max thread-level = 7 *}} {{if $item.thread_level<7}} -
    +
    {{else}} -
    +
    {{/if}}
    {{* Put addional actions in a top-right dropdown menu *}} From da5bbe8b50226435a1ec7dc34cd4c40c8d024e5e Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 05:06:05 -0500 Subject: [PATCH 21/41] Add public_contact() function - Add function to retrieve the public contact id (uid = 0) of the current logged-in user --- boot.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/boot.php b/boot.php index b8e9267070..a5774aaad8 100644 --- a/boot.php +++ b/boot.php @@ -1889,11 +1889,35 @@ function goaway($s) { * @return int|bool user id or false */ function local_user() { - if((x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))) + if (x($_SESSION, 'authenticated') && x($_SESSION, 'uid')) { return intval($_SESSION['uid']); + } return false; } +/** + * @brief Returns the public contact id of logged in user or false. + * + * @return int|bool public contact id or false + */ +function public_contact() { + static $public_contact_id = false; + + if (!$public_contact_id && x($_SESSION, 'authenticated')) { + if (x($_SESSION, 'my_address')) { + // Local user + $public_contact_id = intval(get_contact($_SESSION['my_address'], 0)); + } else if (x($_SESSION, 'visitor_home')) { + // Remote user + $public_contact_id = intval(get_contact($_SESSION['visitor_home'], 0)); + } + } else if (!x($_SESSION, 'authenticated')) { + $public_contact_id = false; + } + + return $public_contact_id; +} + /** * @brief Returns contact id of authenticated site visitor or false * From 67ae0fed7fac98b71076e501bf6595cf917d3b13 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 05:07:17 -0500 Subject: [PATCH 22/41] Fix response "self" assigment - Switch from unreliable `uid` matching to `author-id` using public_contact() --- include/conversation.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/conversation.php b/include/conversation.php index a1d086cb9d..93c42cd7b1 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -416,8 +416,8 @@ These Fields are not added below (yet). They are here to for bug search. `item`.`shadow`, */ - return "`item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`, - `item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`, + return "`item`.`author-id`, `item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`, + `item`.`owner-id`, `item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`, `item`.`contact-id`, `item`.`uid`, `item`.`id`, `item`.`parent`, `item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`, `item`.`commented`, `item`.`created`, `item`.`edited`, @@ -1066,8 +1066,9 @@ function builtin_activity_puller($item, &$conv_responses) { else $conv_responses[$mode][$item['thr-parent']] ++; - if((local_user()) && (local_user() == $item['uid']) && ($item['self'])) + if (public_contact() == $item['author-id']) { $conv_responses[$mode][$item['thr-parent'] . '-self'] = 1; + } $conv_responses[$mode][$item['thr-parent'] . '-l'][] = $url; From 4931ecafbb2bd3cd18a44d3a366c1051f64a08e0 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 05:28:01 -0500 Subject: [PATCH 23/41] Rewriting of do_like() - Fix behavior where event actions had to be performed twice to switch from one to another - Simplify the contact data retrieval - Make sure contact-id, owner-id and author-id are correctly set --- include/like.php | 264 +++++++++++++++++++++++------------------------ 1 file changed, 130 insertions(+), 134 deletions(-) diff --git a/include/like.php b/include/like.php index 210bde6906..a53b90c039 100644 --- a/include/like.php +++ b/include/like.php @@ -18,155 +18,169 @@ require_once("include/diaspora.php"); function do_like($item_id, $verb) { $a = get_app(); - if(! local_user() && ! remote_user()) { + if (! local_user() && ! remote_user()) { return false; } - switch($verb) { + switch ($verb) { case 'like': + $bodyverb = t('%1$s likes %2$s\'s %3$s'); + $activity = ACTIVITY_LIKE; + break; case 'unlike': + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); $activity = ACTIVITY_LIKE; break; case 'dislike': case 'undislike': + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); $activity = ACTIVITY_DISLIKE; break; case 'attendyes': case 'unattendyes': + $bodyverb = t('%1$s is attending %2$s\'s %3$s'); $activity = ACTIVITY_ATTEND; break; case 'attendno': case 'unattendno': + $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); $activity = ACTIVITY_ATTENDNO; break; case 'attendmaybe': case 'unattendmaybe': + $bodyverb = t('%1$s may attend %2$s\'s %3$s'); $activity = ACTIVITY_ATTENDMAYBE; break; default: + logger('like: unknown verb ' . $verb . ' for item ' . $item_id); return false; - break; } + // Enable activity toggling instead of on/off + $event_verb_flag = $activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE; + logger('like: verb ' . $verb . ' item ' . $item_id); - $r = q("SELECT * FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", + // Retrieve item + $items = q("SELECT * FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id) ); - if(! $item_id || (! dbm::is_result($r))) { - logger('like: no item ' . $item_id); + if (! $item_id || ! dbm::is_result($items)) { + logger('like: unknown item ' . $item_id); return false; } - $item = $r[0]; + $item = $items[0]; - $owner_uid = $item['uid']; - - if (! can_write_wall($a,$owner_uid)) { + if (! can_write_wall($a, $item['uid'])) { + logger('like: unable to write on wall ' . $item['uid']); return false; } - $remote_owner = null; + // Retrieves the local post owner + $owners = q("SELECT `contact`.* FROM `contact` + WHERE `contact`.`self` = 1 + AND `contact`.`uid` = %d", + intval($item['uid']) + ); + if (dbm::is_result($owners)) { + $owner_self_contact = $owners[0]; + } else { + logger('like: unknown owner ' . $item['uid']); + return false; + } - if(! $item['wall']) { - // The top level post may have been written by somebody on another system - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($item['contact-id']), - intval($item['uid']) + // Retrieve the current logged in user's public contact + $author_id = public_contact(); + + $contacts = q("SELECT * FROM `contact` WHERE `id` = %d", + intval($author_id) + ); + if (dbm::is_result($contacts)) { + $author_contact = $contacts[0]; + } else { + logger('like: unknown author ' . $author_id); + return false; + } + + // Contact-id is the uid-dependant author contact + if (local_user() == $item['uid']) { + $item_contact_id = $owner_self_contact['id']; + $item_contact = $owner_self_contact; + } else { + $item_contact_id = get_contact($author_contact['url'], $item['uid']); + + $contacts = q("SELECT * FROM `contact` WHERE `id` = %d", + intval($item_contact_id) ); - if (! dbm::is_result($r)) { + if (dbm::is_result($contacts)) { + $item_contact = $contacts[0]; + } else { + logger('like: unknown item contact ' . $item_contact_id); return false; } - if (! $r[0]['self']) { - $remote_owner = $r[0]; - } } - // this represents the post owner on this system. - - $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid` - WHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", - intval($owner_uid) - ); - if (dbm::is_result($r)) { - $owner = $r[0]; - } - - if (! $owner) { - logger('like: no owner'); - return false; - } - - if (! $remote_owner) { - $remote_owner = $owner; - } - - // This represents the person posting - - if ((local_user()) && (local_user() == $owner_uid)) { - $contact = $owner; - } else { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($_SESSION['visitor_id']), - intval($owner_uid) - ); - if (dbm::is_result($r)) { - $contact = $r[0]; - } - } - if (! $contact) { - return false; - } - - - $verbs = " '".dbesc($activity)."' "; - + // Look for an existing verb row // event participation are essentially radio toggles. If you make a subsequent choice, // we need to eradicate your first choice. - if ($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) { - $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' "; + if ($event_verb_flag) { + $verbs = "'" . dbesc(ACTIVITY_ATTEND) . "', '" . dbesc(ACTIVITY_ATTENDNO) . "', '" . dbesc(ACTIVITY_ATTENDMAYBE) . "'"; + } else { + $verbs = "'".dbesc($activity)."'"; } - $r = q("SELECT `id`, `guid` FROM `item` WHERE `verb` IN ( $verbs ) AND `deleted` = 0 - AND `contact-id` = %d AND `uid` = %d - AND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') LIMIT 1", - intval($contact['id']), intval($owner_uid), + $existing_like = q("SELECT `id`, `guid`, `verb` FROM `item` + WHERE `verb` IN ($verbs) + AND `deleted` = 0 + AND `author-id` = %d + AND `uid` = %d + AND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') + LIMIT 1", + intval($author_contact['id']), + intval($item['uid']), dbesc($item_id), dbesc($item_id), dbesc($item['uri']) ); - if (dbm::is_result($r)) { - $like_item = $r[0]; + // If it exists, mark it as deleted + if (dbm::is_result($existing_like)) { + $like_item = $existing_like[0]; // Already voted, undo it - $r = q("UPDATE `item` SET `deleted` = 1, `unseen` = 1, `changed` = '%s' WHERE `id` = %d", + q("UPDATE `item` SET `deleted` = 1, `unseen` = 1, `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($like_item['id']) ); - // Clean up the Diaspora signatures for this like // Go ahead and do it even if Diaspora support is disabled. We still want to clean up // if it had been enabled in the past - $r = q("DELETE FROM `sign` WHERE `iid` = %d", + q("DELETE FROM `sign` WHERE `iid` = %d", intval($like_item['id']) ); $like_item_id = $like_item['id']; proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $like_item_id); + if (!$event_verb_flag || $like_item['verb'] == $activity) { + return true; + } + } + + // Verb is "un-something", just trying to delete existing entries + if (strpos($verb, 'un') === 0) { return true; } - $uri = item_new_uri($a->get_hostname(),$owner_uid); - + // Else or if event verb different from existing row, create a new item row $post_type = (($item['resource-id']) ? t('photo') : t('status')); if ($item['object-type'] === ACTIVITY_OBJ_EVENT) { $post_type = t('event'); } - $objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE ); - $link = xmlify('' . "\n") ; + $objtype = $item['resource-id'] ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE ; + $link = xmlify('' . "\n") ; $body = $item['body']; $obj = <<< EOT @@ -180,80 +194,62 @@ function do_like($item_id, $verb) { $body EOT; - if ($verb === 'like') { - $bodyverb = t('%1$s likes %2$s\'s %3$s'); - } - if ($verb === 'dislike') { - $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - } - if ($verb === 'attendyes') { - $bodyverb = t('%1$s is attending %2$s\'s %3$s'); - } - if ($verb === 'attendno') { - $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); - } - if ($verb === 'attendmaybe') { - $bodyverb = t('%1$s may attend %2$s\'s %3$s'); - } - if (! isset($bodyverb)) { - return false; - } - - $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; + $ulink = '[url=' . $author_contact['url'] . ']' . $author_contact['name'] . '[/url]'; $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]'; - $plink = '[url=' . App::get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]'; + $plink = '[url=' . App::get_baseurl() . '/display/' . $owner_self_contact['nick'] . '/' . $item['id'] . ']' . $post_type . '[/url]'; - /// @TODO Or rewrite this to multi-line initialization of the array? - $arr = array(); + $new_item = array( + 'guid' => get_guid(32), + 'uri' => item_new_uri($a->get_hostname(), $item['uid']), + 'uid' => $item['uid'], + 'contact-id' => $item_contact_id, + 'type' => 'activity', + 'wall' => $item['wall'], + 'origin' => 1, + 'gravity' => GRAVITY_LIKE, + 'parent' => $item['id'], + 'parent-uri' => $item['uri'], + 'thr-parent' => $item['uri'], + 'owner-id' => $item['owner-id'], + 'owner-name' => $item['owner-name'], + 'owner-link' => $item['owner-link'], + 'owner-avatar' => $item['owner-avatar'], + 'author-id' => $author_contact['id'], + 'author-name' => $author_contact['name'], + 'author-link' => $author_contact['url'], + 'author-avatar' => $author_contact['thumb'], + 'body' => sprintf($bodyverb, $ulink, $alink, $plink), + 'verb' => $activity, + 'object-type' => $objtype, + 'object' => $obj, + 'allow_cid' => $item['allow_cid'], + 'allow_gid' => $item['allow_gid'], + 'deny_cid' => $item['deny_cid'], + 'deny_gid' => $item['deny_gid'], + 'visible' => 1, + 'unseen' => 1, + 'last-child' => 0 + ); - $arr['guid'] = get_guid(32); - $arr['uri'] = $uri; - $arr['uid'] = $owner_uid; - $arr['contact-id'] = $contact['id']; - $arr['type'] = 'activity'; - $arr['wall'] = $item['wall']; - $arr['origin'] = 1; - $arr['gravity'] = GRAVITY_LIKE; - $arr['parent'] = $item['id']; - $arr['parent-uri'] = $item['uri']; - $arr['thr-parent'] = $item['uri']; - $arr['owner-name'] = $remote_owner['name']; - $arr['owner-link'] = $remote_owner['url']; - $arr['owner-avatar'] = $remote_owner['thumb']; - $arr['author-name'] = $contact['name']; - $arr['author-link'] = $contact['url']; - $arr['author-avatar'] = $contact['thumb']; - $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink ); - $arr['verb'] = $activity; - $arr['object-type'] = $objtype; - $arr['object'] = $obj; - $arr['allow_cid'] = $item['allow_cid']; - $arr['allow_gid'] = $item['allow_gid']; - $arr['deny_cid'] = $item['deny_cid']; - $arr['deny_gid'] = $item['deny_gid']; - $arr['visible'] = 1; - $arr['unseen'] = 1; - $arr['last-child'] = 0; - - $post_id = item_store($arr); + $new_item_id = item_store($new_item); + // @todo: Explain this block if (! $item['visible']) { - $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d", + q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d", intval($item['id']), - intval($owner_uid) + intval($item['uid']) ); } - // Save the author information for the like in case we need to relay to Diaspora - Diaspora::store_like_signature($contact, $post_id); + Diaspora::store_like_signature($item_contact, $new_item_id); - $arr['id'] = $post_id; + $new_item['id'] = $new_item_id; - call_hooks('post_local_end', $arr); + call_hooks('post_local_end', $new_item); - proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id); + proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $new_item_id); return true; } From ff64beeb4e437ae408bfc2f56b6829ce9694f278 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 05:37:01 -0500 Subject: [PATCH 24/41] Reformatted get_contact() - Resolved one `@todo` (the catch-all contact query) - Improved code readability by naming variables - Code standards compliance --- include/Contact.php | 141 ++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 2aab828f8a..553bf938c2 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -508,72 +508,81 @@ function contacts_not_grouped($uid,$start = 0,$count = 0) { /** * @brief Fetch the contact id for a given url and user * + * First lookup in the contact table to find a record matching either `url`, `nurl`, + * `addr` or `alias`. + * + * If there's no record and we aren't looking for a public contact, we quit. + * If there's one, we check that it isn't time to update the picture else we + * directly return the found contact id. + * + * Second, we probe the provided $url wether it's http://server.tld/profile or + * nick@server.tld. We quit if we can't get any info back. + * + * Third, we create the contact record if it doesn't exist + * + * Fourth, we update the existing record with the new data (avatar, alias, nick) + * if there's any updates + * * @param string $url Contact URL - * @param integer $uid The user id for the contact + * @param integer $uid The user id for the contact (0 = public contact) * @param boolean $no_update Don't update the contact * * @return integer Contact ID */ function get_contact($url, $uid = 0, $no_update = false) { - require_once("include/Scrape.php"); + require_once "include/Scrape.php"; logger("Get contact data for url ".$url." and user ".$uid." - ".App::callstack(), LOGGER_DEBUG);; $data = array(); - $contactid = 0; + $contact_id = 0; - // is it an address in the format user@server.tld? - /// @todo use gcontact and/or the addr field for a lookup - if (!strstr($url, "http") OR strstr($url, "@")) { - $data = probe_url($url); - $url = $data["url"]; - if ($url == "") - return 0; - } + // Catch-all query, may return multiple rows + $contacts = q("SELECT `id`, `avatar-date` FROM `contact` + WHERE ('%s' IN (`url`, `addr`, `alias`) OR '%s' IN (`nurl`, `alias`)) + AND `uid` = %d", + dbesc($url), + dbesc(normalise_link($url)), + intval($uid)); - $contact = q("SELECT `id`, `avatar-date` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2", - dbesc(normalise_link($url)), - intval($uid)); - - if (!$contact) - $contact = q("SELECT `id`, `avatar-date` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `uid` = %d ORDER BY `id` LIMIT 1", - dbesc($url), - dbesc(normalise_link($url)), - intval($uid)); - - if ($contact) { - $contactid = $contact[0]["id"]; + if (dbm::is_result($contacts)) { + $contact_id = $contacts[0]["id"]; // Update the contact every 7 days - $update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -7 days')); - //$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -12 hours')); + $update_photo = ($contacts[0]['avatar-date'] < datetime_convert('','','now -7 days')); if (!$update_photo OR $no_update) { - return($contactid); + return $contact_id; } - } elseif ($uid != 0) + } elseif ($uid != 0) { return 0; + } - if (!count($data)) - $data = probe_url($url); - - // Does this address belongs to a valid network? - if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) { - if ($uid != 0) - return 0; - - // Get data from the gcontact table - $r = q("SELECT `name`, `nick`, `url`, `photo`, `addr`, `alias`, `network` FROM `gcontact` WHERE `nurl` = '%s'", - dbesc(normalise_link($url))); - if (!$r) - return 0; - - $data = $r[0]; + $data = probe_url($url); + if (!$data['url']) { + return 0; } $url = $data["url"]; - if ($contactid == 0) { + // Does this address belongs to a valid network? + if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) { + if ($uid != 0) { + return 0; + } + + // Get data from the gcontact table + $gcontacts = q("SELECT `name`, `nick`, `url`, `photo`, `addr`, `alias`, `network` FROM `gcontact` WHERE `nurl` = '%s'", + dbesc(normalise_link($url))); + if (!$gcontacts) { + return 0; + } + + $data = $gcontacts[0]; + } + + + if (!$contact_id) { q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`, `name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`, `batch`, `request`, `confirm`, `poco`, `name-date`, `uri-date`, @@ -602,45 +611,48 @@ function get_contact($url, $uid = 0, $no_update = false) { dbesc(datetime_convert()) ); - $contact = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2", + $contacts = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2", dbesc(normalise_link($data["url"])), intval($uid)); - if (!$contact) + if (!dbm::is_result($contacts)) { return 0; + } - $contactid = $contact[0]["id"]; + $contact_id = $contacts[0]["id"]; // Update the newly created contact from data in the gcontact table - $r = q("SELECT `location`, `about`, `keywords`, `gender` FROM `gcontact` WHERE `nurl` = '%s'", + $gcontacts = q("SELECT `location`, `about`, `keywords`, `gender` FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($data["url"]))); - if ($r) { - logger("Update contact ".$data["url"]); + if (dbm::is_result($gcontacts)) { + logger("Update contact " . $data["url"] . ' from gcontact'); q("UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d", - dbesc($r["location"]), dbesc($r["about"]), dbesc($r["keywords"]), - dbesc($r["gender"]), intval($contactid)); + dbesc($gcontacts[0]["location"]), dbesc($gcontacts[0]["about"]), dbesc($gcontacts[0]["keywords"]), + dbesc($gcontacts[0]["gender"]), intval($contact_id)); } } - if ((count($contact) > 1) AND ($uid == 0) AND ($contactid != 0) AND ($url != "")) + if (count($contacts) > 1 AND $uid == 0 AND $contact_id != 0 AND $url != "") { q("DELETE FROM `contact` WHERE `nurl` = '%s' AND `id` != %d AND NOT `self`", dbesc(normalise_link($url)), - intval($contactid)); + intval($contact_id)); + } - require_once("Photo.php"); + require_once "Photo.php"; - update_contact_avatar($data["photo"],$uid,$contactid); + update_contact_avatar($data["photo"], $uid, $contact_id); - $r = q("SELECT `addr`, `alias`, `name`, `nick` FROM `contact` WHERE `id` = %d", intval($contactid)); + $contacts = q("SELECT `addr`, `alias`, `name`, `nick` FROM `contact` WHERE `id` = %d", intval($contact_id)); // This condition should always be true - if (!dbm::is_result($r)) - return $contactid; + if (!dbm::is_result($contacts)) { + return $contact_id; + } // Only update if there had something been changed - if (($data["addr"] != $r[0]["addr"]) OR - ($data["alias"] != $r[0]["alias"]) OR - ($data["name"] != $r[0]["name"]) OR - ($data["nick"] != $r[0]["nick"])) + if ($data["addr"] != $contacts[0]["addr"] OR + $data["alias"] != $contacts[0]["alias"] OR + $data["name"] != $contacts[0]["name"] OR + $data["nick"] != $contacts[0]["nick"]) { q("UPDATE `contact` SET `addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s', `name-date` = '%s', `uri-date` = '%s' WHERE `id` = %d", dbesc($data["addr"]), @@ -649,10 +661,11 @@ function get_contact($url, $uid = 0, $no_update = false) { dbesc($data["nick"]), dbesc(datetime_convert()), dbesc(datetime_convert()), - intval($contactid) + intval($contact_id) ); + } - return $contactid; + return $contact_id; } /** From 116b9e1c1f983cc3504cb5f1bf7877a46fb502d5 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 06:01:08 -0500 Subject: [PATCH 25/41] Use Probe::uri instead of probe_url() - Moved file inclusion to enable lazy loading --- include/Contact.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 553bf938c2..ae06ecf11b 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -1,7 +1,5 @@ Date: Mon, 6 Mar 2017 16:19:12 -0500 Subject: [PATCH 26/41] Split slow catch-all query into three fast queries Thanks @annando for the tip. --- include/Contact.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index ae06ecf11b..845ee168cc 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -534,14 +534,32 @@ function get_contact($url, $uid = 0, $no_update = false) { $data = array(); $contact_id = 0; - // Catch-all query, may return multiple rows + // We first try the addr (nick@server.tld) $contacts = q("SELECT `id`, `avatar-date` FROM `contact` - WHERE ('%s' IN (`url`, `addr`, `alias`) OR '%s' IN (`nurl`, `alias`)) + WHERE `addr` = '%s' AND `uid` = %d", dbesc($url), - dbesc(normalise_link($url)), intval($uid)); + // Then the nurl (http://server.tld/nick) + if (! dbm::is_result($contacts)) { + $contacts = q("SELECT `id`, `avatar-date` FROM `contact` + WHERE `nurl` = '%s' + AND `uid` = %d", + dbesc(normalise_link($url)), + intval($uid)); + } + + // Then the alias (which could be anything) + if (! dbm::is_result($contacts)) { + $contacts = q("SELECT `id`, `avatar-date` FROM `contact` + WHERE `alias` IN ('%s', '%s') + AND `uid` = %d", + dbesc($url), + dbesc(normalise_link($url)), + intval($uid)); + } + if (dbm::is_result($contacts)) { $contact_id = $contacts[0]["id"]; @@ -552,6 +570,7 @@ function get_contact($url, $uid = 0, $no_update = false) { return $contact_id; } } elseif ($uid != 0) { + // Non-existing user-specific contact, exiting return 0; } From 97378893cd5875b37647f41e57349ba8af51b8c7 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 6 Mar 2017 16:26:04 -0500 Subject: [PATCH 27/41] Switch nurl and addr lookups - nurl lookup is more frequent than addr lookup, saves queries --- include/Contact.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 845ee168cc..1fcdc6951c 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -534,20 +534,21 @@ function get_contact($url, $uid = 0, $no_update = false) { $data = array(); $contact_id = 0; - // We first try the addr (nick@server.tld) + // We first try the nurl (http://server.tld/nick), most common case $contacts = q("SELECT `id`, `avatar-date` FROM `contact` - WHERE `addr` = '%s' - AND `uid` = %d", - dbesc($url), - intval($uid)); - - // Then the nurl (http://server.tld/nick) - if (! dbm::is_result($contacts)) { - $contacts = q("SELECT `id`, `avatar-date` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d", dbesc(normalise_link($url)), intval($uid)); + + + // Then the addr (nick@server.tld) + if (! dbm::is_result($contacts)) { + $contacts = q("SELECT `id`, `avatar-date` FROM `contact` + WHERE `addr` = '%s' + AND `uid` = %d", + dbesc($url), + intval($uid)); } // Then the alias (which could be anything) From d7f62e82b96d0980e6e54fa8a1899f208b520a8b Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 7 Mar 2017 16:28:15 -0500 Subject: [PATCH 28/41] Fix behavior regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverted quitting get_contact if Probe::uri didn’t yield an url for “nick@server.tld” form. --- include/Contact.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 1fcdc6951c..5b0599449f 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -577,11 +577,6 @@ function get_contact($url, $uid = 0, $no_update = false) { require_once('include/Probe.php'); $data = Probe::uri($url); - if (!$data['url']) { - return 0; - } - - $url = $data["url"]; // Does this address belongs to a valid network? if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) { @@ -599,6 +594,12 @@ function get_contact($url, $uid = 0, $no_update = false) { $data = $gcontacts[0]; } + // Unable to convert nick@server.tld into http://server.tld/nick + if (!$data['url'] && (!strstr($url, "http") OR strstr($url, "@"))) { + return 0; + } + + $url = $data["url"]; if (!$contact_id) { q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`, From 37b15995d84e3833363bb169dcab8c467bbf26b3 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 7 Mar 2017 16:43:22 -0500 Subject: [PATCH 29/41] Add pump.io network to probing supported networks - Remove useless condition --- include/Contact.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 5b0599449f..ee5ec0cfce 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -578,8 +578,8 @@ function get_contact($url, $uid = 0, $no_update = false) { require_once('include/Probe.php'); $data = Probe::uri($url); - // Does this address belongs to a valid network? - if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) { + // Last try in gcontact for unsupported networks + if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO))) { if ($uid != 0) { return 0; } @@ -594,11 +594,6 @@ function get_contact($url, $uid = 0, $no_update = false) { $data = $gcontacts[0]; } - // Unable to convert nick@server.tld into http://server.tld/nick - if (!$data['url'] && (!strstr($url, "http") OR strstr($url, "@"))) { - return 0; - } - $url = $data["url"]; if (!$contact_id) { From 2d2a35af730c323d9358d65c218907a914e5cf13 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 8 Mar 2017 18:03:41 +0000 Subject: [PATCH 30/41] Make Hypolite happy --- include/dfrn.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/dfrn.php b/include/dfrn.php index 30057001cd..39372aef14 100644 --- a/include/dfrn.php +++ b/include/dfrn.php @@ -922,8 +922,9 @@ class dfrn { $xml = $ret['body']; $curl_stat = $a->get_curl_code(); - if(! $curl_stat) + if (!$curl_stat) { return -3; // timed out + } logger('dfrn_deliver: ' . $xml, LOGGER_DATA); @@ -1079,11 +1080,13 @@ class dfrn { logger('dfrn_deliver: ' . "RECEIVED: " . $xml, LOGGER_DATA); $curl_stat = $a->get_curl_code(); - if((! $curl_stat) || (! strlen($xml))) + if ((!$curl_stat) || (!strlen($xml))) { return -9; // timed out + } - if(($curl_stat == 503) && (stristr($a->get_curl_headers(),'retry-after'))) + if (($curl_stat == 503) && (stristr($a->get_curl_headers(),'retry-after'))) { return -10; + } if(strpos($xml,' Date: Sun, 12 Mar 2017 01:11:35 +0100 Subject: [PATCH 31/41] Fix "remember me" cookie for OpenID logins Closes #2432 NOTE: in order to obtain the same "cookie hash" it was required to include unneeded fields in the user record structure, this would be good to change in the future... --- include/auth.php | 48 ++------------------------------------- include/security.php | 54 ++++++++++++++++++++++++++++++++++++++++++++ mod/openid.php | 2 +- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/include/auth.php b/include/auth.php index e3c8d92eeb..62ca3563a4 100644 --- a/include/auth.php +++ b/include/auth.php @@ -125,6 +125,7 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' $openid = new LightOpenID; $openid->identity = $openid_url; $_SESSION['openid'] = $openid_url; + $_SESSION['remember'] = $_POST['remember']; $openid->returnUrl = App::get_baseurl(true).'/openid'; goaway($openid->authUrl()); } catch (Exception $e) { @@ -178,17 +179,8 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' goaway(z_root()); } - // If the user specified to remember the authentication, then set a cookie - // that expires after one week (the default is when the browser is closed). - // The cookie will be renewed automatically. - // The week ensures that sessions will expire after some inactivity. - if ($_POST['remember']) - new_cookie(604800, $r[0]); - else - new_cookie(0); // 0 means delete on browser exit - // if we haven't failed up this point, log them in. - + $_SESSION['remember'] = $_POST['remember']; $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); authenticate_success($record, true, true); } @@ -203,39 +195,3 @@ function nuke_session() { session_unset(); session_destroy(); } - -/** - * @brief Calculate the hash that is needed for the "Friendica" cookie - * - * @param array $user Record from "user" table - * - * @return string Hashed data - */ -function cookie_hash($user) { - return(hash("sha256", get_config("system", "site_prvkey"). - $user["uprvkey"]. - $user["password"])); -} - -/** - * @brief Set the "Friendica" cookie - * - * @param int $time - * @param array $user Record from "user" table - */ -function new_cookie($time, $user = array()) { - - if ($time != 0) - $time = $time + time(); - - if ($user) - $value = json_encode(array("uid" => $user["uid"], - "hash" => cookie_hash($user), - "ip" => $_SERVER['REMOTE_ADDR'])); - else - $value = ""; - - setcookie("Friendica", $value, $time, "/", "", - (get_config('system', 'ssl_policy') == SSL_POLICY_FULL), true); - -} diff --git a/include/security.php b/include/security.php index c379518562..93df6ff255 100644 --- a/include/security.php +++ b/include/security.php @@ -1,5 +1,41 @@ $user["uid"], + "hash" => cookie_hash($user), + "ip" => $_SERVER['REMOTE_ADDR'])); + else + $value = ""; + + setcookie("Friendica", $value, $time, "/", "", + (get_config('system', 'ssl_policy') == SSL_POLICY_FULL), true); + +} + function authenticate_success($user_record, $login_initial = false, $interactive = false, $login_refresh = false) { $a = get_app(); @@ -94,6 +130,24 @@ function authenticate_success($user_record, $login_initial = false, $interactive } + + if ($login_initial) { + // If the user specified to remember the authentication, then set a cookie + // that expires after one week (the default is when the browser is closed). + // The cookie will be renewed automatically. + // The week ensures that sessions will expire after some inactivity. + if ($_SESSION['remember']) { + logger('Injecting cookie for remembered user '. $_SESSION['remember_user']['nickname']); + new_cookie(604800, $user_record); + unset($_SESSION['remember']); + } + else { + new_cookie(0); // 0 means delete on browser exit + } + } + + + if ($login_initial) { call_hooks('logged_in', $a->user); diff --git a/mod/openid.php b/mod/openid.php index 59a7530140..b45cd97975 100644 --- a/mod/openid.php +++ b/mod/openid.php @@ -30,7 +30,7 @@ function openid_content(App $a) { // mod/settings.php in 8367cad so it might have left mixed // records in the user table // - $r = q("SELECT * FROM `user` + $r = q("SELECT *, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey` FROM `user` WHERE ( `openid` = '%s' OR `openid` = '%s' ) AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 From 2310bf994a10996d2b6986e70d56765974581480 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 12 Mar 2017 03:55:22 -0400 Subject: [PATCH 32/41] Normalize line endings instead of adding
    before Markdown() --- include/bb2diaspora.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index f18a0f3c27..e509999236 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -39,9 +39,9 @@ function diaspora2bb($s) { $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8'); // Handles single newlines - $s = str_replace("\r", '
    ', $s); - + $s = str_replace("\r\n", "\n", $s); $s = str_replace("\n", " \n", $s); + $s = str_replace("\r", " \n", $s); // Replace lonely stars in lines not starting with it with literal stars $s = preg_replace('/^([^\*]+)\*([^\*]*)$/im', '$1\*$2', $s); From 30d82f43910f97b0e99c2e7235cbc5c812d39c35 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Sun, 12 Mar 2017 14:40:08 +0100 Subject: [PATCH 33/41] mark the develop version in the version string --- VERSION | 2 +- boot.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index d5c0c99142..ded27b074d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.1 +3.5.2-dev diff --git a/boot.php b/boot.php index c8e84e5c75..285c70370e 100644 --- a/boot.php +++ b/boot.php @@ -38,7 +38,7 @@ require_once('include/dbstructure.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_CODENAME', 'Asparagus'); -define ( 'FRIENDICA_VERSION', '3.5.1' ); +define ( 'FRIENDICA_VERSION', '3.5.2-dev' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1215 ); From 80e58964ceac470b2571e542e53de2558b3fb499 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 13 Mar 2017 00:09:32 +0000 Subject: [PATCH 34/41] Standard stuff --- include/Contact.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 3d4d6ded7f..85dc1008eb 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -717,7 +717,7 @@ function posts_from_gcontact(App $a, $gcontact_id) { $o = conversation($a,$r,'community',false); - $o .= alt_pager($a,count($r)); + $o .= alt_pager($a, count($r)); return $o; } @@ -760,7 +760,7 @@ function posts_from_contact_url(App $a, $contact_url) { $o = conversation($a,$r,'community',false); - $o .= alt_pager($a,count($r)); + $o .= alt_pager($a, count($r)); return $o; } From eb6a6228f752d56e20b897dec8b9525281363ef0 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 13 Mar 2017 05:57:37 +0000 Subject: [PATCH 35/41] more spaces --- include/Contact.php | 4 ++-- mod/community.php | 4 ++-- mod/network.php | 6 +++--- mod/profile.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 85dc1008eb..9fd61f8d5e 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -715,7 +715,7 @@ function posts_from_gcontact(App $a, $gcontact_id) { intval($a->pager['itemspage']) ); - $o = conversation($a,$r,'community',false); + $o = conversation($a, $r, 'community', false); $o .= alt_pager($a, count($r)); @@ -758,7 +758,7 @@ function posts_from_contact_url(App $a, $contact_url) { intval($a->pager['itemspage']) ); - $o = conversation($a,$r,'community',false); + $o = conversation($a, $r, 'community', false); $o .= alt_pager($a, count($r)); diff --git a/mod/community.php b/mod/community.php index 91b09bba9a..1743304010 100644 --- a/mod/community.php +++ b/mod/community.php @@ -84,9 +84,9 @@ function community_content(App $a, $update = 0) { // we behave the same in message lists as the search module - $o .= conversation($a,$s,'community',$update); + $o .= conversation($a, $s, 'community', $update); - $o .= alt_pager($a,count($r)); + $o .= alt_pager($a, count($r)); return $o; } diff --git a/mod/network.php b/mod/network.php index 284bf3d961..a1181a74cb 100644 --- a/mod/network.php +++ b/mod/network.php @@ -773,13 +773,13 @@ function network_content(App $a, $update = 0) { $mode = (($nouveau) ? 'network-new' : 'network'); - $o .= conversation($a,$items,$mode,$update); + $o .= conversation($a, $items, $mode, $update); if (!$update) { - if (get_pconfig(local_user(),'system','infinite_scroll')) { + if (get_pconfig(local_user(), 'system', 'infinite_scroll')) { $o .= scroll_loader(); } else { - $o .= alt_pager($a,count($items)); + $o .= alt_pager($a, count($items)); } } diff --git a/mod/profile.php b/mod/profile.php index 93f2602e23..fbce509d29 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -318,10 +318,10 @@ function profile_content(App $a, $update = 0) { ); } - $o .= conversation($a,$items,'profile',$update); + $o .= conversation($a, $items, 'profile', $update); if (!$update) { - $o .= alt_pager($a,count($items)); + $o .= alt_pager($a, count($items)); } return $o; From cbaf196f509cc5b21f04574cbf80ddd3ecf9f8db Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Mon, 13 Mar 2017 11:57:10 +0100 Subject: [PATCH 36/41] Only remove the "remember me" cookie at submitting the auth form Fixes loss of remember (Friendica) cookie on switching Managed accounts --- include/auth.php | 4 ++++ include/security.php | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/auth.php b/include/auth.php index 62ca3563a4..8512abe486 100644 --- a/include/auth.php +++ b/include/auth.php @@ -179,6 +179,10 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' goaway(z_root()); } + if ( ! $_POST['remember']) { + new_cookie(0); // 0 means delete on browser exit + } + // if we haven't failed up this point, log them in. $_SESSION['remember'] = $_POST['remember']; $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); diff --git a/include/security.php b/include/security.php index 93df6ff255..23fc400b3a 100644 --- a/include/security.php +++ b/include/security.php @@ -141,9 +141,6 @@ function authenticate_success($user_record, $login_initial = false, $interactive new_cookie(604800, $user_record); unset($_SESSION['remember']); } - else { - new_cookie(0); // 0 means delete on browser exit - } } From f2a0c9fad16286c4471fe1bffb2775eb2f3f5116 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 13 Mar 2017 12:10:03 -0400 Subject: [PATCH 37/41] Fix scrollToItem breaking dropItem functionality - Add doc - Refactor function by removing double jQuery wrapping --- view/theme/frio/js/theme.js | 27 ++++++++++++++--------- view/theme/frio/templates/wall_thread.tpl | 4 ++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/view/theme/frio/js/theme.js b/view/theme/frio/js/theme.js index b4ba2fd357..62cd85df9b 100644 --- a/view/theme/frio/js/theme.js +++ b/view/theme/frio/js/theme.js @@ -573,31 +573,38 @@ String.prototype.rtrim = function() { return trimmed; }; -// Scroll to a specific item and highlight it -// Note: jquery.color.js is needed -function scrollToItem(itemID) { - if( typeof itemID === "undefined") +/** + * Scroll the screen to the item element whose id is provided, then highlights it + * + * Note: jquery.color.js is required + * + * @param {string} elementId The item element id + * @returns {undefined} + */ +function scrollToItem(elementId) { + if (typeof elementId === "undefined") { return; + } - var elm = $('#'+itemID); + var $el = $(document.getElementById(elementId)); // Test if the Item exists - if(!elm.length) + if (!$el.length) { return; + } // Define the colors which are used for highlighting var colWhite = {backgroundColor:'#F5F5F5'}; var colShiny = {backgroundColor:'#FFF176'}; - // Get the Item Position (we need to substract 100 to match - // correct position - var itemPos = $(elm).offset().top - 100; + // Get the Item Position (we need to substract 100 to match correct position + var itemPos = $el.offset().top - 100; // Scroll to the DIV with the ID (GUID) $('html, body').animate({ scrollTop: itemPos }, 400, function() { // Highlight post/commenent with ID (GUID) - $(elm).animate(colWhite, 1000).animate(colShiny).animate(colWhite, 600); + $el.animate(colWhite, 1000).animate(colShiny).animate(colWhite, 600); }); } diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl index 1977f541c2..e71dc7b84c 100644 --- a/view/theme/frio/templates/wall_thread.tpl +++ b/view/theme/frio/templates/wall_thread.tpl @@ -68,9 +68,9 @@ as the value of $top_child_total (this is done at the end of this file) {{* Use a different div container in dependence max thread-level = 7 *}} {{if $item.thread_level<7}} -
    +
    {{else}} -
    +
    {{/if}}
    {{* Put addional actions in a top-right dropdown menu *}} From 327b00117defd8b233ef86667733729b8292e1e9 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 13 Mar 2017 12:12:13 -0400 Subject: [PATCH 38/41] Improve dropItem() functionality - Drop the obsolete `#` char - Add error case when deleting item - Add item drop support to search items - Add doc --- view/theme/frio/js/textedit.js | 32 ++++++++++++++--------- view/theme/frio/templates/search_item.tpl | 4 +-- view/theme/frio/templates/wall_thread.tpl | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/view/theme/frio/js/textedit.js b/view/theme/frio/js/textedit.js index 9226646b7b..02191f33de 100644 --- a/view/theme/frio/js/textedit.js +++ b/view/theme/frio/js/textedit.js @@ -162,21 +162,29 @@ function qCommentInsert(obj,id) { function confirmDelete() { return confirm(aStr.delitem); } -function dropItem(url, object) { +/** + * Hide and removes an item element from the DOM after the deletion url is + * successful, restore it else. + * + * @param {string} url The item removal URL + * @param {string} elementId The DOM id of the item element + * @returns {undefined} + */ +function dropItem(url, elementId) { var confirm = confirmDelete(); - //if the first character of the object is #, remove it because - // we use getElementById which don't need the # - // getElementByID selects elements even if there are special characters - // in the ID (like %) which won't work with jQuery - /// @todo ceck if we can solve this in the template - object = object.indexOf('#') == 0 ? object.substring(1) : object; - - if(confirm) { + if (confirm) { $('body').css('cursor', 'wait'); - $(document.getElementById(object)).fadeTo('fast', 0.33, function () { - $.get(url).done(function() { - $(document.getElementById(object)).remove(); + + var $el = $(document.getElementById(elementId)); + + $el.fadeTo('fast', 0.33, function () { + $.get(url).then(function() { + $el.remove(); + }).error(function() { + // @todo Show related error message + $el.show(); + }).always(function() { $('body').css('cursor', 'auto'); }); }); diff --git a/view/theme/frio/templates/search_item.tpl b/view/theme/frio/templates/search_item.tpl index 90fbe03bbc..0a6eca0c27 100644 --- a/view/theme/frio/templates/search_item.tpl +++ b/view/theme/frio/templates/search_item.tpl @@ -7,7 +7,7 @@ -
    +
    {{* Put additional actions in a top-right dropdown menu *}} @@ -54,7 +54,7 @@ {{if $item.drop.dropping}}
  • - {{$item.drop.delete}} + {{$item.drop.delete}}
  • {{/if}} diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl index e71dc7b84c..85091cf1c6 100644 --- a/view/theme/frio/templates/wall_thread.tpl +++ b/view/theme/frio/templates/wall_thread.tpl @@ -129,7 +129,7 @@ as the value of $top_child_total (this is done at the end of this file) {{if $item.drop.dropping}}
  • - {{$item.drop.delete}} + {{$item.drop.delete}}
  • {{/if}} From 8517ba1fab5257fbd3e5cb99677797b5dd9ed69e Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Mon, 13 Mar 2017 23:08:03 +0100 Subject: [PATCH 39/41] Remove extra space after open parentheses --- include/auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/auth.php b/include/auth.php index 8512abe486..57e9d9bf61 100644 --- a/include/auth.php +++ b/include/auth.php @@ -179,7 +179,7 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' goaway(z_root()); } - if ( ! $_POST['remember']) { + if (! $_POST['remember']) { new_cookie(0); // 0 means delete on browser exit } From 0b46a5f935e7e3a669e68455dce294dc70a94182 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Mon, 13 Mar 2017 23:09:09 +0100 Subject: [PATCH 40/41] Standards: add braces (thanks @Hypolite) --- include/security.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/security.php b/include/security.php index 23fc400b3a..afb37a72d8 100644 --- a/include/security.php +++ b/include/security.php @@ -21,15 +21,18 @@ function cookie_hash($user) { */ function new_cookie($time, $user = array()) { - if ($time != 0) + if ($time != 0) { $time = $time + time(); + } - if ($user) + if ($user) { $value = json_encode(array("uid" => $user["uid"], "hash" => cookie_hash($user), "ip" => $_SERVER['REMOTE_ADDR'])); - else + } + else { $value = ""; + } setcookie("Friendica", $value, $time, "/", "", (get_config('system', 'ssl_policy') == SSL_POLICY_FULL), true); From 0143369e54bb8a0c7b6c9b970ffcde1fd60171ff Mon Sep 17 00:00:00 2001 From: rabuzarus Date: Tue, 14 Mar 2017 18:31:03 +0100 Subject: [PATCH 41/41] limit pagination page buttons to max 10 --- include/text.php | 9 +++-- view/theme/frio/css/style.css | 52 +++++++++++++++++++++----- view/theme/frio/templates/paginate.tpl | 16 ++++---- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/include/text.php b/include/text.php index 580bd95fc7..6619dec93a 100644 --- a/include/text.php +++ b/include/text.php @@ -291,8 +291,8 @@ function paginate_data(App $a, $count = null) { } $url = $stripped; - $data = array(); + function _l(&$d, $name, $url, $text, $class = '') { if (strpos($url, '?') === false && ($pos = strpos($url, '&')) !== false) { $url = substr($url, 0, $pos) . '?' . substr($url, $pos + 1); @@ -318,9 +318,10 @@ function paginate_data(App $a, $count = null) { $numstart = 1; $numstop = $numpages; - if ($numpages > 14) { - $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); - $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); + // Limit the number of displayed page number buttons. + if ($numpages > 8) { + $numstart = (($pagenum > 4) ? ($pagenum - 4) : 1); + $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 8)); } $pages = array(); diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 34bcb833db..8d7a5f7696 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2509,21 +2509,53 @@ body .tread-wrapper .hovercard:hover .hover-card-content a { } /* Pagination improvements */ +.pagination { + text-align: center; + display: block; +} .pagination > li > a, .pagination > li > span { - color: $link_color; + color: $link_color; + float: none; } -.pagination>.active>a, -.pagination>.active>a:focus, -.pagination>.active>a:hover, -.pagination>.active>span, -.pagination>.active>span:focus, -.pagination>.active>span:hover { - background-color: $link_color; +.pagination>li>a:hover, +.pagination>li>span:hover { + color: $link_hover_color; +} +.pagination > .active > a, +.pagination > .active > a:focus, +.pagination > .active > a:hover, +.pagination > .active > span, +.pagination > .active > span:focus, +.pagination > .active > span:hover { + background-color: $link_color; border-color: $link_color; + border-radius: 3px; } -.disabled > a { - pointer-events: none; +.pagination li.pager_n a { + margin-left: 3px; + border-radius: 3px; +} +.pagination .pager_prev a { + margin-left: -5px; + margin-right: 4px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pagination .pager_next a { + margin-left: 4px; + margin-right: -5px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pager .next > a, +.pager .previous > a { + float: none; + border-radius: 3px; +} +.pagination .disabled > a, +.pager .disabled > a { + display: none; } /* diff --git a/view/theme/frio/templates/paginate.tpl b/view/theme/frio/templates/paginate.tpl index ab65cdd406..252dd7e5b0 100644 --- a/view/theme/frio/templates/paginate.tpl +++ b/view/theme/frio/templates/paginate.tpl @@ -1,14 +1,16 @@ + {{* Pager template, uses output of paginate_data() in include/text.php *}} + {{if $pager}} -
    - {{if $pager.first}}
  • {{$pager.first.text}}
  • {{/if}} +
    + {{if $pager.last}}
  • >∣
  • {{/if}} + {{/if}}