Merge remote-tracking branch 'upstream/develop' into 1701-performance

This commit is contained in:
Michael 2017-02-23 06:55:35 +00:00
commit f9f27c2f5f
29 changed files with 398 additions and 247 deletions

View file

@ -64,7 +64,7 @@ you wish to communicate with the Diaspora network.
password, database name). password, database name).
- Friendica needs the permission to create and delete fields and tables in its own database. - Friendica needs the permission to create and delete fields and tables in its own database.
- Please check the additional notes if running on MySQ 5.7.17 or newer
4. If you know in advance that it will be impossible for the web server to 4. If you know in advance that it will be impossible for the web server to
write or create files in your web directory, create an empty file called write or create files in your web directory, create an empty file called
@ -291,3 +291,21 @@ This is obvious as soon as you notice that the friendica-cron uses proc_open to
execute php-scripts that also use proc_open, but it took me quite some time to execute php-scripts that also use proc_open, but it took me quite some time to
find that out. I hope this saves some time for other people using suhosin with find that out. I hope this saves some time for other people using suhosin with
function blacklists. function blacklists.
########################################################################
Unable to create all mysql tables on MySQL 5.7.17 or newer
#######################################################################
If the setup fails to create all the database tables and/or manual
creation from the command line fails, with this error:
ERROR 1067 (42000) at line XX: Invalid default value for 'created'
You need to adjust your my.cnf and add the following setting under
the [mysqld] section :
sql_mode = '';
After that, restart mysql and try again.

148
boot.php
View file

@ -430,6 +430,17 @@ define('PRIORITY_LOW', 40);
define('PRIORITY_NEGLIGIBLE',50); define('PRIORITY_NEGLIGIBLE',50);
/* @}*/ /* @}*/
/**
* @name Social Relay settings
*
* See here: https://github.com/jaywink/social-relay
* and here: https://wiki.diasporafoundation.org/Relay_servers_for_public_posts
* @{
*/
define('SR_SCOPE_NONE', '');
define('SR_SCOPE_ALL', 'all');
define('SR_SCOPE_TAGS', 'tags');
/* @}*/
// Normally this constant is defined - but not if "pcntl" isn't installed // Normally this constant is defined - but not if "pcntl" isn't installed
if (!defined("SIGTERM")) if (!defined("SIGTERM"))
@ -1404,6 +1415,53 @@ class App {
proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__))); proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__)));
} }
/**
* @brief Returns the system user that is executing the script
*
* This mostly returns something like "www-data".
*
* @return string system username
*/
static function systemuser() {
if (!function_exists('posix_getpwuid') OR !function_exists('posix_geteuid')) {
return '';
}
$processUser = posix_getpwuid(posix_geteuid());
return $processUser['name'];
}
/**
* @brief Checks if a given directory is usable for the system
*
* @return boolean the directory is usable
*/
static function directory_usable($directory) {
if ($directory == '') {
logger("Directory is empty. This shouldn't happen.", LOGGER_DEBUG);
return false;
}
if (!file_exists($directory)) {
logger('Path "'.$directory.'" does not exist for user '.self::systemuser(), LOGGER_DEBUG);
return false;
}
if (is_file($directory)) {
logger('Path "'.$directory.'" is a file for user '.self::systemuser(), LOGGER_DEBUG);
return false;
}
if (!is_dir($directory)) {
logger('Path "'.$directory.'" is not a directory for user '.self::systemuser(), LOGGER_DEBUG);
return false;
}
if (!is_writable($directory)) {
logger('Path "'.$directory.'" is not writable for user '.self::systemuser(), LOGGER_DEBUG);
return false;
}
return true;
}
} }
/** /**
@ -2308,8 +2366,9 @@ function get_itemcachepath() {
return ""; return "";
$itemcache = get_config('system','itemcache'); $itemcache = get_config('system','itemcache');
if (($itemcache != "") AND is_dir($itemcache) AND is_writable($itemcache)) if (($itemcache != "") AND App::directory_usable($itemcache)) {
return($itemcache); return $itemcache;
}
$temppath = get_temppath(); $temppath = get_temppath();
@ -2319,9 +2378,9 @@ function get_itemcachepath() {
mkdir($itemcache); mkdir($itemcache);
} }
if (is_dir($itemcache) AND is_writable($itemcache)) { if (App::directory_usable($itemcache)) {
set_config("system", "itemcache", $itemcache); set_config("system", "itemcache", $itemcache);
return($itemcache); return $itemcache;
} }
} }
return ""; return "";
@ -2329,24 +2388,33 @@ function get_itemcachepath() {
function get_lockpath() { function get_lockpath() {
$lockpath = get_config('system','lockpath'); $lockpath = get_config('system','lockpath');
if (($lockpath != "") AND is_dir($lockpath) AND is_writable($lockpath)) if (($lockpath != "") AND App::directory_usable($lockpath)) {
return($lockpath); // We have a lock path and it is usable
return $lockpath;
}
// We don't have a working preconfigured lock path, so we take the temp path.
$temppath = get_temppath(); $temppath = get_temppath();
if ($temppath != "") { if ($temppath != "") {
// To avoid any interferences with other systems we create our own directory
$lockpath = $temppath."/lock"; $lockpath = $temppath."/lock";
if (!is_dir($lockpath)) {
if (!is_dir($lockpath))
mkdir($lockpath); mkdir($lockpath);
elseif (!is_writable($lockpath)) }
$lockpath = $temppath;
if (is_dir($lockpath) AND is_writable($lockpath)) { if (App::directory_usable($lockpath)) {
// The new path is usable, we are happy
set_config("system", "lockpath", $lockpath); set_config("system", "lockpath", $lockpath);
return($lockpath); return $lockpath;
} else {
// We can't create a subdirectory, strange.
// But the directory seems to work, so we use it but don't store it.
return $temppath;
} }
} }
// Reaching this point means that the operating system is configured badly.
return ""; return "";
} }
@ -2357,49 +2425,69 @@ function get_lockpath() {
*/ */
function get_spoolpath() { function get_spoolpath() {
$spoolpath = get_config('system','spoolpath'); $spoolpath = get_config('system','spoolpath');
if (($spoolpath != "") AND is_dir($spoolpath) AND is_writable($spoolpath)) { if (($spoolpath != "") AND App::directory_usable($spoolpath)) {
return($spoolpath); // We have a spool path and it is usable
return $spoolpath;
} }
// We don't have a working preconfigured spool path, so we take the temp path.
$temppath = get_temppath(); $temppath = get_temppath();
if ($temppath != "") { if ($temppath != "") {
// To avoid any interferences with other systems we create our own directory
$spoolpath = $temppath."/spool"; $spoolpath = $temppath."/spool";
if (!is_dir($spoolpath)) { if (!is_dir($spoolpath)) {
mkdir($spoolpath); mkdir($spoolpath);
} elseif (!is_writable($spoolpath)) {
$spoolpath = $temppath;
} }
if (is_dir($spoolpath) AND is_writable($spoolpath)) { if (App::directory_usable($spoolpath)) {
// The new path is usable, we are happy
set_config("system", "spoolpath", $spoolpath); set_config("system", "spoolpath", $spoolpath);
return($spoolpath); return $spoolpath;
} else {
// We can't create a subdirectory, strange.
// But the directory seems to work, so we use it but don't store it.
return $temppath;
} }
} }
// Reaching this point means that the operating system is configured badly.
return ""; return "";
} }
function get_temppath() { function get_temppath() {
$a = get_app(); $a = get_app();
$temppath = get_config("system","temppath"); $temppath = get_config("system", "temppath");
if (($temppath != "") AND is_dir($temppath) AND is_writable($temppath))
return($temppath);
if (($temppath != "") AND App::directory_usable($temppath)) {
// We have a temp path and it is usable
return $temppath;
}
// We don't have a working preconfigured temp path, so we take the system path.
$temppath = sys_get_temp_dir(); $temppath = sys_get_temp_dir();
if (($temppath != "") AND is_dir($temppath) AND is_writable($temppath)) {
$temppath .= "/".$a->get_hostname();
if (!is_dir($temppath))
mkdir($temppath);
if (is_dir($temppath) AND is_writable($temppath)) { // Check if it is usable
set_config("system", "temppath", $temppath); if (($temppath != "") AND App::directory_usable($temppath)) {
return($temppath); // To avoid any interferences with other systems we create our own directory
$new_temppath .= "/".$a->get_hostname();
if (!is_dir($new_temppath))
mkdir($new_temppath);
if (App::directory_usable($new_temppath)) {
// The new path is usable, we are happy
set_config("system", "temppath", $new_temppath);
return $new_temppath;
} else {
// We can't create a subdirectory, strange.
// But the directory seems to work, so we use it but don't store it.
return $temppath;
} }
} }
return(""); // Reaching this point means that the operating system is configured badly.
return '';
} }
/// @deprecated /// @deprecated

