From 301fea8684f194bd622994494706b3676fdea299 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 05:51:39 -0400 Subject: [PATCH 01/24] ping.php performance: caching baseurl --- boot.php | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/boot.php b/boot.php index e49ffbd22..4fefe6f7e 100644 --- a/boot.php +++ b/boot.php @@ -787,27 +787,29 @@ class App { if (!is_object($this)) return(self::$a->get_baseurl($ssl)); - $scheme = $this->scheme; + if (!$this->baseurl) { + $scheme = $this->scheme; - if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { - if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) - $scheme = 'https'; - - // Basically, we have $ssl = true on any links which can only be seen by a logged in user - // (and also the login link). Anything seen by an outsider will have it turned off. - - if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { - if($ssl) + if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { + if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) $scheme = 'https'; - else - $scheme = 'http'; + + // Basically, we have $ssl = true on any links which can only be seen by a logged in user + // (and also the login link). Anything seen by an outsider will have it turned off. + + if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { + if($ssl) + $scheme = 'https'; + else + $scheme = 'http'; + } } + + if (get_config('config','hostname') != "") + $this->hostname = get_config('config','hostname'); + + $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); } - - if (get_config('config','hostname') != "") - $this->hostname = get_config('config','hostname'); - - $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); return $this->baseurl; } From 63e5342ced5720d1fd55b8d09462edd945474e32 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 05:54:26 -0400 Subject: [PATCH 02/24] ping.php performance: removing datetime_convert --- include/datetime.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/include/datetime.php b/include/datetime.php index ea98f01fe..626e0b92c 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -328,12 +328,12 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke * @param string $posted_date * @param string $format (optional) Parsed with sprintf() * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago - * + * * @return string with relative date */ -function relative_date($posted_date,$format = null) { +function relative_date($posted_date, $format = null) { - $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date); + $localtime = $posted_date . ' UTC'; $abs = strtotime($localtime); @@ -347,13 +347,6 @@ function relative_date($posted_date,$format = null) { return t('less than a second ago'); } - /* - $time_append = ''; - if ($etime >= 86400) { - $time_append = ' ('.$localtime.')'; - } - */ - $a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')), 30 * 24 * 60 * 60 => array( t('month'), t('months')), 7 * 24 * 60 * 60 => array( t('week'), t('weeks')), @@ -368,8 +361,9 @@ function relative_date($posted_date,$format = null) { if ($d >= 1) { $r = round($d); // translators - e.g. 22 hours ago, 1 minute ago - if(! $format) + if(! $format) { $format = t('%1$d %2$s ago'); + } return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1])); } From 747f902e21f7ddf9e94ede295fe3c12c3ade2eb1 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 05:55:19 -0400 Subject: [PATCH 03/24] ping.php performance: optimizing session_write queries --- include/session.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/session.php b/include/session.php index 8f9d64606..4e7befb1b 100644 --- a/include/session.php +++ b/include/session.php @@ -40,12 +40,12 @@ function ref_session_write ($id,$data) { if($session_exists) { $r = q("UPDATE `session` SET `data` = '%s' - WHERE `data` != '%s' AND `sid` = '%s'", + WHERE `sid` = '%s' AND `data` != '%s'", dbesc($data), dbesc($data), dbesc($id)); $r = q("UPDATE `session` SET `expire` = '%s' - WHERE `expire` != '%s' AND `sid` = '%s'", + WHERE `sid` = '%s' AND `expire` != '%s'", dbesc($expire), dbesc($expire), dbesc($id)); } else $r = q("INSERT INTO `session` From f1c855e755aa1a51bba210221a5a2c1850cfec88 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 06:28:16 -0400 Subject: [PATCH 04/24] ping.php performance: Cache notification bbcode - Add two fields to notifiy table to store cached bbcode result - Add bbcode conversion on notif creation - Add postfact caching if cache field is empty on retrieval --- boot.php | 2 +- database.sql | 2 ++ include/dbstructure.php | 2 ++ include/enotify.php | 35 +++++++++++++++++++++++++---- mod/ping.php | 49 +++++++++++++++++++++++------------------ update.php | 2 +- 6 files changed, 65 insertions(+), 27 deletions(-) diff --git a/boot.php b/boot.php index 4fefe6f7e..cb4feef90 100644 --- a/boot.php +++ b/boot.php @@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_CODENAME', 'Asparagus'); define ( 'FRIENDICA_VERSION', '3.5.1-dev' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); -define ( 'DB_UPDATE_VERSION', 1206 ); +define ( 'DB_UPDATE_VERSION', 1207 ); /** * @brief Constant with a HTML line break. diff --git a/database.sql b/database.sql index f12746e7e..c5fd49ba0 100644 --- a/database.sql +++ b/database.sql @@ -655,6 +655,8 @@ CREATE TABLE IF NOT EXISTS `notify` ( `seen` tinyint(1) NOT NULL DEFAULT 0, `verb` varchar(255) NOT NULL DEFAULT '', `otype` varchar(16) NOT NULL DEFAULT '', + `name_cache` tinytext, + `msg_name` mediumtext, PRIMARY KEY(`id`), INDEX `uid` (`uid`) ) DEFAULT CHARSET=utf8mb4; diff --git a/include/dbstructure.php b/include/dbstructure.php index fdf09d90d..8053965e0 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1036,6 +1036,8 @@ function db_definition($charset) { "seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "otype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""), + "name_cache" => array("type" => "tinytext"), + "msg_cache" => array("type" => "mediumtext") ), "indexes" => array( "PRIMARY" => array("id"), diff --git a/include/enotify.php b/include/enotify.php index 4973bedc2..bcb2ebe7c 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -418,6 +418,7 @@ function notification($params) { $datarray = array(); $datarray['hash'] = $hash; $datarray['name'] = $params['source_name']; + $datarray['name_cache'] = strip_tags(bbcode($params['source_name'])); $datarray['url'] = $params['source_link']; $datarray['photo'] = $params['source_photo']; $datarray['date'] = datetime_convert(); @@ -439,7 +440,7 @@ function notification($params) { // create notification entry in DB - $r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`) + $r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`, `name_cache`) values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s')", dbesc($datarray['hash']), dbesc($datarray['name']), @@ -452,7 +453,8 @@ function notification($params) { intval($datarray['parent']), intval($datarray['type']), dbesc($datarray['verb']), - dbesc($datarray['otype']) + dbesc($datarray['otype']), + dbesc($datarray["name_cache"]) ); $r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' AND `uid` = %d LIMIT 1", @@ -494,8 +496,10 @@ function notification($params) { $itemlink = $a->get_baseurl().'/notify/view/'.$notify_id; $msg = replace_macros($epreamble, array('$itemlink' => $itemlink)); - $r = q("UPDATE `notify` SET `msg` = '%s' WHERE `id` = %d AND `uid` = %d", + $msg_cache = format_notification_message($datarray['name_cache'], strip_tags(bbcode($msg))); + $r = q("UPDATE `notify` SET `msg` = '%s', `msg_cache` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($msg), + dbesc($msg_cache), intval($notify_id), intval($params['uid']) ); @@ -778,4 +782,27 @@ function check_item_notification($itemid, $uid, $defaulttype = "") { if (isset($params["type"])) notification($params); } -?> + +/** + * @brief Formats a notification message with the notification author + * + * Replace the name with {0} but ensure to make that only once. The {0} is used + * later and prints the name in bold. + * + * @param string $name + * @param string $message + * @return string Formatted message + */ +function format_notification_message($name, $message) { + if ($name != '') { + $pos = strpos($message, $name); + } else { + $pos = false; + } + + if ($pos !== false) { + $message = substr_replace($message, '{0}', $pos, strlen($name)); + } + + return $message; +} \ No newline at end of file diff --git a/mod/ping.php b/mod/ping.php index 8c28e7474..a90537122 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -344,6 +344,12 @@ function ping_init(&$a) { killme(); } +/** + * @brief Retrieves the notifications array for the given user ID + * + * @param int $uid + * @return array + */ function ping_get_notifications($uid) { $result = array(); @@ -372,46 +378,47 @@ function ping_get_notifications($uid) { $seensql = ""; $order = "DESC"; $offset = 0; - } elseif (!$r) + } elseif (!$r) { $quit = true; - else + } else { $offset += 50; - + } foreach ($r AS $notification) { - if (is_null($notification["visible"])) + if (is_null($notification["visible"])) { $notification["visible"] = true; + } - if (is_null($notification["spam"])) + if (is_null($notification["spam"])) { $notification["spam"] = 0; + } - if (is_null($notification["deleted"])) + if (is_null($notification["deleted"])) { $notification["deleted"] = 0; + } - $notification["message"] = strip_tags(bbcode($notification["msg"])); - $notification["name"] = strip_tags(bbcode($notification["name"])); + if ($notification["msg_cache"]) { + $notification["name"] = $notification["name_cache"]; + $notification["message"] = $notification["msg_cache"]; + } else { + $notification["name"] = strip_tags(bbcode($notification["name"])); + $notification["message"] = format_notification_message($notification["name"], strip_tags(bbcode($notification["msg"]))); - // Replace the name with {0} but ensure to make that only once - // The {0} is used later and prints the name in bold. + q("UPDATE `notify` SET `name_cache` = '%s', `msg_cache` = '%s' WHERE `id` = %d", + dbesc($notification["name"]), + dbesc($notification["message"]), + intval($notification["id"]) + ); + } - if ($notification['name'] != "") - $pos = strpos($notification["message"],$notification['name']); - else - $pos = false; - - if ($pos !== false) - $notification["message"] = substr_replace($notification["message"],"{0}",$pos,strlen($notification["name"])); - - $notification['href'] = $a->get_baseurl() . '/notify/view/' . $notification['id']; + $notification["href"] = $a->get_baseurl() . "/notify/view/" . $notification["id"]; if ($notification["visible"] AND !$notification["spam"] AND !$notification["deleted"] AND !is_array($result[$notification["parent"]])) { $result[$notification["parent"]] = $notification; } } - } while ((count($result) < 50) AND !$quit); - return($result); } diff --git a/update.php b/update.php index 756091113..5eab9c220 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ Date: Fri, 28 Oct 2016 06:50:08 -0400 Subject: [PATCH 05/24] ping.php performance: improve baseurl caching - Add cache invalidation on set_baseurl - Add documentation - Fix formatting --- boot.php | 58 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/boot.php b/boot.php index cb4feef90..279a9f292 100644 --- a/boot.php +++ b/boot.php @@ -781,16 +781,25 @@ class App { return($this->scheme); } + /** + * @brief Retrieves the Friendica instance base URL + * + * Caches both SSL and non-SSL version for performance + * + * @param bool $ssl + * @return string + */ function get_baseurl($ssl = false) { // Is the function called statically? - if (!is_object($this)) + if (!is_object($this)) { return(self::$a->get_baseurl($ssl)); + } - if (!$this->baseurl) { + if (!isset($this->baseurl[$ssl ? 'https' : 'http'])) { $scheme = $this->scheme; - if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { + if((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) $scheme = 'https'; @@ -798,45 +807,58 @@ class App { // (and also the login link). Anything seen by an outsider will have it turned off. if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { - if($ssl) + if($ssl) { $scheme = 'https'; - else + } else { $scheme = 'http'; + } } } - if (get_config('config','hostname') != "") - $this->hostname = get_config('config','hostname'); + if (get_config('config','hostname') != '') { + $this->hostname = get_config('config', 'hostname'); + } - $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); + $this->baseurl[$ssl ? 'https' : 'http'] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); } - return $this->baseurl; + return $this->baseurl[$ssl ? 'https' : 'http']; } + /** + * @brief Initializes the baseurl components + * + * Clears the baseurl cache to prevent inconstistencies + * + * @param string $url + */ function set_baseurl($url) { $parsed = @parse_url($url); - $this->baseurl = $url; + $this->baseurl = []; if($parsed) { $this->scheme = $parsed['scheme']; $hostname = $parsed['host']; - if(x($parsed,'port')) + if (x($parsed, 'port')) { $hostname .= ':' . $parsed['port']; - if(x($parsed,'path')) - $this->path = trim($parsed['path'],'\\/'); + } + if (x($parsed, 'path')) { + $this->path = trim($parsed['path'], '\\/'); + } - if (file_exists(".htpreconfig.php")) + if (file_exists(".htpreconfig.php")) { @include(".htpreconfig.php"); + } - if (get_config('config','hostname') != "") - $this->hostname = get_config('config','hostname'); + if (get_config('config', 'hostname') != '') { + $this->hostname = get_config('config', 'hostname'); + } - if (!isset($this->hostname) OR ($this->hostname == "")) + if (!isset($this->hostname) OR ($this->hostname == '')) { $this->hostname = $hostname; + } } - } function get_hostname() { From cc4363c5c62656512d64025ee25b5c25887303f0 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 12:29:55 -0400 Subject: [PATCH 06/24] ping.php performance: fix formatting --- boot.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/boot.php b/boot.php index 279a9f292..895530351 100644 --- a/boot.php +++ b/boot.php @@ -793,21 +793,22 @@ class App { // Is the function called statically? if (!is_object($this)) { - return(self::$a->get_baseurl($ssl)); + return self::$a->get_baseurl($ssl); } if (!isset($this->baseurl[$ssl ? 'https' : 'http'])) { $scheme = $this->scheme; - if((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { - if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) + if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { + if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) { $scheme = 'https'; + } // Basically, we have $ssl = true on any links which can only be seen by a logged in user // (and also the login link). Anything seen by an outsider will have it turned off. - if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { - if($ssl) { + if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { + if ($ssl) { $scheme = 'https'; } else { $scheme = 'http'; @@ -815,7 +816,7 @@ class App { } } - if (get_config('config','hostname') != '') { + if (get_config('config', 'hostname') != '') { $this->hostname = get_config('config', 'hostname'); } From bc407080d2832b2096b0f46e715d4f0fe2b97670 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 22:14:51 -0400 Subject: [PATCH 07/24] ping.php performance: improve documentation and formatting --- doc/database/db_notify.md | 36 +++++++++++++++++++----------------- include/session.php | 25 +++++++++++++++++++------ mod/ping.php | 4 ++-- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/doc/database/db_notify.md b/doc/database/db_notify.md index 5ef2aa7eb..b2bae6471 100644 --- a/doc/database/db_notify.md +++ b/doc/database/db_notify.md @@ -1,22 +1,24 @@ Table notify ============ -| Field | Description | Type | Null | Key | Default | Extra | -| ------ | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- | -| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment | -| hash | | varchar(64) | NO | | | | -| type | | int(11) | NO | | 0 | | -| name | | varchar(255) | NO | | | | -| url | | varchar(255) | NO | | | | -| photo | | varchar(255) | NO | | | | -| date | | datetime | NO | | 0000-00-00 00:00:00 | | -| msg | | mediumtext | NO | | NULL | | -| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | | -| link | | varchar(255) | NO | | | | -| parent | | int(11) | NO | | 0 | | -| seen | | tinyint(1) | NO | | 0 | | -| verb | | varchar(255) | NO | | | | -| otype | | varchar(16) | NO | | | | -| iid | item.id | int(11) | NO | | 0 | | +| Field | Description | Type | Null | Key | Default | Extra | +| ---------- | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- | +| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment | +| hash | | varchar(64) | NO | | | | +| type | | int(11) | NO | | 0 | | +| name | | varchar(255) | NO | | | | +| url | | varchar(255) | NO | | | | +| photo | | varchar(255) | NO | | | | +| date | | datetime | NO | | 0000-00-00 00:00:00 | | +| msg | | mediumtext | YES | | NULL | | +| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | | +| link | | varchar(255) | NO | | | | +| iid | item.id | int(11) | NO | | 0 | | +| parent | | int(11) | NO | | 0 | | +| seen | | tinyint(1) | NO | | 0 | | +| verb | | varchar(255) | NO | | | | +| otype | | varchar(16) | NO | | | | +| name_cache | Cached bbcode parsing of name | tinytext | YES | | NULL | | +| msg_cache | Cached bbcode parsing of msg | mediumtext | YES | | NULL | | Return to [database documentation](help/database) diff --git a/include/session.php b/include/session.php index 4e7befb1b..23066be42 100644 --- a/include/session.php +++ b/include/session.php @@ -26,18 +26,30 @@ function ref_session_read ($id) { return ''; }} -if(! function_exists('ref_session_write')) { -function ref_session_write ($id,$data) { +/** + * @brief Standard PHP session write callback + * + * This callback updates the DB-stored session data and/or the expiration depending + * on the case. Uses the $session_expire global for existing session, 5 minutes + * for newly created session. + * + * @global bool $session_exists Whether a session with the given id already exists + * @global int $session_expire Session expiration delay in seconds + * @param string $id Session ID with format: [a-z0-9]{26} + * @param string $data Serialized session data + * @return boolean Returns false if parameters are missing, true otherwise + */ +function ref_session_write($id, $data) { global $session_exists, $session_expire; - if(! $id || ! $data) { + if (!$id || !$data) { return false; } $expire = time() + $session_expire; $default_expire = time() + 300; - if($session_exists) { + if ($session_exists) { $r = q("UPDATE `session` SET `data` = '%s' WHERE `sid` = '%s' AND `data` != '%s'", @@ -47,13 +59,14 @@ function ref_session_write ($id,$data) { SET `expire` = '%s' WHERE `sid` = '%s' AND `expire` != '%s'", dbesc($expire), dbesc($expire), dbesc($id)); - } else + } else { $r = q("INSERT INTO `session` SET `sid` = '%s', `expire` = '%s', `data` = '%s'", dbesc($id), dbesc($default_expire), dbesc($data)); + } return true; -}} +} if(! function_exists('ref_session_close')) { function ref_session_close() { diff --git a/mod/ping.php b/mod/ping.php index a90537122..0ed7eb3fe 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -347,8 +347,8 @@ function ping_init(&$a) { /** * @brief Retrieves the notifications array for the given user ID * - * @param int $uid - * @return array + * @param int $uid User id + * @return array Associative array of notifications */ function ping_get_notifications($uid) { From 0131656a06ddb7162e687cfa598a9d2aecea0a9d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 22:15:24 -0400 Subject: [PATCH 08/24] ping.php perfomance: reverting useless session write changes --- include/session.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/session.php b/include/session.php index 23066be42..5cf4bcc9c 100644 --- a/include/session.php +++ b/include/session.php @@ -52,12 +52,12 @@ function ref_session_write($id, $data) { if ($session_exists) { $r = q("UPDATE `session` SET `data` = '%s' - WHERE `sid` = '%s' AND `data` != '%s'", + WHERE `data` != '%s' AND `sid` = '%s'", dbesc($data), dbesc($data), dbesc($id)); $r = q("UPDATE `session` SET `expire` = '%s' - WHERE `sid` = '%s' AND `expire` != '%s'", + WHERE `expire` != '%s' AND `sid` = '%s'", dbesc($expire), dbesc($expire), dbesc($id)); } else { $r = q("INSERT INTO `session` From cd3f98d27dc6ffaa188cc81f0f50217cd8b3bf1d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 28 Oct 2016 22:27:26 -0400 Subject: [PATCH 09/24] ping.php improvement: db version bump --- boot.php | 2 +- update.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boot.php b/boot.php index 0be159540..5df6520db 100644 --- a/boot.php +++ b/boot.php @@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_CODENAME', 'Asparagus'); define ( 'FRIENDICA_VERSION', '3.5.1-dev' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); -define ( 'DB_UPDATE_VERSION', 1207 ); +define ( 'DB_UPDATE_VERSION', 1208 ); /** * @brief Constant with a HTML line break. diff --git a/update.php b/update.php index 5eab9c220..fa03ddd1a 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ Date: Sun, 30 Oct 2016 23:59:14 -0400 Subject: [PATCH 10/24] bbcode documentation: fix broken bookmark form: #^[url]...[/url] - Prevents the advance recognition of `^` in tags before bbcode() - Formatting - Documentation --- include/text.php | 53 +++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/include/text.php b/include/text.php index 5c9202c58..50e2e8193 100644 --- a/include/text.php +++ b/include/text.php @@ -769,71 +769,74 @@ function activity_match($haystack,$needle) { }} -if(! function_exists('get_tags')) { /** - * Pull out all #hashtags and @person tags from $s; + * Pull out all #hashtags and @person tags from $string; * We also get @person@domain.com - which would make * the regex quite complicated as tags can also * end a sentence. So we'll run through our results * and strip the period from any tags which end with one. * Returns array of tags found, or empty array. * - * @param string $s - * @return array + * @param string $string Post content + * @return array List of tag and person names */ -function get_tags($s) { +function get_tags($string) { $ret = array(); // Convert hashtag links to hashtags - $s = preg_replace("/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism", "#$2", $s); + $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string); // ignore anything in a code block - $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s); + $string = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $string); // Force line feeds at bbtags - $s = str_replace(array("[", "]"), array("\n[", "]\n"), $s); + $string = str_replace(array('[', ']'), array("\n[", "]\n"), $string); // ignore anything in a bbtag - $s = preg_replace('/\[(.*?)\]/sm','',$s); + $string = preg_replace('/\[(.*?)\]/sm', '', $string); // Match full names against @tags including the space between first and last // We will look these up afterward to see if they are full names or not recognisable. - if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) { - foreach($match[1] as $mtch) { - if(strstr($mtch,"]")) { + if (preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/', $string, $matches)) { + foreach ($matches[1] as $match) { + if (strstr($match, ']')) { // we might be inside a bbcode color tag - leave it alone continue; } - if(substr($mtch,-1,1) === '.') - $ret[] = substr($mtch,0,-1); - else - $ret[] = $mtch; + if (substr($match, -1, 1) === '.') { + $ret[] = substr($match, 0, -1); + } else { + $ret[] = $match; + } } } // Otherwise pull out single word tags. These can be @nickname, @first_last // and #hash tags. - if(preg_match_all('/([!#@][^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/',$s,$match)) { - foreach($match[1] as $mtch) { - if(strstr($mtch,"]")) { + if (preg_match_all('/([!#@][^\^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/', $string, $matches)) { + foreach($matches[1] as $match) { + if (strstr($match, ']')) { // we might be inside a bbcode color tag - leave it alone continue; } - if(substr($mtch,-1,1) === '.') - $mtch = substr($mtch,0,-1); + if (substr($match, -1, 1) === '.') { + $match = substr($match,0,-1); + } // ignore strictly numeric tags like #1 - if((strpos($mtch,'#') === 0) && ctype_digit(substr($mtch,1))) + if ((strpos($match, '#') === 0) && ctype_digit(substr($match, 1))) { continue; + } // try not to catch url fragments - if(strpos($s,$mtch) && preg_match('/[a-zA-z0-9\/]/',substr($s,strpos($s,$mtch)-1,1))) + if (strpos($string, $match) && preg_match('/[a-zA-z0-9\/]/', substr($string, strpos($string, $match) - 1, 1))) { continue; - $ret[] = $mtch; + } + $ret[] = $match; } } return $ret; -}} +} // From 63b1e822cdc6af84973805214eee4c0454a2ff4f Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 31 Oct 2016 00:00:12 -0400 Subject: [PATCH 11/24] bbcode documentation: improved webfinger profile regexp --- include/bbcode.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/bbcode.php b/include/bbcode.php index ed2325364..6d56587ab 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -892,8 +892,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal // we may need to restrict this further if it picks up too many strays // link acct:user@host to a webfinger profile redirector - $Text = preg_replace('/acct:(.*?)@(.*?)([ ,])/', 'acct:' . "$1@$2$3" . '',$Text); + $Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', 'acct:$1@$2',$Text); // Perform MAIL Search $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $Text); From db874f0fbe0429cd185c5420daf47db3cc96cc93 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 31 Oct 2016 14:27:19 -0400 Subject: [PATCH 12/24] ping.php improvement: using baser cache key --- boot.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/boot.php b/boot.php index 5df6520db..8dd43101c 100644 --- a/boot.php +++ b/boot.php @@ -800,7 +800,9 @@ class App { return self::$a->get_baseurl($ssl); } - if (!isset($this->baseurl[$ssl ? 'https' : 'http'])) { + $cache_index = $ssl ? 'https' : 'http'; + + if (!isset($this->baseurl[$cache_index])) { $scheme = $this->scheme; if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { @@ -824,9 +826,9 @@ class App { $this->hostname = get_config('config', 'hostname'); } - $this->baseurl[$ssl ? 'https' : 'http'] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); + $this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); } - return $this->baseurl[$ssl ? 'https' : 'http']; + return $this->baseurl[$cache_index]; } /** From 5e188a9250d42a82cd6b8e84d65875f3bc6067fb Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 1 Nov 2016 02:04:59 -0400 Subject: [PATCH 13/24] ping.php improvement: datetime.php formatting --- include/datetime.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/datetime.php b/include/datetime.php index 626e0b92c..16b134e90 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -325,7 +325,7 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke * Results relative to current timezone. * Limited to range of timestamps. * - * @param string $posted_date + * @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS) * @param string $format (optional) Parsed with sprintf() * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago * @@ -361,11 +361,11 @@ function relative_date($posted_date, $format = null) { if ($d >= 1) { $r = round($d); // translators - e.g. 22 hours ago, 1 minute ago - if(! $format) { + if (!$format) { $format = t('%1$d %2$s ago'); } - return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1])); + return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1])); } } } From 97c2e99d46efe9f2ff447acebe5d3e7239447d6c Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 1 Nov 2016 17:05:23 -0400 Subject: [PATCH 14/24] ping.php improvement: improving get_baseurl - Adding more documentation - Trying hard to make @annando happy --- boot.php | 69 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/boot.php b/boot.php index 8dd43101c..eb91b26ba 100644 --- a/boot.php +++ b/boot.php @@ -788,10 +788,18 @@ class App { /** * @brief Retrieves the Friendica instance base URL * - * Caches both SSL and non-SSL version for performance + * This function assembles the base URL from multiple parts: + * - Protocol is determined either by the request or a combination of + * system.ssl_policy and the $ssl parameter. + * - Host name is determined either by system.hostname or inferred from request + * - Path is inferred from SCRIPT_NAME * - * @param bool $ssl - * @return string + * Caches the result (depending on $ssl value) for performance. + * + * Note: $ssl parameter value doesn't directly correlate with the resulting protocol + * + * @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN + * @return string Friendica server base URL */ function get_baseurl($ssl = false) { @@ -800,34 +808,39 @@ class App { return self::$a->get_baseurl($ssl); } + // Arbitrary values, the resulting url protocol can be different $cache_index = $ssl ? 'https' : 'http'; - if (!isset($this->baseurl[$cache_index])) { - $scheme = $this->scheme; - - if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { - if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) { - $scheme = 'https'; - } - - // Basically, we have $ssl = true on any links which can only be seen by a logged in user - // (and also the login link). Anything seen by an outsider will have it turned off. - - if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { - if ($ssl) { - $scheme = 'https'; - } else { - $scheme = 'http'; - } - } - } - - if (get_config('config', 'hostname') != '') { - $this->hostname = get_config('config', 'hostname'); - } - - $this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); + // Cached value found, nothing to process + if (isset($this->baseurl[$cache_index])) { + return $this->baseurl[$cache_index]; } + + $scheme = $this->scheme; + + if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) { + if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) { + $scheme = 'https'; + } + + // Basically, we have $ssl = true on any links which can only be seen by a logged in user + // (and also the login link). Anything seen by an outsider will have it turned off. + + if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { + if ($ssl) { + $scheme = 'https'; + } else { + $scheme = 'http'; + } + } + } + + if (get_config('config', 'hostname') != '') { + $this->hostname = get_config('config', 'hostname'); + } + + $this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); + return $this->baseurl[$cache_index]; } From 6626ef64a91786ad7e6a32e03fdbc44f07c41bf6 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 1 Nov 2016 23:07:37 -0400 Subject: [PATCH 15/24] bbcode documentation: enable overline --- view/global.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/view/global.css b/view/global.css index 1bc2f11d6..bcf7174ea 100644 --- a/view/global.css +++ b/view/global.css @@ -27,6 +27,10 @@ a.btn, a.btn:hover { background-color: #2d2d2d; } +.overline { + text-decoration: overline; +} + /* List of social Networks */ img.connector, img.connector-disabled { height: 40px; From aff467adf2f399b64a05c332751cf517f4bf0099 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 1 Nov 2016 23:08:26 -0400 Subject: [PATCH 16/24] bbcode documentation: improve cleancss --- include/bbcode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bbcode.php b/include/bbcode.php index 6d56587ab..ebafc353a 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -146,7 +146,7 @@ function cleancss($input) { if (($char >= "a") and ($char <= "z")) $cleaned .= $char; - if (!(strpos(" #;:0123456789-_", $char) === false)) + if (!(strpos(" #;:0123456789-_.%", $char) === false)) $cleaned .= $char; } From 68bf1aa4cdd52eb0aab3eef02d5a357896c9fef3 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 2 Nov 2016 22:41:07 -0400 Subject: [PATCH 17/24] bbcode documentation: fix anchors on frio --- view/theme/frio/css/style.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 2be7d5cb4..d2467b135 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -38,6 +38,18 @@ body a { color: $link_color; text-decoration: none; } +/* Anchors incorrectly display with a fixed top menu. This global rule offsets all + * anchors so that accessing them with a # link will actually scroll the associated + * content in the visible part of the page. + * + * anchor.top should be the opposite of body.padding-top + */ +body a[name]:not([href]) { + display: block; + position: relative; + top: -110px; + visibility: hidden; +} body a:hover, body a:focus, body a:active, body a.active, body .btn-link:hover{ /*color: #59d6e4;*/ From 106f003447eae11060f026c48981ebaafd60f279 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 2 Nov 2016 22:42:19 -0400 Subject: [PATCH 18/24] bbcode documentation: BBCodes.md complete rewrite - Switched to table display to put BBCodes and result side-by-side - Added all missing BBCodes --- doc/BBCode.md | 739 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 571 insertions(+), 168 deletions(-) diff --git a/doc/BBCode.md b/doc/BBCode.md index d22f7afa5..aeb5e06c9 100644 --- a/doc/BBCode.md +++ b/doc/BBCode.md @@ -1,208 +1,611 @@ Friendica BBCode tags reference ======================== -* [Home](help) +* [Creating posts](help/Text_editor) -Inline ------ +## Inline + -
[u]underlined[/u]
: underlined + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[b]bold[/b]bold
[i]italic[/i]italic
[u]underlined[/u]underlined
[s]strike[/s]strike
[o]overline[/o]overline
[color=red]red[/color]red
[url=http://www.friendica.com]Friendica[/url]Friendica
[img]http://friendica.com/sites/default/files/friendika-32.png[/img]Immagine/foto
[img=64x32]http://friendica.com/sites/default/files/friendika-32.png[/img]
+
Note: provided height is simply discarded.
[size=xx-small]small text[/size]small text
[size=xx-large]big text[/size]big text
[size=20]exact size[/size] (size can be any number, in pixel)exact size
[font=serif]Serif font[/font]Serif font
-
[s]strike[/s]
: strike +### Links -
[color=red]red[/color]
: red + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[url]http://friendica.com[/url]http://friendica.com
[url=http://friendica.com]Friendica[/url]Friendica
[bookmark]http://friendica.com[/bookmark]

+#^[url]http://friendica.com[/url]

Friendica: http://friendica.com

[bookmark=http://friendica.com]Bookmark[/bookmark]

+#^[url=http://friendica.com]Bookmark[/url]

+#[url=http://friendica.com]^[/url][url=http://friendica.com]Bookmark[/url]

Friendica: Bookmark

[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url]Diaspora post with GUID
#Friendica#Friendica
@Mention@Mention
acct:account@friendica.host.com (WebFinger)acct:account@friendica.host.com
[mail]user@mail.example.com[/mail]user@mail.example.com
[mail=user@mail.example.com]Send an email to User[/mail]Send an email to User
-
[url=http://www.friendica.com]Friendica[/url]
: Friendica +## Blocks -
[img]http://friendica.com/sites/default/files/friendika-32.png[/img]
: Immagine/foto + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[p]A paragraph of text[/p]

A paragraph of text

Inline [code]code[/code] in a paragraphInline code in a paragraph
[code]Multi
line
code[/code]
Multi +line +code
[code=php]function text_highlight($s,$lang)[/code]
  1.  function text_highlight($s,$lang)
[quote]quote[/quote]
quote
[quote=Author]Author? Me? No, no, no...[/quote]Author wrote:
Author? Me? No, no, no...
[center]Centered text[/center]
Centered text
You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler] +
+ You should not read any further if you want to be surprised.
+ Click to open/close + +
+
+
[spoiler=Author]Spoiler quote[/spoiler] +
+ Author wrote:
+ Click to open/close + +
+
+
[hr] (horizontal line)
-
[size=xx-small]small text[/size]
: small text +### Titles -
[size=xx-large]big text[/size]
: big text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[h1]Title 1[/h1]

Title 1

[h2]Title 2[/h2]

Title 2

[h3]Title 3[/h3]

Title 3

[h4]Title 4[/h4]

Title 4

[h5]Title 5[/h5]
Title 5
[h6]Title 6[/h6]
Title 6
-
[size=20]exact size[/size] (size can be any number, in pixel)
: exact size +### Tables + + + + + + + + + + + + + + + + + +
BBCodeResult
[table]
+  [tr]
+    [th]Header 1[/th]
+    [th]Header 2[/th]
+    [th]Header 2[/th]
+  [/tr]
+  [tr]
+    [td]Cell 1[/td]
+    [td]Cell 2[/td]
+    [td]Cell 3[/td]
+  [/tr]
+  [tr]
+    [td]Cell 4[/td]
+    [td]Cell 5[/td]
+    [td]Cell 6[/td]
+  [/tr]
+[/table]
+ + + + + + + + + + + + + + + + + + +
Header 1Header 2Header 3
Cell 1Cell 2Cell 3
Cell 4Cell 5Cell 6
+
[table border=0] + + + + + + + + + + + + + + + + + + +
Header 1Header 2Header 3
Cell 1Cell 2Cell 3
Cell 4Cell 5Cell 6
+
[table border=1] + + + + + + + + + + + + + + + + + + +
Header 1Header 2Header 3
Cell 1Cell 2Cell 3
Cell 4Cell 5Cell 6
+
+### Lists + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[ul]
+  [li] First list element
+  [li] Second list element
+[/ul]
+[list]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[ol]
+  [*] First list element
+  [*] Second list element
+[/ol]
+[list=1]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[list=]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[list=i]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[list=I]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[list=a]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
[list=A]
+  [*] First list element
+  [*] Second list element
+[/list]
+
    +
  • First list element
  • +
  • Second list element
  • +
+
- - - -Block ------ - -
[code]code[/code]
- -code - -

 

- -
[code=php]function text_highlight($s,$lang)[/code]
- -
  1.  function text_highlight($s,$lang)
- -

 

- -
[quote]quote[/quote]
- -
quote
- -

 

- -
[quote=Author]Author? Me? No, no, no...[/quote]
- -Author wrote:
Author? Me? No, no, no...
- -

 

- -
[center]centered text[/center]
- -
centered text
- -

 

- -
You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]
- -You should not read any further if you want to be surprised.
*click to open/close* - -(The text between thhe opening and the closing of the spoiler tag will be visible once the link is clicked. So *"There is a happy end."* wont be visible until the spoiler is uncovered.) - -

 

- -**Table** -
[table border=1]
- [tr] 
-   [th]Tables now[/th]
- [/tr]
- [tr]
-   [td]Have headers[/td]
- [/tr]
-[/table]
- -
Tables now
Have headers
- -

 

- -**List** - -
[list]
- [*] First list element
- [*] Second list element
-[/list]
-
    -
  • First list element
    -
  • -
  • Second list element
  • -
- -[list] is equivalent to [ul] (unordered list). - -[ol] can be used instead of [list] to show an ordered list: - -
[ol]
- [*] First list element
- [*] Second list element
-[/ol]
-
  • First list element
  • Second list element
- -For more options on ordered lists, you can define the style of numeration on [list] argument: -
[list=1]
: decimal - -
[list=i]
: lover case roman - -
[list=I]
: upper case roman - -
[list=a]
: lover case alphabetic - -
[list=A] 
: upper case alphabetic - - - - -Embed ------- +## Embed You can embed video, audio and more in a message. -
[video]url[/video]
-
[audio]url[/audio]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
[video]url[/video]Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications.
[video]Video file url[/video] +[audio]Audio file url[/audio]Full URL to an ogg/ogv/oga/ogm/webm/mp4/mp3 file. An HTML5 player will be used to show it.
[youtube]Youtube URL[/youtube]Youtube video OEmbed display. May not embed an actual player.
[youtube]Youtube video ID[/youtube]Youtube player iframe embed.
[vimeo]Vimeo URL[/vimeo]Vimeo video OEmbed display. May not embed an actual player.
[vimeo]Vimeo video ID[/vimeo]Vimeo player iframe embed.
[iframe]URL[/iframe]General embed, iframe size is limited by the theme size for video players.
[url]*url*[/url]If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd). +Page title with a link to *url* will be shown.
-Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications. -*url* can be also full url to an ogg file. HTML5 tag will be used to show it. +## Map -
[url]*url*[/url]
+This require "openstreetmap" addon version 1.3 or newer. If the addon isn't activated, +the raw coordinates are shown instead. -If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd). -Page title with a link to *url* will be shown. + + + + + + + + + + + + + + + + + +
BBCodeResult
[map]address[/map]Embeds a map centered on this address.
[map=lat,long]Embeds a map centered on those coordinates.
[map]Embeds a map centered on the post's location.
-Map ---- +## Abstract for longer posts -
[map]address[/map]
-
[map=lat,long]
+If you want to spread your post to several third party networks you can have the problem that these networks have a length limitation like on Twitter. -You can embed maps from coordinates or addresses. -This require "openstreetmap" addon version 1.3 or newer. - ------------------------------------------------------------ - -Abstract for longer posts -------------------------- - -If you want to spread your post to several third party networks you can have the problem that these networks have (for example) a length limitation. -(Like on Twitter) - -Friendica is using a semi intelligent mechanism to generate a fitting abstract. -But it can be interesting to define an own abstract that will only be displayed on the external network. -This is done with the [abstract]-element. -Example: - -
[abstract]Totally interesting! A must-see! Please click the link![/abstract]
-I want to tell you a really boring story that you really never wanted 
-to hear.
- -Twitter would display the text "Totally interesting! A must-see! Please click the link!". -On Friendica you would only see the text after "I want to tell you a really ..." +Friendica is using a semi intelligent mechanism to generate a fitting abstract. +But it can be interesting to define a custom abstract that will only be displayed on the external network. +This is done with the [abstract]-element. + + + + + + + + + +
BBCodeResult
[abstract]Totally interesting! A must-see! Please click the link![/abstract]
+I want to tell you a really boring story that you really never wanted to hear.
Twitter would display the text "Totally interesting! A must-see! Please click the link!". +On Friendica you would only see the text after "I want to tell you a really ..."
It is even possible to define abstracts for separate networks: -
-[abstract]Hi friends Here are my newest pictures![abstract]
-[abstract=twit]Hi my dear Twitter followers. Do you want to see my new 
-pictures?[abstract]
-[abstract=apdn]Helly my dear followers on ADN. I made sone new pictures 
-that I wanted to share with you.[abstract]
-Today I was in the woods and took some real cool pictures ...
-
- -For Twitter and App.net the system will use the defined abstracts. -For other networks (e.g. when you are using the "statusnet" connector that is used to post to GNU Social) the general abstract element will be used. + + + + + + + + + +
BBCodeResult
+[abstract]Hi friends Here are my newest pictures![/abstract]
+[abstract=twit]Hi my dear Twitter followers. Do you want to see my new +pictures?[/abstract]
+[abstract=apdn]Helly my dear followers on ADN. I made sone new pictures +that I wanted to share with you.[/abstract]
+Today I was in the woods and took some real cool pictures ...
For Twitter and App.net the system will use the defined abstracts.
+For other networks (e.g. when you are using the "statusnet" connector that is used to post to GNU Social) the general abstract element will be used.
If you use (for example) the "buffer" connector to post to Facebook or Google+ you can use this element to define an abstract for a longer blogpost that you don't want to post completely to these networks. -Networks like Facebook or Google+ aren't length limited. -For this reason the [abstract] element isn't used. +Networks like Facebook or Google+ aren't length limited. +For this reason the [abstract] element isn't used. Instead you have to name the explicit network: -
-[abstract]These days I had a strange encounter ...[abstract]
-[abstract=goog]Helly my dear Google+ followers. You have to read my 
-newest blog post![abstract]
-[abstract=face]Hello my Facebook friends. These days happened something 
-really cool.[abstract]
-While taking pictures in the woods I had a really strange encounter ... 
+ + + + + + + + + +
BBCodeResult
+[abstract]These days I had a strange encounter...[/abstract]
+[abstract=goog]Helly my dear Google+ followers. You have to read my newest blog post![/abstract]
+[abstract=face]Hello my Facebook friends. These days happened something really cool.[/abstract]
+While taking pictures in the woods I had a really strange encounter...
Google and Facebook will show the respective abstracts while the other networks will show the default one.
+
Meanwhile, Friendica won't show any of the abstracts.
-The [abstract] element isn't working with the native OStatus connection or with connectors where we post the HTML. -(Like Tumblr, Wordpress or Pump.io) +The [abstract] element isn't working with the native OStatus connection or with connectors where we post the HTML like Tumblr, Wordpress or Pump.io. -Special -------- +## Special -If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode: + + + + + + + + + + + + + + + + + + + + + +
BBCodeResult
If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
+
    +
  • [noparse][b]bold[/b][/noparse]
  • +
  • [nobb][b]bold[/b][/nobb]
  • +
  • [pre][b]bold[/b][/pre]
  • +
+
[b]bold[/b]
[nosmile] is used to disable smilies on a post by post basis
+
+ [nosmile] ;-) :-O +
;-) :-O
Custom inline styles
+
+[style=text-shadow: 0 0 4px #CC0000;]You can change all the CSS properties of this block.[/style]
You can change all the CSS properties of this block.
Custom class block
+
+[class=custom]If the class exists, this block will have the custom class style applied.[/class]
<span class="custom">If the class exists,
this block will have the custom class
style applied.</span>
-
[noparse][b]bold[/b][/noparse]
: [b]bold[/b] From 3a2ec5e4db719d09e13f7c17488ebc1cf7a37e26 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Thu, 3 Nov 2016 14:00:20 +0100 Subject: [PATCH 19/24] missing placeholder for name_cache value --- include/enotify.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/enotify.php b/include/enotify.php index bcb2ebe7c..5b2bea297 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -441,7 +441,7 @@ function notification($params) { // create notification entry in DB $r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`, `name_cache`) - values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s')", + values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s')", dbesc($datarray['hash']), dbesc($datarray['name']), dbesc($datarray['url']), @@ -805,4 +805,4 @@ function format_notification_message($name, $message) { } return $message; -} \ No newline at end of file +} From 3579a1494506f8919a9ce2efd5404df7a027d0fe Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 3 Nov 2016 21:01:09 -0400 Subject: [PATCH 20/24] bbcode documentation: minor formatting changes --- include/text.php | 3 ++- view/theme/frio/css/style.css | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/text.php b/include/text.php index 50e2e8193..83eab1927 100644 --- a/include/text.php +++ b/include/text.php @@ -770,7 +770,8 @@ function activity_match($haystack,$needle) { /** - * Pull out all #hashtags and @person tags from $string; + * @brief Pull out all #hashtags and @person tags from $string. + * * We also get @person@domain.com - which would make * the regex quite complicated as tags can also * end a sentence. So we'll run through our results diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index d2467b135..e284310b8 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -45,7 +45,7 @@ body a { * anchor.top should be the opposite of body.padding-top */ body a[name]:not([href]) { - display: block; + display: block; position: relative; top: -110px; visibility: hidden; From 3d29b7745ccbffe1881798971474475b41aa554e Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 4 Nov 2016 11:20:47 -0400 Subject: [PATCH 21/24] bbcode documentation: minor style changes --- doc/BBCode.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/doc/BBCode.md b/doc/BBCode.md index aeb5e06c9..595c2da86 100644 --- a/doc/BBCode.md +++ b/doc/BBCode.md @@ -12,21 +12,21 @@ table.bbcodes { border: 1px solid #aaa; border-collapse: collapse; color: #000; - width: 100%; + width: 100%; } table.bbcodes > tr > th, table.bbcodes > tr > td, table.bbcodes > * > tr > th, table.bbcodes > * > tr > td { - border: 1px solid #aaa; - padding: 0.2em 0.4em + border: 1px solid #aaa; + padding: 0.2em 0.4em } table.bbcodes > tr > th, table.bbcodes > * > tr > th { - background-color: #f2f2f2; - text-align: center + background-color: #f2f2f2; + text-align: center } @@ -522,8 +522,8 @@ This is done with the [abstract]-element. [abstract]Totally interesting! A must-see! Please click the link![/abstract]
I want to tell you a really boring story that you really never wanted to hear. - Twitter would display the text "Totally interesting! A must-see! Please click the link!". -On Friendica you would only see the text after "I want to tell you a really ..." + Twitter would display the text
Totally interesting! A must-see! Please click the link!
+On Friendica you would only see the text after
I want to tell you a really ...
@@ -579,7 +579,7 @@ The [abstract] element isn't working with the native OStatus connection or with Result - If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
+ If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
  • [noparse][b]bold[/b][/noparse]
  • [nobb][b]bold[/b][/nobb]
  • @@ -608,4 +608,3 @@ The [abstract] element isn't working with the native OStatus connection or with
    <span class="custom">If the class exists,
    this block will have the custom class
    style applied.</span>
    - From 5459b00499c01bcf450669bcf42798f0cb049bef Mon Sep 17 00:00:00 2001 From: rabuzarus <> Date: Fri, 4 Nov 2016 16:44:49 +0100 Subject: [PATCH 22/24] cache: serialize the cache content directly in the cache class --- include/Photo.php | 1355 ++++++++++++++++++++++---------------------- include/Probe.php | 3 +- include/cache.php | 10 +- include/cron.php | 4 +- include/gprobe.php | 21 +- include/oembed.php | 61 +- include/photos.php | 31 + mod/photos.php | 2 - 8 files changed, 775 insertions(+), 712 deletions(-) diff --git a/include/Photo.php b/include/Photo.php index e734fed89..f1e2989d5 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -1,91 +1,97 @@ 'jpg', - 'image/png' => 'png', - 'image/gif' => 'gif' - ); - } else { - $t = array(); - $t['image/jpeg'] ='jpg'; - if (imagetypes() & IMG_PNG) $t['image/png'] = 'png'; - } + /** + * @brief supported mimetypes and corresponding file extensions + */ + static function supportedTypes() { + if (class_exists('Imagick')) { - return $t; - } - - public function __construct($data, $type=null) { - $this->imagick = class_exists('Imagick'); - $this->types = $this->supportedTypes(); - if (!array_key_exists($type,$this->types)){ - $type='image/jpeg'; - } - $this->type = $type; - - if($this->is_imagick() && $this->load_data($data)) { - return true; + // Imagick::queryFormats won't help us a lot there... + // At least, not yet, other parts of friendica uses this array + $t = array( + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif' + ); } else { - // Failed to load with Imagick, fallback - $this->imagick = false; + $t = array(); + $t['image/jpeg'] ='jpg'; + if (imagetypes() & IMG_PNG) { + $t['image/png'] = 'png'; + } } - return $this->load_data($data); - } - public function __destruct() { - if($this->image) { - if($this->is_imagick()) { - $this->image->clear(); - $this->image->destroy(); - return; - } - imagedestroy($this->image); + return $t; } - } - public function is_imagick() { - return $this->imagick; - } + public function __construct($data, $type=null) { + $this->imagick = class_exists('Imagick'); + $this->types = $this->supportedTypes(); + if (!array_key_exists($type,$this->types)){ + $type='image/jpeg'; + } + $this->type = $type; - /** - * Maps Mime types to Imagick formats - */ - public function get_FormatsMap() { - $m = array( - 'image/jpeg' => 'JPG', - 'image/png' => 'PNG', - 'image/gif' => 'GIF' - ); - return $m; - } + if ($this->is_imagick() && $this->load_data($data)) { + return true; + } else { + // Failed to load with Imagick, fallback + $this->imagick = false; + } + return $this->load_data($data); + } - private function load_data($data) { - if($this->is_imagick()) { - $this->image = new Imagick(); - try { + public function __destruct() { + if ($this->image) { + if ($this->is_imagick()) { + $this->image->clear(); + $this->image->destroy(); + return; + } + imagedestroy($this->image); + } + } + + public function is_imagick() { + return $this->imagick; + } + + /** + * @brief Maps Mime types to Imagick formats + */ + public function get_FormatsMap() { + $m = array( + 'image/jpeg' => 'JPG', + 'image/png' => 'PNG', + 'image/gif' => 'GIF' + ); + return $m; + } + + private function load_data($data) { + if ($this->is_imagick()) { + $this->image = new Imagick(); + try { $this->image->readImageBlob($data); } catch (Exception $e) { @@ -93,41 +99,43 @@ class Photo { return false; } - /** - * Setup the image to the format it will be saved to - */ - $map = $this->get_FormatsMap(); - $format = $map[$type]; - $this->image->setFormat($format); + /* + * Setup the image to the format it will be saved to + */ + $map = $this->get_FormatsMap(); + $format = $map[$type]; + $this->image->setFormat($format); - // Always coalesce, if it is not a multi-frame image it won't hurt anyway - $this->image = $this->image->coalesceImages(); + // Always coalesce, if it is not a multi-frame image it won't hurt anyway + $this->image = $this->image->coalesceImages(); - /** - * setup the compression here, so we'll do it only once - */ - switch($this->getType()){ - case "image/png": - $quality = get_config('system','png_quality'); - if((! $quality) || ($quality > 9)) - $quality = PNG_QUALITY; - /** - * From http://www.imagemagick.org/script/command-line-options.php#quality: - * - * 'For the MNG and PNG image formats, the quality value sets - * the zlib compression level (quality / 10) and filter-type (quality % 10). - * The default PNG "quality" is 75, which means compression level 7 with adaptive PNG filtering, - * unless the image has a color map, in which case it means compression level 7 with no PNG filtering' - */ - $quality = $quality * 10; - $this->image->setCompressionQuality($quality); - break; - case "image/jpeg": - $quality = get_config('system','jpeg_quality'); - if((! $quality) || ($quality > 100)) - $quality = JPEG_QUALITY; - $this->image->setCompressionQuality($quality); - } + /* + * setup the compression here, so we'll do it only once + */ + switch($this->getType()){ + case "image/png": + $quality = get_config('system','png_quality'); + if ((! $quality) || ($quality > 9)) { + $quality = PNG_QUALITY; + } + /* + * From http://www.imagemagick.org/script/command-line-options.php#quality: + * + * 'For the MNG and PNG image formats, the quality value sets + * the zlib compression level (quality / 10) and filter-type (quality % 10). + * The default PNG "quality" is 75, which means compression level 7 with adaptive PNG filtering, + * unless the image has a color map, in which case it means compression level 7 with no PNG filtering' + */ + $quality = $quality * 10; + $this->image->setCompressionQuality($quality); + break; + case "image/jpeg": + $quality = get_config('system','jpeg_quality'); + if ((! $quality) || ($quality > 100)) { + $quality = JPEG_QUALITY; + } + $this->image->setCompressionQuality($quality); + } // The 'width' and 'height' properties are only used by non-Imagick routines. $this->width = $this->image->getImageWidth(); @@ -139,7 +147,7 @@ class Photo { $this->valid = false; $this->image = @imagecreatefromstring($data); - if($this->image !== FALSE) { + if ($this->image !== false) { $this->width = imagesx($this->image); $this->height = imagesy($this->image); $this->valid = true; @@ -148,123 +156,125 @@ class Photo { return true; } - + return false; } - public function is_valid() { - if($this->is_imagick()) - return ($this->image !== FALSE); - return $this->valid; - } - - public function getWidth() { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) - return $this->image->getImageWidth(); - return $this->width; - } - - public function getHeight() { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) - return $this->image->getImageHeight(); - return $this->height; - } - - public function getImage() { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) { - /* Clean it */ - $this->image = $this->image->deconstructImages(); - return $this->image; + public function is_valid() { + if ($this->is_imagick()) { + return ($this->image !== false); + } + return $this->valid; } - return $this->image; - } - public function getType() { - if(!$this->is_valid()) - return FALSE; + public function getWidth() { + if (!$this->is_valid()) { + return false; + } - return $this->type; - } + if ($this->is_imagick()) { + return $this->image->getImageWidth(); + } + return $this->width; + } - public function getExt() { - if(!$this->is_valid()) - return FALSE; + public function getHeight() { + if (!$this->is_valid()) { + return false; + } - return $this->types[$this->getType()]; - } + if ($this->is_imagick()) { + return $this->image->getImageHeight(); + } + return $this->height; + } - public function scaleImage($max) { - if(!$this->is_valid()) - return FALSE; + public function getImage() { + if (!$this->is_valid()) { + return false; + } - $width = $this->getWidth(); - $height = $this->getHeight(); + if ($this->is_imagick()) { + /* Clean it */ + $this->image = $this->image->deconstructImages(); + return $this->image; + } + return $this->image; + } - $dest_width = $dest_height = 0; + public function getType() { + if (!$this->is_valid()) { + return false; + } - if((! $width)|| (! $height)) - return FALSE; + return $this->type; + } - if($width > $max && $height > $max) { + public function getExt() { + if (!$this->is_valid()) { + return false; + } + + return $this->types[$this->getType()]; + } + + public function scaleImage($max) { + if (!$this->is_valid()) { + return false; + } + + $width = $this->getWidth(); + $height = $this->getHeight(); + + $dest_width = $dest_height = 0; + + if ((! $width)|| (! $height)) { + return false; + } + + if ($width > $max && $height > $max) { // very tall image (greater than 16:9) // constrain the width - let the height float. - if((($height * 9) / 16) > $width) { + if ((($height * 9) / 16) > $width) { $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(( $height * $max ) / $width); + } elseif ($width > $height) { + // else constrain both dimensions + $dest_width = $max; + $dest_height = intval(( $height * $max ) / $width); + } else { + $dest_width = intval(( $width * $max ) / $height); + $dest_height = $max; } - - // else constrain both dimensions - - elseif($width > $height) { - $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); - } - else { - $dest_width = intval(( $width * $max ) / $height); - $dest_height = $max; - } - } - else { - if( $width > $max ) { - $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); - } - else { - if( $height > $max ) { + } else { + if ( $width > $max ) { + $dest_width = $max; + $dest_height = intval(( $height * $max ) / $width); + } else { + if ( $height > $max ) { // very tall image (greater than 16:9) // but width is OK - don't do anything - if((($height * 9) / 16) > $width) { + if ((($height * 9) / 16) > $width) { $dest_width = $width; - $dest_height = $height; - } - else { - $dest_width = intval(( $width * $max ) / $height); - $dest_height = $max; + $dest_height = $height; + } else { + $dest_width = intval(( $width * $max ) / $height); + $dest_height = $max; } + } else { + $dest_width = $width; + $dest_height = $height; + } + } } - else { - $dest_width = $width; - $dest_height = $height; - } - } - } - if($this->is_imagick()) { - /** + if ($this->is_imagick()) { + /* * If it is not animated, there will be only one iteration here, * so don't bother checking */ @@ -283,234 +293,253 @@ class Photo { $this->height = $this->image->getImageHeight(); return; - } - - - $dest = imagecreatetruecolor( $dest_width, $dest_height ); - imagealphablending($dest, false); - imagesavealpha($dest, true); - if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha - imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height); - if($this->image) - imagedestroy($this->image); - $this->image = $dest; - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } - - public function rotate($degrees) { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) { - $this->image->setFirstIterator(); - do { - $this->image->rotateImage(new ImagickPixel(), -$degrees); // ImageMagick rotates in the opposite direction of imagerotate() - } while ($this->image->nextImage()); - return; - } - - $this->image = imagerotate($this->image,$degrees,0); - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } - - public function flip($horiz = true, $vert = false) { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) { - $this->image->setFirstIterator(); - do { - if($horiz) $this->image->flipImage(); - if($vert) $this->image->flopImage(); - } while ($this->image->nextImage()); - return; - } - - $w = imagesx($this->image); - $h = imagesy($this->image); - $flipped = imagecreate($w, $h); - if($horiz) { - for ($x = 0; $x < $w; $x++) { - imagecopy($flipped, $this->image, $x, 0, $w - $x - 1, 0, 1, $h); - } - } - if($vert) { - for ($y = 0; $y < $h; $y++) { - imagecopy($flipped, $this->image, 0, $y, 0, $h - $y - 1, $w, 1); - } - } - $this->image = $flipped; - } - - public function orient($filename) { - if ($this->is_imagick()) { - // based off comment on http://php.net/manual/en/imagick.getimageorientation.php - $orientation = $this->image->getImageOrientation(); - switch ($orientation) { - case imagick::ORIENTATION_BOTTOMRIGHT: - $this->image->rotateimage("#000", 180); - break; - case imagick::ORIENTATION_RIGHTTOP: - $this->image->rotateimage("#000", 90); - break; - case imagick::ORIENTATION_LEFTBOTTOM: - $this->image->rotateimage("#000", -90); - break; } - $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); - return TRUE; - } - // based off comment on http://php.net/manual/en/function.imagerotate.php - if(!$this->is_valid()) - return FALSE; - - if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) - return; - - $exif = @exif_read_data($filename,null,true); - if(! $exif) - return; - - $ort = $exif['IFD0']['Orientation']; - - switch($ort) - { - case 1: // nothing - break; - - case 2: // horizontal flip - $this->flip(); - break; - - case 3: // 180 rotate left - $this->rotate(180); - break; - - case 4: // vertical flip - $this->flip(false, true); - break; - - case 5: // vertical flip + 90 rotate right - $this->flip(false, true); - $this->rotate(-90); - break; - - case 6: // 90 rotate right - $this->rotate(-90); - break; - - case 7: // horizontal flip + 90 rotate right - $this->flip(); - $this->rotate(-90); - break; - - case 8: // 90 rotate left - $this->rotate(90); - break; - } - - // logger('exif: ' . print_r($exif,true)); - return $exif; - - } - - - - public function scaleImageUp($min) { - if(!$this->is_valid()) - return FALSE; - - - $width = $this->getWidth(); - $height = $this->getHeight(); - - $dest_width = $dest_height = 0; - - if((! $width)|| (! $height)) - return FALSE; - - if($width < $min && $height < $min) { - if($width > $height) { - $dest_width = $min; - $dest_height = intval(( $height * $min ) / $width); - } - else { - $dest_width = intval(( $width * $min ) / $height); - $dest_height = $min; - } - } - else { - if( $width < $min ) { - $dest_width = $min; - $dest_height = intval(( $height * $min ) / $width); - } - else { - if( $height < $min ) { - $dest_width = intval(( $width * $min ) / $height); - $dest_height = $min; + $dest = imagecreatetruecolor( $dest_width, $dest_height ); + imagealphablending($dest, false); + imagesavealpha($dest, true); + if ($this->type=='image/png') { + imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha } - else { - $dest_width = $width; - $dest_height = $height; + imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height); + if ($this->image) { + imagedestroy($this->image); } - } + $this->image = $dest; + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); } - if($this->is_imagick()) - return $this->scaleImage($dest_width,$dest_height); + public function rotate($degrees) { + if (!$this->is_valid()) { + return false; + } - $dest = imagecreatetruecolor( $dest_width, $dest_height ); - imagealphablending($dest, false); - imagesavealpha($dest, true); - if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha - imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height); - if($this->image) - imagedestroy($this->image); - $this->image = $dest; - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } + if ($this->is_imagick()) { + $this->image->setFirstIterator(); + do { + $this->image->rotateImage(new ImagickPixel(), -$degrees); // ImageMagick rotates in the opposite direction of imagerotate() + } while ($this->image->nextImage()); + return; + } - - - public function scaleImageSquare($dim) { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) { - $this->image->setFirstIterator(); - do { - $this->image->scaleImage($dim, $dim); - } while ($this->image->nextImage()); - return; + $this->image = imagerotate($this->image,$degrees,0); + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); } - $dest = imagecreatetruecolor( $dim, $dim ); - imagealphablending($dest, false); - imagesavealpha($dest, true); - if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha - imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height); - if($this->image) - imagedestroy($this->image); - $this->image = $dest; - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } + public function flip($horiz = true, $vert = false) { + if (!$this->is_valid()) { + return false; + } + + if ($this->is_imagick()) { + $this->image->setFirstIterator(); + do { + if ($horiz) { + $this->image->flipImage(); + } + if ($vert) { + $this->image->flopImage(); + } + } while ($this->image->nextImage()); + return; + } + + $w = imagesx($this->image); + $h = imagesy($this->image); + $flipped = imagecreate($w, $h); + if ($horiz) { + for ($x = 0; $x < $w; $x++) { + imagecopy($flipped, $this->image, $x, 0, $w - $x - 1, 0, 1, $h); + } + } + if ($vert) { + for ($y = 0; $y < $h; $y++) { + imagecopy($flipped, $this->image, 0, $y, 0, $h - $y - 1, $w, 1); + } + } + $this->image = $flipped; + } + + public function orient($filename) { + if ($this->is_imagick()) { + // based off comment on http://php.net/manual/en/imagick.getimageorientation.php + $orientation = $this->image->getImageOrientation(); + switch ($orientation) { + case imagick::ORIENTATION_BOTTOMRIGHT: + $this->image->rotateimage("#000", 180); + break; + case imagick::ORIENTATION_RIGHTTOP: + $this->image->rotateimage("#000", 90); + break; + case imagick::ORIENTATION_LEFTBOTTOM: + $this->image->rotateimage("#000", -90); + break; + } + + $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); + return true; + } + // based off comment on http://php.net/manual/en/function.imagerotate.php + + if (!$this->is_valid()) { + return false; + } + + if ( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) { + return; + } + + $exif = @exif_read_data($filename,null,true); + if (! $exif) { + return; + } + + $ort = $exif['IFD0']['Orientation']; + + switch($ort) + { + case 1: // nothing + break; + + case 2: // horizontal flip + $this->flip(); + break; + + case 3: // 180 rotate left + $this->rotate(180); + break; + + case 4: // vertical flip + $this->flip(false, true); + break; + + case 5: // vertical flip + 90 rotate right + $this->flip(false, true); + $this->rotate(-90); + break; + + case 6: // 90 rotate right + $this->rotate(-90); + break; + + case 7: // horizontal flip + 90 rotate right + $this->flip(); + $this->rotate(-90); + break; + + case 8: // 90 rotate left + $this->rotate(90); + break; + } + + // logger('exif: ' . print_r($exif,true)); + return $exif; + + } - public function cropImage($max,$x,$y,$w,$h) { - if(!$this->is_valid()) - return FALSE; - if($this->is_imagick()) { + public function scaleImageUp($min) { + if (!$this->is_valid()) { + return false; + } + + + $width = $this->getWidth(); + $height = $this->getHeight(); + + $dest_width = $dest_height = 0; + + if ((! $width)|| (! $height)) { + return false; + } + + if ($width < $min && $height < $min) { + if ($width > $height) { + $dest_width = $min; + $dest_height = intval(( $height * $min ) / $width); + } else { + $dest_width = intval(( $width * $min ) / $height); + $dest_height = $min; + } + } else { + if ( $width < $min ) { + $dest_width = $min; + $dest_height = intval(( $height * $min ) / $width); + } else { + if ( $height < $min ) { + $dest_width = intval(( $width * $min ) / $height); + $dest_height = $min; + } else { + $dest_width = $width; + $dest_height = $height; + } + } + } + + if ($this->is_imagick()) { + return $this->scaleImage($dest_width,$dest_height); + } + + $dest = imagecreatetruecolor( $dest_width, $dest_height ); + imagealphablending($dest, false); + imagesavealpha($dest, true); + if ($this->type=='image/png') { + imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha + } + imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height); + if ($this->image) { + imagedestroy($this->image); + } + $this->image = $dest; + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); + } + + + + public function scaleImageSquare($dim) { + if (!$this->is_valid()) { + return false; + } + + if ($this->is_imagick()) { + $this->image->setFirstIterator(); + do { + $this->image->scaleImage($dim, $dim); + } while ($this->image->nextImage()); + return; + } + + $dest = imagecreatetruecolor( $dim, $dim ); + imagealphablending($dest, false); + imagesavealpha($dest, true); + if ($this->type=='image/png') { + imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha + } + imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height); + if ($this->image) { + imagedestroy($this->image); + } + $this->image = $dest; + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); + } + + + public function cropImage($max,$x,$y,$w,$h) { + if (!$this->is_valid()) { + return false; + } + + if ($this->is_imagick()) { $this->image->setFirstIterator(); do { $this->image->cropImage($w, $h, $x, $y); - /** + /* * We need to remove the canva, * or the image is not resized to the crop: * http://php.net/manual/en/imagick.cropimage.php#97232 @@ -520,165 +549,172 @@ class Photo { return $this->scaleImage($max); } - $dest = imagecreatetruecolor( $max, $max ); - imagealphablending($dest, false); - imagesavealpha($dest, true); - if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha - imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h); - if($this->image) - imagedestroy($this->image); - $this->image = $dest; - $this->width = imagesx($this->image); - $this->height = imagesy($this->image); - } - - public function saveImage($path) { - if(!$this->is_valid()) - return FALSE; - - $string = $this->imageString(); - - $a = get_app(); - - $stamp1 = microtime(true); - file_put_contents($path, $string); - $a->save_timestamp($stamp1, "file"); - } - - public function imageString() { - if(!$this->is_valid()) - return FALSE; - - if($this->is_imagick()) { - /* Clean it */ - $this->image = $this->image->deconstructImages(); - $string = $this->image->getImagesBlob(); - return $string; + $dest = imagecreatetruecolor( $max, $max ); + imagealphablending($dest, false); + imagesavealpha($dest, true); + if ($this->type=='image/png') { + imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha + } + imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h); + if ($this->image) { + imagedestroy($this->image); + } + $this->image = $dest; + $this->width = imagesx($this->image); + $this->height = imagesy($this->image); } - $quality = FALSE; + public function saveImage($path) { + if (!$this->is_valid()) { + return false; + } - ob_start(); + $string = $this->imageString(); - // Enable interlacing - imageinterlace($this->image, true); + $a = get_app(); - switch($this->getType()){ - case "image/png": - $quality = get_config('system','png_quality'); - if((! $quality) || ($quality > 9)) - $quality = PNG_QUALITY; - imagepng($this->image,NULL, $quality); - break; - case "image/jpeg": - $quality = get_config('system','jpeg_quality'); - if((! $quality) || ($quality > 100)) - $quality = JPEG_QUALITY; - imagejpeg($this->image,NULL,$quality); + $stamp1 = microtime(true); + file_put_contents($path, $string); + $a->save_timestamp($stamp1, "file"); } - $string = ob_get_contents(); - ob_end_clean(); - return $string; - } + public function imageString() { + if (!$this->is_valid()) { + return false; + } + + if ($this->is_imagick()) { + /* Clean it */ + $this->image = $this->image->deconstructImages(); + $string = $this->image->getImagesBlob(); + return $string; + } + + $quality = FALSE; + + ob_start(); + + // Enable interlacing + imageinterlace($this->image, true); + + switch($this->getType()){ + case "image/png": + $quality = get_config('system','png_quality'); + if ((! $quality) || ($quality > 9)) { + $quality = PNG_QUALITY; + } + imagepng($this->image,NULL, $quality); + break; + case "image/jpeg": + $quality = get_config('system','jpeg_quality'); + if ((! $quality) || ($quality > 100)) { + $quality = JPEG_QUALITY; + } + imagejpeg($this->image,NULL,$quality); + } + $string = ob_get_contents(); + ob_end_clean(); + + return $string; + } - public function store($uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') { + public function store($uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') { - $r = q("select `guid` from photo where `resource-id` = '%s' and `guid` != '' limit 1", - dbesc($rid) - ); - if(count($r)) - $guid = $r[0]['guid']; - else - $guid = get_guid(); + $r = q("SELECT `guid` FROM `photo` WHERE `resource-id` = '%s' AND `guid` != '' LIMIT 1", + dbesc($rid) + ); + if (dbm::is_result($r)) { + $guid = $r[0]['guid']; + } else { + $guid = get_guid(); + } - $x = q("select id from photo where `resource-id` = '%s' and uid = %d and `contact-id` = %d and `scale` = %d limit 1", - dbesc($rid), - intval($uid), - intval($cid), - intval($scale) - ); - if(count($x)) { - $r = q("UPDATE `photo` - set `uid` = %d, - `contact-id` = %d, - `guid` = '%s', - `resource-id` = '%s', - `created` = '%s', - `edited` = '%s', - `filename` = '%s', - `type` = '%s', - `album` = '%s', - `height` = %d, - `width` = %d, + $x = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `contact-id` = %d AND `scale` = %d LIMIT 1", + dbesc($rid), + intval($uid), + intval($cid), + intval($scale) + ); + if (dbm::is_result($x)) { + $r = q("UPDATE `photo` + SET `uid` = %d, + `contact-id` = %d, + `guid` = '%s', + `resource-id` = '%s', + `created` = '%s', + `edited` = '%s', + `filename` = '%s', + `type` = '%s', + `album` = '%s', + `height` = %d, + `width` = %d, `datasize` = %d, - `data` = '%s', - `scale` = %d, - `profile` = %d, - `allow_cid` = '%s', - `allow_gid` = '%s', - `deny_cid` = '%s', - `deny_gid` = '%s' - where id = %d", + `data` = '%s', + `scale` = %d, + `profile` = %d, + `allow_cid` = '%s', + `allow_gid` = '%s', + `deny_cid` = '%s', + `deny_gid` = '%s' + WHERE `id` = %d", - intval($uid), - intval($cid), - dbesc($guid), - dbesc($rid), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(basename($filename)), - dbesc($this->getType()), - dbesc($album), - intval($this->getHeight()), - intval($this->getWidth()), + intval($uid), + intval($cid), + dbesc($guid), + dbesc($rid), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(basename($filename)), + dbesc($this->getType()), + dbesc($album), + intval($this->getHeight()), + intval($this->getWidth()), dbesc(strlen($this->imageString())), - dbesc($this->imageString()), - intval($scale), - intval($profile), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - intval($x[0]['id']) - ); - } - else { - $r = q("INSERT INTO `photo` - ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) - VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", - intval($uid), - intval($cid), - dbesc($guid), - dbesc($rid), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(basename($filename)), - dbesc($this->getType()), - dbesc($album), - intval($this->getHeight()), - intval($this->getWidth()), + dbesc($this->imageString()), + intval($scale), + intval($profile), + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid), + intval($x[0]['id']) + ); + } else { + $r = q("INSERT INTO `photo` + ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", + intval($uid), + intval($cid), + dbesc($guid), + dbesc($rid), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(basename($filename)), + dbesc($this->getType()), + dbesc($album), + intval($this->getHeight()), + intval($this->getWidth()), dbesc(strlen($this->imageString())), - dbesc($this->imageString()), - intval($scale), - intval($profile), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid) - ); - } + dbesc($this->imageString()), + intval($scale), + intval($profile), + dbesc($allow_cid), + dbesc($allow_gid), + dbesc($deny_cid), + dbesc($deny_gid) + ); + } - // Update the cached values - if ($album != 'Contact Photos') { - photo_albums($uid, true); - } + // Update the cached values + if ($album != 'Contact Photos') { + photo_albums($uid, true); + } - return $r; - } -}} + return $r; + } +} /** @@ -688,41 +724,43 @@ class Photo { * @arg $fromcurl boolean Check Content-Type header from curl request */ function guess_image_type($filename, $fromcurl=false) { - logger('Photo: guess_image_type: '.$filename . ($fromcurl?' from curl headers':''), LOGGER_DEBUG); - $type = null; - if ($fromcurl) { - $a = get_app(); - $headers=array(); - $h = explode("\n",$a->get_curl_headers()); - foreach ($h as $l) { - list($k,$v) = array_map("trim", explode(":", trim($l), 2)); - $headers[$k] = $v; + logger('Photo: guess_image_type: '.$filename . ($fromcurl?' from curl headers':''), LOGGER_DEBUG); + $type = null; + if ($fromcurl) { + $a = get_app(); + $headers=array(); + $h = explode("\n",$a->get_curl_headers()); + foreach ($h as $l) { + list($k,$v) = array_map("trim", explode(":", trim($l), 2)); + $headers[$k] = $v; + } + if (array_key_exists('Content-Type', $headers)) + $type = $headers['Content-Type']; } - if (array_key_exists('Content-Type', $headers)) - $type = $headers['Content-Type']; - } - if (is_null($type)){ - // Guessing from extension? Isn't that... dangerous? - if(class_exists('Imagick') && file_exists($filename) && is_readable($filename)) { - /** - * Well, this not much better, - * but at least it comes from the data inside the image, - * we won't be tricked by a manipulated extension - */ - $image = new Imagick($filename); - $type = $image->getImageMimeType(); - $image->setInterlaceScheme(Imagick::INTERLACE_PLANE); - } else { - $ext = pathinfo($filename, PATHINFO_EXTENSION); - $types = Photo::supportedTypes(); - $type = "image/jpeg"; - foreach ($types as $m=>$e){ - if ($ext==$e) $type = $m; - } + if (is_null($type)){ + // Guessing from extension? Isn't that... dangerous? + if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) { + /** + * Well, this not much better, + * but at least it comes from the data inside the image, + * we won't be tricked by a manipulated extension + */ + $image = new Imagick($filename); + $type = $image->getImageMimeType(); + $image->setInterlaceScheme(Imagick::INTERLACE_PLANE); + } else { + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $types = Photo::supportedTypes(); + $type = "image/jpeg"; + foreach ($types as $m=>$e){ + if ($ext==$e) { + $type = $m; + } + } + } } - } - logger('Photo: guess_image_type: type='.$type, LOGGER_DEBUG); - return $type; + logger('Photo: guess_image_type: type='.$type, LOGGER_DEBUG); + return $type; } @@ -739,10 +777,11 @@ function guess_image_type($filename, $fromcurl=false) { function update_contact_avatar($avatar,$uid,$cid, $force = false) { $r = q("SELECT `avatar`, `photo`, `thumb`, `micro` FROM `contact` WHERE `id` = %d LIMIT 1", intval($cid)); - if (!$r) + if (!dbm::is_result($r)) { return false; - else + } else { $data = array($r[0]["photo"], $r[0]["thumb"], $r[0]["micro"]); + } if (($r[0]["avatar"] != $avatar) OR $force) { $photos = import_profile_photo($avatar,$uid,$cid, true); @@ -762,59 +801,63 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) { $a = get_app(); - $r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1", + $r = q("SELECT `resource-id` FROM `photo` WHERE `uid` = %d AND `contact-id` = %d AND `scale` = 4 AND `album` = 'Contact Photos' LIMIT 1", intval($uid), intval($cid) ); - if(count($r) && strlen($r[0]['resource-id'])) { + if (dbm::is_result($r) && strlen($r[0]['resource-id'])) { $hash = $r[0]['resource-id']; } else { $hash = photo_new_resource(); - } + } $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo,true); - if ($quit_on_error AND ($img_str == "")) + if ($quit_on_error AND ($img_str == "")) { return false; + } $type = guess_image_type($photo,true); $img = new Photo($img_str, $type); - if($img->is_valid()) { + if ($img->is_valid()) { $img->scaleImageSquare(175); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4 ); - if($r === false) + if ($r === false) $photo_failure = true; $img->scaleImage(80); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5 ); - if($r === false) + if ($r === false) $photo_failure = true; $img->scaleImage(48); $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6 ); - if($r === false) + if ($r === false) { $photo_failure = true; + } $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt(); $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt(); $micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt(); - } else + } else { $photo_failure = true; + } - if($photo_failure AND $quit_on_error) + if ($photo_failure AND $quit_on_error) { return false; + } - if($photo_failure) { + if ($photo_failure) { $photo = $a->get_baseurl() . '/images/person-175.jpg'; $thumb = $a->get_baseurl() . '/images/person-80.jpg'; $micro = $a->get_baseurl() . '/images/person-48.jpg'; @@ -829,17 +872,13 @@ function get_photo_info($url) { $data = Cache::get($url); - // Unserialise to be able to check in the next step if the cached data is alright. - if (!is_null($data)) - $data = unserialize($data); - if (is_null($data) OR !$data) { $img_str = fetch_url($url, true, $redirects, 4); $filesize = strlen($img_str); - if (function_exists("getimagesizefromstring")) + if (function_exists("getimagesizefromstring")) { $data = getimagesizefromstring($img_str); - else { + } else { $tempfile = tempnam(get_temppath(), "cache"); $a = get_app(); @@ -851,10 +890,11 @@ function get_photo_info($url) { unlink($tempfile); } - if ($data) + if ($data) { $data["size"] = $filesize; + } - Cache::set($url, serialize($data)); + Cache::set($url, $data); } return $data; @@ -864,36 +904,37 @@ function scale_image($width, $height, $max) { $dest_width = $dest_height = 0; - if((!$width) || (!$height)) - return FALSE; + if ((!$width) || (!$height)) { + return false; + } - if($width > $max && $height > $max) { + if ($width > $max && $height > $max) { // very tall image (greater than 16:9) // constrain the width - let the height float. - if((($height * 9) / 16) > $width) { + if ((($height * 9) / 16) > $width) { $dest_width = $max; $dest_height = intval(( $height * $max ) / $width); - } elseif($width > $height) { + } elseif ($width > $height) { // else constrain both dimensions $dest_width = $max; $dest_height = intval(( $height * $max ) / $width); - } else { + } else { $dest_width = intval(( $width * $max ) / $height); $dest_height = $max; } } else { - if( $width > $max ) { + if ( $width > $max ) { $dest_width = $max; $dest_height = intval(( $height * $max ) / $width); - } else { - if( $height > $max ) { + } else { + if ( $height > $max ) { // very tall image (greater than 16:9) // but width is OK - don't do anything - if((($height * 9) / 16) > $width) { + if ((($height * 9) / 16) > $width) { $dest_width = $width; $dest_height = $height; } else { @@ -911,10 +952,10 @@ function scale_image($width, $height, $max) { function store_photo($a, $uid, $imagedata = "", $url = "") { $r = q("SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid` - WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", + WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 AND `contact`.`self` = 1 LIMIT 1", intval($uid)); - if(!count($r)) { + if (!dbm::is_result($r)) { logger("Can't detect user data for uid ".$uid, LOGGER_DEBUG); return(array()); } @@ -938,22 +979,22 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $maximagesize = get_config('system','maximagesize'); - if(($maximagesize) && (strlen($imagedata) > $maximagesize)) { + if (($maximagesize) && (strlen($imagedata) > $maximagesize)) { logger("Image exceeds size limit of ".$maximagesize, LOGGER_DEBUG); return(array()); - } + } /* - $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", - intval($uid) - ); + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($uid) + ); - $limit = service_class_fetch($uid,'photo_upload_limit'); + $limit = service_class_fetch($uid,'photo_upload_limit'); - if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + if (($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { logger("Image exceeds personal limit of uid ".$uid, LOGGER_DEBUG); return(array()); - } + } */ $tempfile = tempnam(get_temppath(), "cache"); @@ -972,7 +1013,7 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $ph = new Photo($imagedata, $data["mime"]); - if(!$ph->is_valid()) { + if (!$ph->is_valid()) { unlink($tempfile); logger("Picture is no valid picture", LOGGER_DEBUG); return(array()); @@ -982,10 +1023,12 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { unlink($tempfile); $max_length = get_config('system','max_image_length'); - if(! $max_length) + if (! $max_length) { $max_length = MAX_IMAGE_LENGTH; - if($max_length > 0) + } + if ($max_length > 0) { $ph->scaleImage($max_length); + } $width = $ph->getWidth(); $height = $ph->getHeight(); @@ -1001,7 +1044,7 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm); - if(!$r) { + if (!$r) { logger("Picture couldn't be stored", LOGGER_DEBUG); return(array()); } @@ -1009,43 +1052,49 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $image = array("page" => $a->get_baseurl().'/photos/'.$page_owner_nick.'/image/'.$hash, "full" => $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt()); - if($width > 800 || $height > 800) + if ($width > 800 || $height > 800) { $image["large"] = $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt(); + } - if($width > 640 || $height > 640) { + if ($width > 640 || $height > 640) { $ph->scaleImage(640); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm); - if($r) + if ($r) { $image["medium"] = $a->get_baseurl()."/photo/{$hash}-1.".$ph->getExt(); + } } - if($width > 320 || $height > 320) { + if ($width > 320 || $height > 320) { $ph->scaleImage(320); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm); - if($r) + if ($r) { $image["small"] = $a->get_baseurl()."/photo/{$hash}-2.".$ph->getExt(); + } } - if($width > 160 AND $height > 160) { + if ($width > 160 AND $height > 160) { $x = 0; $y = 0; $min = $ph->getWidth(); - if ($min > 160) + if ($min > 160) { $x = ($min - 160) / 2; + } if ($ph->getHeight() < $min) { $min = $ph->getHeight(); - if ($min > 160) + if ($min > 160) { $y = ($min - 160) / 2; + } } $min = 160; $ph->cropImage(160, $x, $y, $min, $min); $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm); - if($r) + if ($r) { $image["thumb"] = $a->get_baseurl()."/photo/{$hash}-3.".$ph->getExt(); + } } // Set the full image as preview image. This will be overwritten, if the picture is larger than 640. @@ -1059,39 +1108,9 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { //if (isset($image["small"])) // $image["preview"] = $image["small"]; - if (isset($image["medium"])) + if (isset($image["medium"])) { $image["preview"] = $image["medium"]; + } return($image); } - -/** - * @brief Fetch the photo albums that are available for a viewer - * - * The query in this function is cost intensive, so it is cached. - * - * @param int $uid User id of the photos - * @param bool $update Update the cache - * - * @return array Returns array of the photo albums - */ -function photo_albums($uid, $update = false) { - $sql_extra = permissions_sql($uid); - - $key = "photo_albums:".$uid.":".local_user().":".remote_user(); - $albums = Cache::get($key); - if (is_null($albums) OR $update) { - /// @todo This query needs to be renewed. It is really slow - // At this time we just store the data in the cache - $albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album` - FROM `photo` USE INDEX (`uid_album_created`) - WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra - GROUP BY `album` ORDER BY `created` DESC", - intval($uid), - dbesc('Contact Photos'), - dbesc(t('Contact Photos')) - ); - Cache::set($key, $albums, CACHE_DAY); - } - return $albums; -} diff --git a/include/Probe.php b/include/Probe.php index d266a384e..aa9f7d21d 100644 --- a/include/Probe.php +++ b/include/Probe.php @@ -217,7 +217,6 @@ class Probe { if ($cache) { $result = Cache::get("probe_url:".$network.":".$uri); if (!is_null($result)) { - $result = unserialize($result); return $result; } } @@ -257,7 +256,7 @@ class Probe { // Only store into the cache if the value seems to be valid if (!in_array($data['network'], array(NETWORK_PHANTOM, NETWORK_MAIL))) { - Cache::set("probe_url:".$network.":".$uri,serialize($data), CACHE_DAY); + Cache::set("probe_url:".$network.":".$uri, $data, CACHE_DAY); /// @todo temporary fix - we need a real contact update function that updates only changing fields /// The biggest problem is the avatar picture that could have a reduced image size. diff --git a/include/cache.php b/include/cache.php index 45938dddf..b8016ac45 100644 --- a/include/cache.php +++ b/include/cache.php @@ -99,8 +99,8 @@ class Cache { dbesc($key) ); - if (count($r)) { - return $r[0]['v']; + if (dbm::is_result($r)) { + return unserialize($r[0]['v']); } return null; @@ -108,7 +108,9 @@ class Cache { /** * @brief Put data in the cache according to the key - * + * + * The input $value can have multiple formats. + * * @param string $key The key to the cached data * @param mixed $valie The value that is about to be stored * @param integer $duration The cache lifespan @@ -126,7 +128,7 @@ class Cache { /// @todo store the cache data in the same way like the config data q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')", dbesc($key), - dbesc($value), + dbesc(serialize($value)), intval($duration), dbesc(datetime_convert())); } diff --git a/include/cron.php b/include/cron.php index c03745a44..2c27e9f99 100644 --- a/include/cron.php +++ b/include/cron.php @@ -11,6 +11,7 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) { } require_once("boot.php"); +require_once("include/photos.php"); function cron_run(&$argv, &$argc){ @@ -162,8 +163,9 @@ function cron_run(&$argv, &$argc){ */ function cron_update_photo_albums() { $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`"); - if (!dbm::is_result($r)) + if (!dbm::is_result($r)) { return; + } foreach ($r AS $user) { photo_albums($user['uid'], true); diff --git a/include/gprobe.php b/include/gprobe.php index 91b9b16e3..278547534 100644 --- a/include/gprobe.php +++ b/include/gprobe.php @@ -12,11 +12,11 @@ function gprobe_run(&$argv, &$argc){ } if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; + @include(".htconfig.php"); + require_once("include/dba.php"); + $db = new dba($db_host, $db_user, $db_pass, $db_data); + unset($db_host, $db_user, $db_pass, $db_data); + }; require_once('include/session.php'); require_once('include/datetime.php'); @@ -39,14 +39,13 @@ function gprobe_run(&$argv, &$argc){ logger("gprobe start for ".normalise_link($url), LOGGER_DEBUG); - if (!count($r)) { + if (!dbm::is_result($r)) { // Is it a DDoS attempt? $urlparts = parse_url($url); $result = Cache::get("gprobe:".$urlparts["host"]); if (!is_null($result)) { - $result = unserialize($result); if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) { logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG); return; @@ -56,7 +55,7 @@ function gprobe_run(&$argv, &$argc){ $arr = probe_url($url); if (is_null($result)) - Cache::set("gprobe:".$urlparts["host"],serialize($arr)); + Cache::set("gprobe:".$urlparts["host"], $arr); if (!in_array($arr["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) update_gcontact($arr); @@ -65,7 +64,7 @@ function gprobe_run(&$argv, &$argc){ dbesc(normalise_link($url)) ); } - if(count($r)) { + if(dbm::is_result($r)) { // Check for accessibility and do a poco discovery if (poco_last_updated($r[0]['url'], true) AND ($r[0]["network"] == NETWORK_DFRN)) poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url'])); @@ -76,6 +75,6 @@ function gprobe_run(&$argv, &$argc){ } if (array_search(__file__,get_included_files())===0){ - gprobe_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); + gprobe_run($_SERVER["argv"],$_SERVER["argc"]); + killme(); } diff --git a/include/oembed.php b/include/oembed.php index 898d900f4..be6c298e8 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -6,7 +6,15 @@ function oembed_replacecb($matches){ return $s; } - +/** + * @brief Get data from an URL to embed its content. + * + * @param string $embedurl The URL from which the data should be fetched. + * @param bool $no_rich_type If set to true rich type content won't be fetched. + * + * @return bool|object Returns object with embed content or false if no embedable + * content exists + */ function oembed_fetch_url($embedurl, $no_rich_type = false){ $embedurl = trim($embedurl, "'"); $embedurl = trim($embedurl, '"'); @@ -16,11 +24,11 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ $r = q("SELECT * FROM `oembed` WHERE `url` = '%s'", dbesc(normalise_link($embedurl))); - if ($r) + if (dbm::is_result($r)) { $txt = $r[0]["content"]; - else + } else { $txt = Cache::get($a->videowidth . $embedurl); - + } // These media files should now be caught in bbcode.php // left here as a fallback in case this is called from another source @@ -28,27 +36,27 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ $ext = pathinfo(strtolower($embedurl),PATHINFO_EXTENSION); - if(is_null($txt)){ + if (is_null($txt)) { $txt = ""; if (!in_array($ext, $noexts)){ // try oembed autodiscovery $redirects = 0; - $html_text = fetch_url($embedurl, false, $redirects, 15, "text/*"); /**/ - if($html_text){ + $html_text = fetch_url($embedurl, false, $redirects, 15, "text/*"); + if ($html_text) { $dom = @DOMDocument::loadHTML($html_text); - if ($dom){ + if ($dom) { $xpath = new DOMXPath($dom); $attr = "oembed"; $xattr = oe_build_xpath("class","oembed"); $entries = $xpath->query("//link[@type='application/json+oembed']"); - foreach($entries as $e){ + foreach ($entries as $e) { $href = $e->getAttributeNode("href")->nodeValue; $txt = fetch_url($href . '&maxwidth=' . $a->videowidth); break; } $entries = $xpath->query("//link[@type='text/json+oembed']"); - foreach($entries as $e){ + foreach ($entries as $e) { $href = $e->getAttributeNode("href")->nodeValue; $txt = fetch_url($href . '&maxwidth=' . $a->videowidth); break; @@ -57,7 +65,7 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ } } - if ($txt==false || $txt==""){ + if ($txt==false || $txt=="") { $embedly = get_config("system", "embedly"); if ($embedly != "") { // try embedly service @@ -70,30 +78,33 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ $txt=trim($txt); - if ($txt[0]!="{") + if ($txt[0]!="{") { $txt='{"type":"error"}'; - else { //save in cache + } else { //save in cache $j = json_decode($txt); - if ($j->type != "error") + if ($j->type != "error") { q("INSERT INTO `oembed` (`url`, `content`, `created`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'", dbesc(normalise_link($embedurl)), dbesc($txt), dbesc(datetime_convert()), dbesc($txt), dbesc(datetime_convert())); + } - Cache::set($a->videowidth.$embedurl,$txt, CACHE_DAY); + Cache::set($a->videowidth.$embedurl, $txt, CACHE_DAY); } } $j = json_decode($txt); - if (!is_object($j)) + if (!is_object($j)) { return false; + } // Always embed the SSL version - if (isset($j->html)) + if (isset($j->html)) { $j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"), array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html); + } $j->embedurl = $embedurl; @@ -109,16 +120,18 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ //$j->height = $data["images"][0]["height"]; } - if (isset($data["title"])) - $j->title = $data["title"]; + if (isset($data["title"])) { + $j->title = $data["title"]; + } - if (isset($data["text"])) - $j->description = $data["text"]; + if (isset($data["text"])) { + $j->description = $data["text"]; + } if (is_array($data["images"])) { - $j->thumbnail_url = $data["images"][0]["src"]; - $j->thumbnail_width = $data["images"][0]["width"]; - $j->thumbnail_height = $data["images"][0]["height"]; + $j->thumbnail_url = $data["images"][0]["src"]; + $j->thumbnail_width = $data["images"][0]["width"]; + $j->thumbnail_height = $data["images"][0]["height"]; } } diff --git a/include/photos.php b/include/photos.php index 93a565b51..2beb23ffa 100644 --- a/include/photos.php +++ b/include/photos.php @@ -25,3 +25,34 @@ function gps2Num($coordPart) { return floatval($parts[0]) / floatval($parts[1]); } + +/** + * @brief Fetch the photo albums that are available for a viewer + * + * The query in this function is cost intensive, so it is cached. + * + * @param int $uid User id of the photos + * @param bool $update Update the cache + * + * @return array Returns array of the photo albums + */ +function photo_albums($uid, $update = false) { + $sql_extra = permissions_sql($uid); + + $key = "photo_albums:".$uid.":".local_user().":".remote_user(); + $albums = Cache::get($key); + if (is_null($albums) OR $update) { + /// @todo This query needs to be renewed. It is really slow + // At this time we just store the data in the cache + $albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album` + FROM `photo` USE INDEX (`uid_album_created`) + WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra + GROUP BY `album` ORDER BY `created` DESC", + intval($uid), + dbesc('Contact Photos'), + dbesc(t('Contact Photos')) + ); + Cache::set($key, $albums, CACHE_DAY); + } + return $albums; +} diff --git a/mod/photos.php b/mod/photos.php index edaba5a90..1730a9b60 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -21,8 +21,6 @@ function photos_init(&$a) { nav_set_selected('home'); - $o = ''; - if ($a->argc > 1) { $nick = $a->argv[1]; $user = qu("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 LIMIT 1", From e446e9571f1da818afbd5a3316043d47b16978fa Mon Sep 17 00:00:00 2001 From: rabuzarus <> Date: Fri, 4 Nov 2016 19:26:28 +0100 Subject: [PATCH 23/24] some more coding style correction --- include/Photo.php | 126 ++++++++++++++++++++++----------------------- include/gprobe.php | 4 +- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/include/Photo.php b/include/Photo.php index f1e2989d5..6a7cc3e52 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -47,18 +47,18 @@ class Photo { public function __construct($data, $type=null) { $this->imagick = class_exists('Imagick'); $this->types = $this->supportedTypes(); - if (!array_key_exists($type,$this->types)){ + if (!array_key_exists($type, $this->types)){ $type='image/jpeg'; } $this->type = $type; if ($this->is_imagick() && $this->load_data($data)) { - return true; - } else { - // Failed to load with Imagick, fallback - $this->imagick = false; - } - return $this->load_data($data); + return true; + } else { + // Failed to load with Imagick, fallback + $this->imagick = false; + } + return $this->load_data($data); } public function __destruct() { @@ -78,6 +78,7 @@ class Photo { /** * @brief Maps Mime types to Imagick formats + * @return arr With with image formats (mime type as key) */ public function get_FormatsMap() { $m = array( @@ -90,11 +91,10 @@ class Photo { private function load_data($data) { if ($this->is_imagick()) { - $this->image = new Imagick(); + $this->image = new Imagick(); try { $this->image->readImageBlob($data); - } - catch (Exception $e) { + } catch (Exception $e) { // Imagick couldn't use the data return false; } @@ -114,7 +114,7 @@ class Photo { */ switch($this->getType()){ case "image/png": - $quality = get_config('system','png_quality'); + $quality = get_config('system', 'png_quality'); if ((! $quality) || ($quality > 9)) { $quality = PNG_QUALITY; } @@ -130,7 +130,7 @@ class Photo { $this->image->setCompressionQuality($quality); break; case "image/jpeg": - $quality = get_config('system','jpeg_quality'); + $quality = get_config('system', 'jpeg_quality'); if ((! $quality) || ($quality > 100)) { $quality = JPEG_QUALITY; } @@ -239,21 +239,21 @@ class Photo { if ((($height * 9) / 16) > $width) { $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } elseif ($width > $height) { // else constrain both dimensions $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } else { - $dest_width = intval(( $width * $max ) / $height); + $dest_width = intval(($width * $max) / $height); $dest_height = $max; } } else { - if ( $width > $max ) { + if ($width > $max) { $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } else { - if ( $height > $max ) { + if ($height > $max) { // very tall image (greater than 16:9) // but width is OK - don't do anything @@ -262,7 +262,7 @@ class Photo { $dest_width = $width; $dest_height = $height; } else { - $dest_width = intval(( $width * $max ) / $height); + $dest_width = intval(($width * $max) / $height); $dest_height = $max; } } else { @@ -296,7 +296,7 @@ class Photo { } - $dest = imagecreatetruecolor( $dest_width, $dest_height ); + $dest = imagecreatetruecolor($dest_width, $dest_height); imagealphablending($dest, false); imagesavealpha($dest, true); if ($this->type=='image/png') { @@ -388,12 +388,12 @@ class Photo { return false; } - if ( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) { + if ((!function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg')) { return; } $exif = @exif_read_data($filename,null,true); - if (! $exif) { + if (!$exif) { return; } @@ -453,25 +453,25 @@ class Photo { $dest_width = $dest_height = 0; - if ((! $width)|| (! $height)) { + if ((!$width)|| (!$height)) { return false; } if ($width < $min && $height < $min) { if ($width > $height) { $dest_width = $min; - $dest_height = intval(( $height * $min ) / $width); + $dest_height = intval(($height * $min) / $width); } else { - $dest_width = intval(( $width * $min ) / $height); + $dest_width = intval(($width * $min) / $height); $dest_height = $min; } } else { - if ( $width < $min ) { + if ($width < $min) { $dest_width = $min; - $dest_height = intval(( $height * $min ) / $width); + $dest_height = intval(($height * $min) / $width); } else { - if ( $height < $min ) { - $dest_width = intval(( $width * $min ) / $height); + if ($height < $min) { + $dest_width = intval(($width * $min) / $height); $dest_height = $min; } else { $dest_width = $width; @@ -481,10 +481,10 @@ class Photo { } if ($this->is_imagick()) { - return $this->scaleImage($dest_width,$dest_height); + return $this->scaleImage($dest_width, $dest_height); } - $dest = imagecreatetruecolor( $dest_width, $dest_height ); + $dest = imagecreatetruecolor($dest_width, $dest_height); imagealphablending($dest, false); imagesavealpha($dest, true); if ($this->type=='image/png') { @@ -514,7 +514,7 @@ class Photo { return; } - $dest = imagecreatetruecolor( $dim, $dim ); + $dest = imagecreatetruecolor($dim, $dim); imagealphablending($dest, false); imagesavealpha($dest, true); if ($this->type=='image/png') { @@ -530,7 +530,7 @@ class Photo { } - public function cropImage($max,$x,$y,$w,$h) { + public function cropImage($max, $x, $y, $w, $h) { if (!$this->is_valid()) { return false; } @@ -549,7 +549,7 @@ class Photo { return $this->scaleImage($max); } - $dest = imagecreatetruecolor( $max, $max ); + $dest = imagecreatetruecolor($max, $max); imagealphablending($dest, false); imagesavealpha($dest, true); if ($this->type=='image/png') { @@ -590,7 +590,7 @@ class Photo { return $string; } - $quality = FALSE; + $quality = false; ob_start(); @@ -599,18 +599,18 @@ class Photo { switch($this->getType()){ case "image/png": - $quality = get_config('system','png_quality'); - if ((! $quality) || ($quality > 9)) { + $quality = get_config('system', 'png_quality'); + if ((!$quality) || ($quality > 9)) { $quality = PNG_QUALITY; } - imagepng($this->image,NULL, $quality); + imagepng($this->image, null, $quality); break; case "image/jpeg": - $quality = get_config('system','jpeg_quality'); - if ((! $quality) || ($quality > 100)) { + $quality = get_config('system', 'jpeg_quality'); + if ((!$quality) || ($quality > 100)) { $quality = JPEG_QUALITY; } - imagejpeg($this->image,NULL,$quality); + imagejpeg($this->image, null, $quality); } $string = ob_get_contents(); ob_end_clean(); @@ -683,8 +683,8 @@ class Photo { ); } else { $r = q("INSERT INTO `photo` - ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) - VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", + (`uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`) + VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", intval($uid), intval($cid), dbesc($guid), @@ -752,8 +752,8 @@ function guess_image_type($filename, $fromcurl=false) { $ext = pathinfo($filename, PATHINFO_EXTENSION); $types = Photo::supportedTypes(); $type = "image/jpeg"; - foreach ($types as $m=>$e){ - if ($ext==$e) { + foreach ($types as $m => $e){ + if ($ext == $e) { $type = $m; } } @@ -774,7 +774,7 @@ function guess_image_type($filename, $fromcurl=false) { * * @return array Returns array of the different avatar sizes */ -function update_contact_avatar($avatar,$uid,$cid, $force = false) { +function update_contact_avatar($avatar, $uid, $cid, $force = false) { $r = q("SELECT `avatar`, `photo`, `thumb`, `micro` FROM `contact` WHERE `id` = %d LIMIT 1", intval($cid)); if (!dbm::is_result($r)) { @@ -784,7 +784,7 @@ function update_contact_avatar($avatar,$uid,$cid, $force = false) { } if (($r[0]["avatar"] != $avatar) OR $force) { - $photos = import_profile_photo($avatar,$uid,$cid, true); + $photos = import_profile_photo($avatar, $uid, $cid, true); if ($photos) { q("UPDATE `contact` SET `avatar` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s', `avatar-date` = '%s' WHERE `id` = %d", @@ -797,7 +797,7 @@ function update_contact_avatar($avatar,$uid,$cid, $force = false) { return $data; } -function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) { +function import_profile_photo($photo, $uid, $cid, $quit_on_error = false) { $a = get_app(); @@ -814,33 +814,33 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) { $photo_failure = false; $filename = basename($photo); - $img_str = fetch_url($photo,true); + $img_str = fetch_url($photo, true); if ($quit_on_error AND ($img_str == "")) { return false; } - $type = guess_image_type($photo,true); + $type = guess_image_type($photo, true); $img = new Photo($img_str, $type); if ($img->is_valid()) { $img->scaleImageSquare(175); - $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4); if ($r === false) $photo_failure = true; $img->scaleImage(80); - $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5); if ($r === false) $photo_failure = true; $img->scaleImage(48); - $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6); if ($r === false) { $photo_failure = true; @@ -915,21 +915,21 @@ function scale_image($width, $height, $max) { if ((($height * 9) / 16) > $width) { $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } elseif ($width > $height) { // else constrain both dimensions $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } else { - $dest_width = intval(( $width * $max ) / $height); + $dest_width = intval(($width * $max) / $height); $dest_height = $max; } } else { - if ( $width > $max ) { + if ($width > $max) { $dest_width = $max; - $dest_height = intval(( $height * $max ) / $width); + $dest_height = intval(($height * $max) / $width); } else { - if ( $height > $max ) { + if ($height > $max) { // very tall image (greater than 16:9) // but width is OK - don't do anything @@ -938,7 +938,7 @@ function scale_image($width, $height, $max) { $dest_width = $width; $dest_height = $height; } else { - $dest_width = intval(( $width * $max ) / $height); + $dest_width = intval(($width * $max) / $height); $dest_height = $max; } } else { @@ -977,7 +977,7 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $a->save_timestamp($stamp1, "file"); } - $maximagesize = get_config('system','maximagesize'); + $maximagesize = get_config('system', 'maximagesize'); if (($maximagesize) && (strlen($imagedata) > $maximagesize)) { logger("Image exceeds size limit of ".$maximagesize, LOGGER_DEBUG); @@ -1022,7 +1022,7 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { $ph->orient($tempfile); unlink($tempfile); - $max_length = get_config('system','max_image_length'); + $max_length = get_config('system', 'max_image_length'); if (! $max_length) { $max_length = MAX_IMAGE_LENGTH; } @@ -1040,7 +1040,7 @@ function store_photo($a, $uid, $imagedata = "", $url = "") { // Pictures are always public by now //$defperm = '<'.$default_cid.'>'; $defperm = ""; - $visitor = 0; + $visitor = 0; $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm); diff --git a/include/gprobe.php b/include/gprobe.php index 278547534..42a8ef713 100644 --- a/include/gprobe.php +++ b/include/gprobe.php @@ -13,9 +13,9 @@ function gprobe_run(&$argv, &$argc){ if(is_null($db)) { @include(".htconfig.php"); - require_once("include/dba.php"); + require_once("include/dba.php"); $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); + unset($db_host, $db_user, $db_pass, $db_data); }; require_once('include/session.php'); From 98d52bc56820190f6431ae013c01065dd56a5e6d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 4 Nov 2016 21:19:07 -0400 Subject: [PATCH 24/24] [frio] fix wall_thread.tpl error with unstareable items --- view/theme/frio/templates/wall_thread.tpl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl index 21792d41c..25ad41bc3 100644 --- a/view/theme/frio/templates/wall_thread.tpl +++ b/view/theme/frio/templates/wall_thread.tpl @@ -3,7 +3,7 @@ It would be better if it would be done in friendica core but since core lacks this functionality it is done in the theme -In short: the piece of code counts the total number of children of the toplevelpost +In short: the piece of code counts the total number of children of the toplevelpost - this are usaly all posts with thread_level = 2 - and stores it in variable $top_children_total. The first time a children which hits thread_level = 2 and $top_child = 1 opens the div. @@ -41,9 +41,9 @@ as the value of $top_child_total (this is done at the end of this file) {{if $item.thread_level<3}}

    @@ -57,7 +57,9 @@ as the value of $top_child_total (this is done at the end of this file) @@ -73,7 +75,7 @@ as the value of $top_child_total (this is done at the end of this file) {{/if}}
    {{* Put addional actions in a top-right dropdown menu *}} - +