View file

@ -69,6 +69,15 @@ Create an empty database and note the access details (hostname, username, passwo
Friendica needs the permission to create and delete fields and tables in its own database. Friendica needs the permission to create and delete fields and tables in its own database.
With newer releases of MySQL (5.7.17 or newer), you might need to set the sql_mode to '' (blank).
Use this setting when the installer is unable to create all the needed tables due to a timestamp format problem.
In this case find the [mysqld] section in your my.cnf file and add the line :
sql_mode = ''
Restart mysql and you should be fine.
###Run the installer ###Run the installer
Point your web browser to the new site and follow the instructions. Point your web browser to the new site and follow the instructions.

View file

@ -5,17 +5,8 @@ Here are some more things to help get you started:
**Groups** **Groups**
- <a href="https://kakste.com/profile/newhere">New Here</a> - a group for people new to Friendica
- <a href="http://helpers.pyxis.uberspace.de/profile/helpers">Friendica Support</a> - problems? This is the place to ask. - <a href="http://helpers.pyxis.uberspace.de/profile/helpers">Friendica Support</a> - problems? This is the place to ask.
- <a href="https://kakste.com/profile/public_stream">Public Stream</a> - a place to talk about anything to anyone.
- <a href="https://letstalk.pyxis.uberspace.de/profile/letstalk">Let's Talk</a> a group for finding people and groups who share similar interests.
- <a href="http://newzot.hydra.uberspace.de/profile/newzot">Local Friendica</a> a page for local Friendica groups</a>
**Documentation** **Documentation**
- <a href="help/Connectors">Connecting to more networks</a> - <a href="help/Connectors">Connecting to more networks</a>

View file

@ -730,6 +730,10 @@ function posts_from_contact_url(App $a, $contact_url) {
$sql = "`item`.`uid` = %d"; $sql = "`item`.`uid` = %d";
} }
if (!dbm::is_result($r)) {
return '';
}
$author_id = intval($r[0]["author-id"]); $author_id = intval($r[0]["author-id"]);
if (get_config('system', 'old_pager')) { if (get_config('system', 'old_pager')) {

View file

@ -21,13 +21,13 @@ class ParseUrl {
/** /**
* @brief Search for chached embeddable data of an url otherwise fetch it * @brief Search for chached embeddable data of an url otherwise fetch it
* *
* @param type $url The url of the page which should be scraped * @param type $url The url of the page which should be scraped
* @param type $no_guessing If true the parse doens't search for * @param type $no_guessing If true the parse doens't search for
* preview pictures * preview pictures
* @param type $do_oembed The false option is used by the function fetch_oembed() * @param type $do_oembed The false option is used by the function fetch_oembed()
* to avoid endless loops * to avoid endless loops
* *
* @return array which contains needed data for embedding * @return array which contains needed data for embedding
* string 'url' => The url of the parsed page * string 'url' => The url of the parsed page
* string 'type' => Content type * string 'type' => Content type
@ -37,9 +37,9 @@ class ParseUrl {
* if $no_geuessing = false * if $no_geuessing = false
* array'images' = Array of preview pictures * array'images' = Array of preview pictures
* string 'keywords' => The tags which belong to the content * string 'keywords' => The tags which belong to the content
* *
* @see ParseUrl::getSiteinfo() for more information about scraping * @see ParseUrl::getSiteinfo() for more information about scraping
* embeddable content * embeddable content
*/ */
public static function getSiteinfoCached($url, $no_guessing = false, $do_oembed = true) { public static function getSiteinfoCached($url, $no_guessing = false, $do_oembed = true) {
@ -71,21 +71,21 @@ class ParseUrl {
} }
/** /**
* @brief Parse a page for embeddable content information * @brief Parse a page for embeddable content information
* *
* This method parses to url for meta data which can be used to embed * This method parses to url for meta data which can be used to embed
* the content. If available it prioritizes Open Graph meta tags. * the content. If available it prioritizes Open Graph meta tags.
* If this is not available it uses the twitter cards meta tags. * If this is not available it uses the twitter cards meta tags.
* As fallback it uses standard html elements with meta informations * As fallback it uses standard html elements with meta informations
* like \<title\>Awesome Title\</title\> or * like \<title\>Awesome Title\</title\> or
* \<meta name="description" content="An awesome description"\> * \<meta name="description" content="An awesome description"\>
* *
* @param type $url The url of the page which should be scraped * @param type $url The url of the page which should be scraped
* @param type $no_guessing If true the parse doens't search for * @param type $no_guessing If true the parse doens't search for
* preview pictures * preview pictures
* @param type $do_oembed The false option is used by the function fetch_oembed() * @param type $do_oembed The false option is used by the function fetch_oembed()
* to avoid endless loops * to avoid endless loops
* @param type $count Internal counter to avoid endless loops * @param type $count Internal counter to avoid endless loops
* *
* @return array which contains needed data for embedding * @return array which contains needed data for embedding
* string 'url' => The url of the parsed page * string 'url' => The url of the parsed page
* string 'type' => Content type * string 'type' => Content type
@ -95,13 +95,13 @@ class ParseUrl {
* if $no_geuessing = false * if $no_geuessing = false
* array'images' = Array of preview pictures * array'images' = Array of preview pictures
* string 'keywords' => The tags which belong to the content * string 'keywords' => The tags which belong to the content
* *
* @todo https://developers.google.com/+/plugins/snippet/ * @todo https://developers.google.com/+/plugins/snippet/
* @verbatim * @verbatim
* <meta itemprop="name" content="Awesome title"> * <meta itemprop="name" content="Awesome title">
* <meta itemprop="description" content="An awesome description"> * <meta itemprop="description" content="An awesome description">
* <meta itemprop="image" content="http://maple.libertreeproject.org/images/tree-icon.png"> * <meta itemprop="image" content="http://maple.libertreeproject.org/images/tree-icon.png">
* *
* <body itemscope itemtype="http://schema.org/Product"> * <body itemscope itemtype="http://schema.org/Product">
* <h1 itemprop="name">Shiny Trinket</h1> * <h1 itemprop="name">Shiny Trinket</h1>
* <img itemprop="image" src="{image-url}" /> * <img itemprop="image" src="{image-url}" />
@ -130,7 +130,7 @@ class ParseUrl {
$url = trim($url, "'"); $url = trim($url, "'");
$url = trim($url, '"'); $url = trim($url, '"');
$url = original_url($url); $url = strip_tracking_query_params($url);
$siteinfo["url"] = $url; $siteinfo["url"] = $url;
$siteinfo["type"] = "link"; $siteinfo["type"] = "link";
@ -142,8 +142,7 @@ class ParseUrl {
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent()); curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
@ -151,7 +150,6 @@ class ParseUrl {
$header = curl_exec($ch); $header = curl_exec($ch);
$curl_info = @curl_getinfo($ch); $curl_info = @curl_getinfo($ch);
$http_code = $curl_info["http_code"];
curl_close($ch); curl_close($ch);
$a->save_timestamp($stamp1, "network"); $a->save_timestamp($stamp1, "network");
@ -197,26 +195,6 @@ class ParseUrl {
} }
} }
$stamp1 = microtime(true);
// Now fetch the body as well
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info["http_code"];
curl_close($ch);
$a->save_timestamp($stamp1, "network");
// Fetch the first mentioned charset. Can be in body or header // Fetch the first mentioned charset. Can be in body or header
$charset = ""; $charset = "";
if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches)) { if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches)) {
@ -476,7 +454,7 @@ class ParseUrl {
/** /**
* @brief Convert tags from CSV to an array * @brief Convert tags from CSV to an array
* *
* @param string $string Tags * @param string $string Tags
* @return array with formatted Hashtags * @return array with formatted Hashtags
*/ */
@ -492,9 +470,9 @@ class ParseUrl {
/** /**
* @brief Add a hasht sign to a string * @brief Add a hasht sign to a string
* *
* This method is used as callback function * This method is used as callback function
* *
* @param string $tag The pure tag name * @param string $tag The pure tag name
* @param int $k Counter for internal use * @param int $k Counter for internal use
*/ */
@ -504,16 +482,16 @@ class ParseUrl {
/** /**
* @brief Add a scheme to an url * @brief Add a scheme to an url
* *
* The src attribute of some html elements (e.g. images) * The src attribute of some html elements (e.g. images)
* can miss the scheme so we need to add the correct * can miss the scheme so we need to add the correct
* scheme * scheme
* *
* @param string $url The url which possibly does have * @param string $url The url which possibly does have
* a missing scheme (a link to an image) * a missing scheme (a link to an image)
* @param string $scheme The url with a correct scheme * @param string $scheme The url with a correct scheme
* (e.g. the url from the webpage which does contain the image) * (e.g. the url from the webpage which does contain the image)
* *
* @return string The url with a scheme * @return string The url with a scheme
*/ */
private static function completeUrl($url, $scheme) { private static function completeUrl($url, $scheme) {

View file

@ -626,7 +626,7 @@ use \Friendica\Core\Config;
// count friends // count friends
$r = q("SELECT count(*) as `count` FROM `contact` $r = q("SELECT count(*) as `count` FROM `contact`
WHERE `uid` = %d AND `rel` IN ( %d, %d ) WHERE `uid` = %d AND `rel` IN ( %d, %d )
AND `self`=0 AND NOT `blocked` AND `hidden`=0", AND `self`=0 AND NOT `blocked` AND NOT `pending` AND `hidden`=0",
intval($uinfo[0]['uid']), intval($uinfo[0]['uid']),
intval(CONTACT_IS_SHARING), intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND) intval(CONTACT_IS_FRIEND)
@ -635,7 +635,7 @@ use \Friendica\Core\Config;
$r = q("SELECT count(*) as `count` FROM `contact` $r = q("SELECT count(*) as `count` FROM `contact`
WHERE `uid` = %d AND `rel` IN ( %d, %d ) WHERE `uid` = %d AND `rel` IN ( %d, %d )
AND `self`=0 AND NOT `blocked` AND `hidden`=0", AND `self`=0 AND NOT `blocked` AND NOT `pending` AND `hidden`=0",
intval($uinfo[0]['uid']), intval($uinfo[0]['uid']),
intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FOLLOWER),
intval(CONTACT_IS_FRIEND) intval(CONTACT_IS_FRIEND)

View file

@ -8,6 +8,8 @@
* This will change in the future. * This will change in the future.
*/ */
use \Friendica\Core\Config;
require_once("include/items.php"); require_once("include/items.php");
require_once("include/bb2diaspora.php"); require_once("include/bb2diaspora.php");
require_once("include/Scrape.php"); require_once("include/Scrape.php");
@ -309,10 +311,6 @@ class Diaspora {
return false; return false;
} }
// Use a dummy importer to import the data for the public copy
$importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE);
$message_id = self::dispatch($importer,$msg);
// Now distribute it to the followers // Now distribute it to the followers
$r = q("SELECT `user`.* FROM `user` WHERE `user`.`uid` IN $r = q("SELECT `user`.* FROM `user` WHERE `user`.`uid` IN
(SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s') (SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s')
@ -320,13 +318,22 @@ class Diaspora {
dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DIASPORA),
dbesc($msg["author"]) dbesc($msg["author"])
); );
if ($r) {
if (dbm::is_result($r)) {
foreach ($r as $rr) { foreach ($r as $rr) {
logger("delivering to: ".$rr["username"]); logger("delivering to: ".$rr["username"]);
self::dispatch($rr,$msg); self::dispatch($rr,$msg);
} }
} else { } else {
logger("No subscribers for ".$msg["author"]." ".print_r($msg, true), LOGGER_DEBUG); $social_relay = (bool)Config::get('system', 'relay_subscribe', false);
// Use a dummy importer to import the data for the public copy
if ($social_relay) {
$importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE);
$message_id = self::dispatch($importer,$msg);
} else {
logger("Unwanted message from ".$msg["author"]." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG);
}
} }
return $message_id; return $message_id;

View file

@ -374,7 +374,10 @@ function profile_sidebar($profile, $block = 0) {
if (dbm::is_result($r)) if (dbm::is_result($r))
$updated = date("c", strtotime($r[0]['updated'])); $updated = date("c", strtotime($r[0]['updated']));
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `hidden` AND NOT `archive` $r = q("SELECT COUNT(*) AS `total` FROM `contact`
WHERE `uid` = %d
AND NOT `self` AND NOT `blocked` AND NOT `pending`
AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s', '')", AND `network` IN ('%s', '%s', '%s', '')",
intval($profile['uid']), intval($profile['uid']),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DFRN),

View file

@ -857,10 +857,15 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
} }
// Now we store the data in the spool directory // Now we store the data in the spool directory
$file = 'item-'.round(microtime(true) * 10000).".msg"; // We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates
$spool = get_spoolpath().'/'.$file; $file = 'item-'.round(microtime(true) * 10000).'-'.mt_rand().'.msg';
file_put_contents($spool, json_encode($arr));
logger("Item wasn't stored - Item was spooled into file ".$file, LOGGER_DEBUG); $spoolpath = get_spoolpath();
if ($spoolpath != "") {
$spool = $spoolpath.'/'.$file;
file_put_contents($spool, json_encode($arr));
logger("Item wasn't stored - Item was spooled into file ".$file, LOGGER_DEBUG);
}
return 0; return 0;
} }

View file

@ -11,11 +11,11 @@ require_once('include/Probe.php');
/** /**
* @brief Curl wrapper * @brief Curl wrapper
* *
* If binary flag is true, return binary results. * If binary flag is true, return binary results.
* Set the cookiejar argument to a string (e.g. "/tmp/friendica-cookies.txt") * Set the cookiejar argument to a string (e.g. "/tmp/friendica-cookies.txt")
* to preserve cookies from one request to the next. * to preserve cookies from one request to the next.
* *
* @param string $url URL to fetch * @param string $url URL to fetch
* @param boolean $binary default false * @param boolean $binary default false
* TRUE if asked to return binary results (file download) * TRUE if asked to return binary results (file download)
@ -23,7 +23,7 @@ require_once('include/Probe.php');
* @param integer $timeout Timeout in seconds, default system config value or 60 seconds * @param integer $timeout Timeout in seconds, default system config value or 60 seconds
* @param string $accept_content supply Accept: header with 'accept_content' as the value * @param string $accept_content supply Accept: header with 'accept_content' as the value
* @param string $cookiejar Path to cookie jar file * @param string $cookiejar Path to cookie jar file
* *
* @return string The fetched content * @return string The fetched content
*/ */
function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_content=Null, $cookiejar = 0) { function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_content=Null, $cookiejar = 0) {
@ -220,13 +220,13 @@ function z_fetch_url($url,$binary = false, &$redirects = 0, $opts=array()) {
/** /**
* @brief Post request to $url * @brief Post request to $url
* *
* @param string $url URL to post * @param string $url URL to post
* @param mixed $params * @param mixed $params
* @param string $headers HTTP headers * @param string $headers HTTP headers
* @param integer $redirects Recursion counter for internal use - default = 0 * @param integer $redirects Recursion counter for internal use - default = 0
* @param integer $timeout The timeout in seconds, default system config value or 60 seconds * @param integer $timeout The timeout in seconds, default system config value or 60 seconds
* *
* @return string The content * @return string The content
*/ */
function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0) { function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0) {
@ -387,10 +387,10 @@ function http_status_exit($val, $description = array()) {
/** /**
* @brief Check URL to se if ts's real * @brief Check URL to se if ts's real
* *
* Take a URL from the wild, prepend http:// if necessary * Take a URL from the wild, prepend http:// if necessary
* and check DNS to see if it's real (or check if is a valid IP address) * and check DNS to see if it's real (or check if is a valid IP address)
* *
* @param string $url The URL to be validated * @param string $url The URL to be validated
* @return boolean True if it's a valid URL, fals if something wrong with it * @return boolean True if it's a valid URL, fals if something wrong with it
*/ */
@ -417,7 +417,7 @@ function validate_url(&$url) {
/** /**
* @brief Checks that email is an actual resolvable internet address * @brief Checks that email is an actual resolvable internet address
* *
* @param string $addr The email address * @param string $addr The email address
* @return boolean True if it's a valid email address, false if it's not * @return boolean True if it's a valid email address, false if it's not
*/ */
@ -438,10 +438,10 @@ function validate_email($addr) {
/** /**
* @brief Check if URL is allowed * @brief Check if URL is allowed
* *
* Check $url against our list of allowed sites, * Check $url against our list of allowed sites,
* wildcards allowed. If allowed_sites is unset return true; * wildcards allowed. If allowed_sites is unset return true;
* *
* @param string $url URL which get tested * @param string $url URL which get tested
* @return boolean True if url is allowed otherwise return false * @return boolean True if url is allowed otherwise return false
*/ */
@ -483,9 +483,9 @@ function allowed_url($url) {
/** /**
* @brief Check if email address is allowed to register here. * @brief Check if email address is allowed to register here.
* *
* Compare against our list (wildcards allowed). * Compare against our list (wildcards allowed).
* *
* @param type $email * @param type $email
* @return boolean False if not allowed, true if allowed * @return boolean False if not allowed, true if allowed
* or if allowed list is not configured * or if allowed list is not configured
@ -672,42 +672,71 @@ function fix_contact_ssl_policy(&$contact,$new_policy) {
} }
} }
function original_url($url, $depth=1, $fetchbody = false) { /**
* @brief Remove Google Analytics and other tracking platforms params from URL
$a = get_app(); *
* @param string $url Any user-submitted URL that may contain tracking params
// Remove Analytics Data from Google and other tracking platforms * @return string The same URL stripped of tracking parameters
*/
function strip_tracking_query_params($url)
{
$urldata = parse_url($url); $urldata = parse_url($url);
if (is_string($urldata["query"])) { if (is_string($urldata["query"])) {
$query = $urldata["query"]; $query = $urldata["query"];
parse_str($query, $querydata); parse_str($query, $querydata);
if (is_array($querydata)) if (is_array($querydata)) {
foreach ($querydata AS $param=>$value) foreach ($querydata AS $param => $value) {
if (in_array($param, array("utm_source", "utm_medium", "utm_term", "utm_content", "utm_campaign", if (in_array($param, array("utm_source", "utm_medium", "utm_term", "utm_content", "utm_campaign",
"wt_mc", "pk_campaign", "pk_kwd", "mc_cid", "mc_eid", "wt_mc", "pk_campaign", "pk_kwd", "mc_cid", "mc_eid",
"fb_action_ids", "fb_action_types", "fb_ref", "fb_action_ids", "fb_action_types", "fb_ref",
"awesm", "wtrid", "awesm", "wtrid",
"woo_campaign", "woo_source", "woo_medium", "woo_content", "woo_term"))) { "woo_campaign", "woo_source", "woo_medium", "woo_content", "woo_term"))) {
$pair = $param."=".urlencode($value); $pair = $param . "=" . urlencode($value);
$url = str_replace($pair, "", $url); $url = str_replace($pair, "", $url);
// Second try: if the url isn't encoded completely // Second try: if the url isn't encoded completely
$pair = $param."=".str_replace(" ", "+", $value); $pair = $param . "=" . str_replace(" ", "+", $value);
$url = str_replace($pair, "", $url); $url = str_replace($pair, "", $url);
// Third try: Maybey the url isn't encoded at all // Third try: Maybey the url isn't encoded at all
$pair = $param."=".$value; $pair = $param . "=" . $value;
$url = str_replace($pair, "", $url); $url = str_replace($pair, "", $url);
$url = str_replace(array("?&", "&&"), array("?", ""), $url); $url = str_replace(array("?&", "&&"), array("?", ""), $url);
} }
}
}
if (substr($url, -1, 1) == "?") if (substr($url, -1, 1) == "?") {
$url = substr($url, 0, -1); $url = substr($url, 0, -1);
}
} }
return $url;
}
/**
* @brief Returns the original URL of the provided URL
*
* This function strips tracking query params and follows redirections, either
* through HTTP code or meta refresh tags. Stops after 10 redirections.
*
* @todo Remove the $fetchbody parameter that generates an extraneous HEAD request
*
* @see ParseUrl::getSiteinfo
*
* @param string $url A user-submitted URL
* @param int $depth The current redirection recursion level (internal)
* @param bool $fetchbody Wether to fetch the body or not after the HEAD requests
* @return string A canonical URL
*/
function original_url($url, $depth = 1, $fetchbody = false) {
$a = get_app();
$url = strip_tracking_query_params($url);
if ($depth > 10) if ($depth > 10)
return($url); return($url);
@ -823,7 +852,7 @@ function short_link($url) {
/** /**
* @brief Encodes content to json * @brief Encodes content to json
* *
* This function encodes an array to json format * This function encodes an array to json format
* and adds an application/json HTTP header to the output. * and adds an application/json HTTP header to the output.
* After finishing the process is getting killed. * After finishing the process is getting killed.

View file

@ -27,15 +27,41 @@ function spool_post_run($argv, $argc) {
$path = get_spoolpath(); $path = get_spoolpath();
if (is_writable($path)){ if (($path != '') AND is_writable($path)){
if ($dh = opendir($path)) { if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) { while (($file = readdir($dh)) !== false) {
// It is not named like a spool file, so we don't care.
if (substr($file, 0, 5) != "item-") {
continue;
}
$fullfile = $path."/".$file; $fullfile = $path."/".$file;
// We don't care about directories either
if (filetype($fullfile) != "file") { if (filetype($fullfile) != "file") {
continue; continue;
} }
// We can't read or write the file? So we don't care about it.
if (!is_writable($fullfile) OR !is_readable($fullfile)) {
continue;
}
$arr = json_decode(file_get_contents($fullfile), true); $arr = json_decode(file_get_contents($fullfile), true);
// If it isn't an array then it is no spool file
if (!is_array($arr)) {
continue;
}
// Skip if it doesn't seem to be an item array
if (!isset($arr['uid']) AND !isset($arr['uri']) AND !isset($arr['network'])) {
continue;
}
$result = item_store($arr); $result = item_store($arr);
logger("Spool file ".$file." stored: ".$result, LOGGER_DEBUG); logger("Spool file ".$file." stored: ".$result, LOGGER_DEBUG);
unlink($fullfile); unlink($fullfile);
} }

View file

@ -875,7 +875,7 @@ function contact_block() {
return $o; return $o;
$r = q("SELECT COUNT(*) AS `total` FROM `contact` $r = q("SELECT COUNT(*) AS `total` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` WHERE `uid` = %d AND NOT `self` AND NOT `blocked`
AND NOT `hidden` AND NOT `archive` AND NOT `pending` AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s')", AND `network` IN ('%s', '%s', '%s')",
intval($a->profile['uid']), intval($a->profile['uid']),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DFRN),
@ -893,8 +893,9 @@ function contact_block() {
// Splitting the query in two parts makes it much faster // Splitting the query in two parts makes it much faster
$r = q("SELECT `id` FROM `contact` $r = q("SELECT `id` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` WHERE `uid` = %d AND NOT `self` AND NOT `blocked`
AND NOT `hidden` AND NOT `archive` AND NOT `pending` AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s') ORDER BY RAND() LIMIT %d", AND `network` IN ('%s', '%s', '%s')
ORDER BY RAND() LIMIT %d",
intval($a->profile['uid']), intval($a->profile['uid']),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DFRN),
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),

View file

@ -1,67 +1,68 @@
<?php <?php
/// @TODO This file has DOS line endings!
require_once("mod/hostxrd.php"); use \Friendica\Core\Config;
require_once("mod/nodeinfo.php");
require_once("mod/hostxrd.php");
function _well_known_init(App $a) { require_once("mod/nodeinfo.php");
if ($a->argc > 1) {
switch($a->argv[1]) { function _well_known_init(App $a) {
case "host-meta": if ($a->argc > 1) {
hostxrd_init($a); switch($a->argv[1]) {
break; case "host-meta":
case "x-social-relay": hostxrd_init($a);
wk_social_relay($a); break;
break; case "x-social-relay":
case "nodeinfo": wk_social_relay($a);
nodeinfo_wellknown($a); break;
break; case "nodeinfo":
} nodeinfo_wellknown($a);
} break;
http_status_exit(404); }
killme(); }
} http_status_exit(404);
killme();
function wk_social_relay(App $a) { }
define('SR_SCOPE_ALL', 'all'); function wk_social_relay(App $a) {
define('SR_SCOPE_TAGS', 'tags');
$subscribe = (bool)Config::get('system', 'relay_subscribe', false);
$subscribe = (bool)get_config('system', 'relay_subscribe');
if ($subscribe) {
if ($subscribe) $scope = Config::get('system', 'relay_scope', SR_SCOPE_ALL);
$scope = get_config('system', 'relay_scope'); } else {
else $scope = SR_SCOPE_NONE;
$scope = ""; }
$tags = array(); $tags = array();
if ($scope == SR_SCOPE_TAGS) { if ($scope == SR_SCOPE_TAGS) {
$server_tags = Config::get('system', 'relay_server_tags');
$server_tags = get_config('system', 'relay_server_tags'); $tagitems = explode(",", $server_tags);
$tagitems = explode(",", $server_tags);
foreach($tagitems AS $tag) {
foreach($tagitems AS $tag) $tags[trim($tag, "# ")] = trim($tag, "# ");
$tags[trim($tag, "# ")] = trim($tag, "# "); }
if (get_config('system', 'relay_user_tags')) { if (Config::get('system', 'relay_user_tags')) {
$terms = q("SELECT DISTINCT(`term`) FROM `search`"); $terms = q("SELECT DISTINCT(`term`) FROM `search`");
foreach($terms AS $term) { foreach($terms AS $term) {
$tag = trim($term["term"], "#"); $tag = trim($term["term"], "#");
$tags[$tag] = $tag; $tags[$tag] = $tag;
} }
} }
} }
$taglist = array(); $taglist = array();
foreach($tags AS $tag) foreach($tags AS $tag) {
$taglist[] = $tag; $taglist[] = $tag;
}
$relay = array("subscribe" => $subscribe,
"scope" => $scope, $relay = array("subscribe" => $subscribe,
"tags" => $taglist); "scope" => $scope,
"tags" => $taglist);
header('Content-type: application/json; charset=utf-8');
echo json_encode($relay, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); header('Content-type: application/json; charset=utf-8');
exit; echo json_encode($relay, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
} exit;
}

View file

@ -574,9 +574,10 @@ function network_content(App $a, $update = 0) {
$sql_order = "`item`.`id`"; $sql_order = "`item`.`id`";
$order_mode = "id"; $order_mode = "id";
} else { } else {
if (get_config('system','use_fulltext_engine')) // Disabled until final decision what to do with this
$sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); //if (get_config('system','use_fulltext_engine'))
else // $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
//else
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
$sql_order = "`item`.`id`"; $sql_order = "`item`.`id`";
$order_mode = "id"; $order_mode = "id";

View file

@ -203,11 +203,12 @@ function search_content(App $a) {
} else { } else {
logger("Start fulltext search for '".$search."'", LOGGER_DEBUG); logger("Start fulltext search for '".$search."'", LOGGER_DEBUG);
if (get_config('system','use_fulltext_engine')) { // Disabled until finally is decided how to proceed with this
$sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); //if (get_config('system','use_fulltext_engine')) {
} else { // $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
//} else {
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
} //}
$r = q("SELECT %s $r = q("SELECT %s
FROM `item` %s FROM `item` %s

View file

@ -48,7 +48,8 @@ function viewcontacts_content(App $a) {
} }
$r = q("SELECT COUNT(*) AS `total` FROM `contact` $r = q("SELECT COUNT(*) AS `total` FROM `contact`
WHERE `uid` = %d AND (NOT `blocked` OR `pending`) AND NOT `hidden` AND NOT `archive` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending`
AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s')", AND `network` IN ('%s', '%s', '%s')",
intval($a->profile['uid']), intval($a->profile['uid']),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DFRN),
@ -59,7 +60,8 @@ function viewcontacts_content(App $a) {
$a->set_pager_total($r[0]['total']); $a->set_pager_total($r[0]['total']);
$r = q("SELECT * FROM `contact` $r = q("SELECT * FROM `contact`
WHERE `uid` = %d AND (NOT `blocked` OR `pending`) AND NOT `hidden` AND NOT `archive` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending`
AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s') AND `network` IN ('%s', '%s', '%s')
ORDER BY `name` ASC LIMIT %d, %d", ORDER BY `name` ASC LIMIT %d, %d",
intval($a->profile['uid']), intval($a->profile['uid']),

View file

@ -51,7 +51,7 @@ if [ $( lsb_release -c | cut -f 2 ) == "trusty" ]; then
sudo service apache2 restart sudo service apache2 restart
elif [ $( lsb_release -c | cut -f 2 ) == "xenial" ]; then elif [ $( lsb_release -c | cut -f 2 ) == "xenial" ]; then
echo ">>> Installing PHP7" echo ">>> Installing PHP7"
sudo apt-get install -y php libapache2-mod-php php-cli php-mysql php-curl php-gd sudo apt-get install -y php libapache2-mod-php php-cli php-mysql php-curl php-gd php-mbstring
sudo apt-get install -y imagemagick sudo apt-get install -y imagemagick
sudo apt-get install -y php-imagick sudo apt-get install -y php-imagick
sudo systemctl restart apache2 sudo systemctl restart apache2

View file

@ -28,7 +28,7 @@
# silke m <silke@silkemeyer.net>, 2015 # silke m <silke@silkemeyer.net>, 2015
# Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2013-2016 # Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2013-2016
# Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2011-2013 # Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2011-2013
# Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2016 # Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2016-2017
# zottel <transifex@zottel.net>, 2011-2012 # zottel <transifex@zottel.net>, 2011-2012
# tschlotfeldt <ts+transifex@ml.tschlotfeldt.de>, 2011 # tschlotfeldt <ts+transifex@ml.tschlotfeldt.de>, 2011
msgid "" msgid ""
@ -36,8 +36,8 @@ msgstr ""
"Project-Id-Version: friendica\n" "Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-19 07:46+0100\n" "POT-Creation-Date: 2016-12-19 07:46+0100\n"
"PO-Revision-Date: 2017-01-02 17:16+0000\n" "PO-Revision-Date: 2017-02-17 07:07+0000\n"
"Last-Translator: rabuzarus <rabuzarus@t-online.de>\n" "Last-Translator: Tobias Diekershoff <tobias.diekershoff@gmx.net>\n"
"Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n" "Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -4667,7 +4667,7 @@ msgid ""
"Shall your connection be bidirectional or not? \"Friend\" implies that you " "Shall your connection be bidirectional or not? \"Friend\" implies that you "
"allow to read and you subscribe to their posts. \"Sharer\" means that you " "allow to read and you subscribe to their posts. \"Sharer\" means that you "
"allow to read but you do not want to read theirs. Approve as: " "allow to read but you do not want to read theirs. Approve as: "
msgstr "Soll Deine Beziehung beidseitig sein oder nicht? \"Freund\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:" msgstr "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"
#: mod/notifications.php:209 #: mod/notifications.php:209
msgid "Friend" msgid "Friend"

View file

@ -1066,7 +1066,7 @@ $a->strings["Claims to be known to you: "] = "Behauptet Dich zu kennen: ";
$a->strings["yes"] = "ja"; $a->strings["yes"] = "ja";
$a->strings["no"] = "nein"; $a->strings["no"] = "nein";
$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Fan/Admirer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr könnt gegenseitig die Beiträge des Anderen lesen dürft. \"Fan/Verehrer\", dass du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"; $a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Fan/Admirer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr könnt gegenseitig die Beiträge des Anderen lesen dürft. \"Fan/Verehrer\", dass du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:";
$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Sharer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Freund\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:"; $a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Sharer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "Soll Deine Beziehung beidseitig sein oder nicht? \"Kontakt\" bedeutet, ihr gegenseitig die Beiträge des Anderen lesen dürft. \"Teilenden\", das du das lesen deiner Beiträge erlaubst aber nicht die Beiträge der anderen Seite lesen möchtest. Genehmigen als:";
$a->strings["Friend"] = "Kontakt"; $a->strings["Friend"] = "Kontakt";
$a->strings["Sharer"] = "Teilenden"; $a->strings["Sharer"] = "Teilenden";
$a->strings["Fan/Admirer"] = "Fan/Verehrer"; $a->strings["Fan/Admirer"] = "Fan/Verehrer";

View file

@ -3,14 +3,15 @@
# This file is distributed under the same license as the Friendica package. # This file is distributed under the same license as the Friendica package.
# #
# Translators: # Translators:
# Jonatan Nyberg <jonatan@autistici.org>, 2017
# Mike Macgirvin, 2010 # Mike Macgirvin, 2010
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: friendica\n" "Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-19 07:46+0100\n" "POT-Creation-Date: 2016-12-19 07:46+0100\n"
"PO-Revision-Date: 2016-12-19 10:01+0000\n" "PO-Revision-Date: 2017-02-13 20:15+0000\n"
"Last-Translator: fabrixxm <fabrix.xm@gmail.com>\n" "Last-Translator: Jonatan Nyberg <jonatan@autistici.org>\n"
"Language-Team: Swedish (http://www.transifex.com/Friendica/friendica/language/sv/)\n" "Language-Team: Swedish (http://www.transifex.com/Friendica/friendica/language/sv/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -20,7 +21,7 @@ msgstr ""
#: include/contact_widgets.php:6 #: include/contact_widgets.php:6
msgid "Add New Contact" msgid "Add New Contact"
msgstr "" msgstr "Lägg till kontakt"
#: include/contact_widgets.php:7 #: include/contact_widgets.php:7
msgid "Enter address or web location" msgid "Enter address or web location"

View file

@ -5,7 +5,7 @@ function string_plural_select_sv($n){
return ($n != 1);; return ($n != 1);;
}} }}
; ;
$a->strings["Add New Contact"] = ""; $a->strings["Add New Contact"] = "Lägg till kontakt";
$a->strings["Enter address or web location"] = ""; $a->strings["Enter address or web location"] = "";
$a->strings["Example: bob@example.com, http://example.com/barbara"] = "Exempel: adam@exempel.com, http://exempel.com/bertil"; $a->strings["Example: bob@example.com, http://example.com/barbara"] = "Exempel: adam@exempel.com, http://exempel.com/bertil";
$a->strings["Connect"] = "Skicka kontaktf&ouml;rfr&aring;gan"; $a->strings["Connect"] = "Skicka kontaktf&ouml;rfr&aring;gan";

View file

@ -147,7 +147,7 @@
<div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div> <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$performance}}</h3> <h3>{{$performance}}</h3>
{{include file="field_checkbox.tpl" field=$use_fulltext_engine}} <!-- {{include file="field_checkbox.tpl" field=$use_fulltext_engine}} -->
{{include file="field_checkbox.tpl" field=$only_tag_search}} {{include file="field_checkbox.tpl" field=$only_tag_search}}
{{include file="field_input.tpl" field=$itemcache}} {{include file="field_input.tpl" field=$itemcache}}
{{include file="field_input.tpl" field=$itemcache_duration}} {{include file="field_input.tpl" field=$itemcache_duration}}

View file

@ -81,39 +81,25 @@ function showHideCommentBox(id) {
} }
function commentOpenUI(obj, id) { function commentOpenUI(obj, id) {
$(document).unbind( "click.commentOpen", handler ); $("#comment-edit-text-" + id).addClass("comment-edit-text-full").removeClass("comment-edit-text-empty");
// Choose an arbitrary tab index that's greater than what we're using in jot (3 of them)
var handler = function() { // The submit button gets tabindex + 1
if (obj.value == '') { $("#comment-edit-text-" + id).attr('tabindex','9');
$("#comment-edit-text-" + id).addClass("comment-edit-text-full").removeClass("comment-edit-text-empty"); $("#comment-edit-submit-" + id).attr('tabindex','10');
// Choose an arbitrary tab index that's greater than what we're using in jot (3 of them) $("#comment-edit-submit-wrapper-" + id).show();
// The submit button gets tabindex + 1 // initialize autosize for this comment
$("#comment-edit-text-" + id).attr('tabindex','9'); autosize($("#comment-edit-text-" + id + ".text-autosize"));
$("#comment-edit-submit-" + id).attr('tabindex','10');
$("#comment-edit-submit-wrapper-" + id).show();
// initialize autosize for this comment
autosize($("#comment-edit-text-" + id + ".text-autosize"));
}
};
$(document).bind( "click.commentOpen", handler );
} }
function commentCloseUI(obj, id) { function commentCloseUI(obj, id) {
$(document).unbind( "click.commentClose", handler ); if (obj.value === '') {
$("#comment-edit-text-" + id).removeClass("comment-edit-text-full").addClass("comment-edit-text-empty");
var handler = function() { $("#comment-edit-text-" + id).removeAttr('tabindex');
if (obj.value === '') { $("#comment-edit-submit-" + id).removeAttr('tabindex');
$("#comment-edit-text-" + id).removeClass("comment-edit-text-full").addClass("comment-edit-text-empty"); $("#comment-edit-submit-wrapper-" + id).hide();
$("#comment-edit-text-" + id).removeAttr('tabindex'); // destroy the automatic textarea resizing
$("#comment-edit-submit-" + id).removeAttr('tabindex'); autosize.destroy($("#comment-edit-text-" + id + ".text-autosize"));
$("#comment-edit-submit-wrapper-" + id).hide(); }
// destroy the automatic textarea resizing
autosize.destroy($("#comment-edit-text-" + id + ".text-autosize"));
}
};
$(document).bind( "click.commentClose", handler );
} }
function jotTextOpenUI(obj) { function jotTextOpenUI(obj) {

View file

@ -10,7 +10,7 @@ $(document).ready(function(){
$("#back-to-top").fadeOut(); $("#back-to-top").fadeOut();
} }
}); });
// scroll body to 0px on click // scroll body to 0px on click
$("#back-to-top").click(function () { $("#back-to-top").click(function () {
$("body,html").animate({ $("body,html").animate({
@ -54,7 +54,7 @@ $(document).ready(function(){
} }
// make responsive tabmenu with flexmenu.js // make responsive tabmenu with flexmenu.js
// the menupoints which doesn't fit in the second nav bar will moved to a // the menupoints which doesn't fit in the second nav bar will moved to a
// dropdown menu. Look at common_tabs.tpl // dropdown menu. Look at common_tabs.tpl
$("ul.tabs.flex-nav").flexMenu({ $("ul.tabs.flex-nav").flexMenu({
'cutoff': 2, 'cutoff': 2,
@ -82,17 +82,17 @@ $(document).ready(function(){
return false; return false;
} }
}); });
if(checked == true) { if(checked == true) {
$("a#item-delete-selected").fadeTo(400, 1); $("a#item-delete-selected").fadeTo(400, 1);
$("a#item-delete-selected").show(); $("a#item-delete-selected").show();
} else { } else {
$("a#item-delete-selected").fadeTo(400, 0, function(){ $("a#item-delete-selected").fadeTo(400, 0, function(){
$("a#item-delete-selected").hide(); $("a#item-delete-selected").hide();
}); });
} }
}); });
//$('ul.flex-nav').flexMenu(); //$('ul.flex-nav').flexMenu();
// initialize the bootstrap tooltips // initialize the bootstrap tooltips
@ -128,7 +128,7 @@ $(document).ready(function(){
// append the new heading to the navbar // append the new heading to the navbar
$("#topbar-second > .container > #tabmenu").append(newText); $("#topbar-second > .container > #tabmenu").append(newText);
// try to get the value of the original search input to insert it // try to get the value of the original search input to insert it
// as value in the nav-search-input // as value in the nav-search-input
var searchValue = $("#search-wrapper .form-group-search input").val(); var searchValue = $("#search-wrapper .form-group-search input").val();

View file

@ -1210,7 +1210,7 @@ section {
.wall-item-container .wall-item-actions-social a { .wall-item-container .wall-item-actions-social a {
margin-right: 3em; margin-right: 3em;
} }
.wall-item-container .wall-item-actions-social a .active { .wall-item-container .wall-item-actions-social a.active {
font-weight: bold; font-weight: bold;
} }
.wall-item-container .wall-item-actions-tools { .wall-item-container .wall-item-actions-tools {

View file

@ -1210,7 +1210,7 @@ section {
.wall-item-container .wall-item-actions-social a { .wall-item-container .wall-item-actions-social a {
margin-right: 3em; margin-right: 3em;
} }
.wall-item-container .wall-item-actions-social a .active { .wall-item-container .wall-item-actions-social a.active {
font-weight: bold; font-weight: bold;
} }
.wall-item-container .wall-item-actions-tools { .wall-item-container .wall-item-actions-tools {

View file

@ -1210,7 +1210,7 @@ section {
.wall-item-container .wall-item-actions-social a { .wall-item-container .wall-item-actions-social a {
margin-right: 3em; margin-right: 3em;
} }
.wall-item-container .wall-item-actions-social a .active { .wall-item-container .wall-item-actions-social a.active {
font-weight: bold; font-weight: bold;
} }
.wall-item-container .wall-item-actions-tools { .wall-item-container .wall-item-actions-tools {

View file

@ -576,7 +576,7 @@ section {
} }
.wall-item-actions-social { float: left; margin-top: 0.5em; .wall-item-actions-social { float: left; margin-top: 0.5em;
a { margin-right: 3em; a { margin-right: 3em;
.active { font-weight: bold;} &.active { font-weight: bold;}
} }
} }
.wall-item-actions-tools { float: right; width: 15%; .wall-item-actions-tools { float: right; width: 15%;