Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Michael Vogel 2015-04-05 20:30:38 +02:00
commit 8bdb026745
149 changed files with 119107 additions and 112211 deletions

View file

@ -1,5 +1,33 @@
Version 3.4
Optionally, "like" and "dislike" activities don't update thread timestamp (annando)
Updated markdown libraries (annando)
Updated jQuery (StefOfficiel)
Cache zrl verification requests to prevent DSoS (issue #1453) (annando)
"Verify SSL" options affects also VERIFYHOST (annando)
Better handling of hashtags (annando)
Updated translations (translation teams, tobias)
Access a contact directly from the contact-manager-page (FlxAlbroscheit)
Reworked GUID generation, remove db store (annando)
Improve search for tags and terms (annando)
Fix OAuth signature (thorsten23)
Fix utf8 characters in items (issue #1307) (hauke)
Ignore tag-likes char sequences in code blocks (issue #1041) (fabrixxm)
Fix sending email to CC recipients (issue #1437) (fabrixxm)
Fix signature check of likes from diaspora (issue #905) (mike, annando)
Fix pagination urls (issue #1341) (fabrixxm)
Add scheme if missing in "web link" dialog (issue #1362) (fabrixxm)
Don't detect Facebook and App.net RSS feeds as contacts (issue #1432) (annando)
Add cli command to generate database.sql from scheme description (issue #1370) (fabrixxm)
Fix warning trying to creating already existing itemcache dir (pztrn)
Send update to directory when account is removed (issue #1038) (annando)
Fix settings page's aside menu visibility (issue #1459) (fabrixxm)
Don't show past events in event reminder in profile page (issue #1306) (annando)
Add help text to explain the options for approving contacts (issue #1349) (silke)
API set as unseen only posts returned by the call (issue #1063) (annando)
Version 3.3.3
More separation between php and html in photo album (issue #1258) (rabuzarus)
Enhanced community page shows public posts from public contacts of public profiles (annando)
Support for IndieAuth/Web-sign-in (hauke)
@ -67,17 +95,17 @@ Version 3.3
API
added support in the API to allow image uploads from Twidere
support for the diaspora app in Firefox
Themes
Themes
Stopped support of unmaintained themes. They will continue to work if enabled but are no longer displayed in the list of themes.
Merged all "zero" themes into a theme with variations.
Merged all "zero" themes into a theme with variations.
new default avatar by Andi Stadler
Usability
network page as default page after login
sections on users' settings page are now collapsable
automatic updating the network stream was improved
Interaction
ignoring of threads
for selected contects one can now get notifications when they post something, useful e.g. for forums
@ -85,8 +113,8 @@ Version 3.3
many improvement on all connectors, new app.net connector
the algorithm for shortening postings when posting to limited platforms was improved
improvements for the remote_self functionality for RSS/Atom feeds were done
System stuff
System stuff
no more apc support due problems with PHP 5.5
privacy image cache moved from an addon into the core
updated the following libraries: smarty 3.1.19, fullcalendar 1.6.4, jquery 1.11, jgrowl 1.3.0
@ -99,8 +127,8 @@ Version 3.3
some bugs were fixed for the profile import function
BBCode handling and reformatting to e.g. markdown was improved
Internal PusH server for communication with OStatus contacts
Addons
Addons
translation now done at transifex as well
"newmemberwidget" adds widget with help links + welcome message to sidebar of network tab for new members
new statistics addon to take part in the Diaspora* survey
@ -109,10 +137,10 @@ Version 3.3
new connector for the buffer service
improvements for the connectors with Twitter, StatusNet/GNU Social, pump.io, google+ and facebook
improvements to the cal and jappix-mini addons
Change in the structure of the git repo
The "master" branch will now contain stable stuff and hotfixes.
The new "develop" branch will contain the latest changes.
The new "develop" branch will contain the latest changes.
Version 3.2

113
boot.php
View file

@ -15,10 +15,10 @@ require_once('update.php');
require_once('include/dbstructure.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Ginger');
define ( 'FRIENDICA_VERSION', '3.3.3' );
define ( 'FRIENDICA_CODENAME', 'Lily of the valley');
define ( 'FRIENDICA_VERSION', '3.4.0' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1178 );
define ( 'DB_UPDATE_VERSION', 1182 );
define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@ -127,6 +127,11 @@ define ( 'PAGE_FREELOVE', 3 );
define ( 'PAGE_BLOG', 4 );
define ( 'PAGE_PRVGROUP', 5 );
// Type of the community page
define ( 'CP_NO_COMMUNITY_PAGE', -1 );
define ( 'CP_USERS_ON_SERVER', 0 );
define ( 'CP_GLOBAL_COMMUNITY', 1 );
/**
* Network and protocol family types
*/
@ -1191,36 +1196,25 @@ if(! function_exists('check_plugins')) {
}
}
function get_guid($size=16) {
$exists = true; // assume by default that we don't have a unique guid
do {
$prefix = "";
while (strlen($prefix) < ($size - 13))
$prefix .= mt_rand();
function get_guid($size=16, $prefix = "") {
$s = substr(uniqid($prefix), -$size);
if ($prefix == "") {
$a = get_app();
$prefix = hash("crc32", $a->get_hostname());
}
$r = q("select id from guid where guid = '%s' limit 1", dbesc($s));
if(! count($r))
$exists = false;
} while($exists);
q("insert into guid (guid) values ('%s') ", dbesc($s));
return $s;
while (strlen($prefix) < ($size - 13))
$prefix .= mt_rand();
if ($size >= 24) {
$prefix = substr($prefix, 0, $size - 22);
return(str_replace(".", "", uniqid($prefix, true)));
} else {
$prefix = substr($prefix, 0, $size - 13);
return(uniqid($prefix));
}
}
/*function get_guid($size=16) {
$exists = true; // assume by default that we don't have a unique guid
do {
$s = random_string($size);
$r = q("select id from guid where guid = '%s' limit 1", dbesc($s));
if(! count($r))
$exists = false;
} while($exists);
q("insert into guid ( guid ) values ( '%s' ) ", dbesc($s));
return $s;
}*/
// wrapper for adding a login box. If $register == true provide a registration
// link. This will most always depend on the value of $a->config['register_policy'].
// returns the complete html for inserting into the page
@ -1405,11 +1399,11 @@ if(! function_exists('get_max_import_size')) {
if(! function_exists('profile_load')) {
function profile_load(&$a, $nickname, $profile = 0, $profiledata = array()) {
$user = q("select uid from user where nickname = '%s' limit 1",
$user = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname)
);
if(! ($user && count($user))) {
if(!$user && count($user) && !count($profiledata)) {
logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
notice( t('Requested account is not available.') . EOL );
$a->error = 404;
@ -1440,7 +1434,7 @@ if(! function_exists('profile_load')) {
intval($profile_int)
);
}
if((! $r) && (! count($r))) {
if((!$r) && (!count($r))) {
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 and `contact`.`self` = 1 LIMIT 1",
@ -1448,7 +1442,7 @@ if(! function_exists('profile_load')) {
);
}
if(($r === false) || (! count($r))) {
if(($r === false) || (!count($r)) && !count($profiledata)) {
logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
notice( t('Requested profile is not available.') . EOL );
$a->error = 404;
@ -1457,7 +1451,7 @@ if(! function_exists('profile_load')) {
// fetch user tags if this isn't the default profile
if(! $r[0]['is-default']) {
if(!$r[0]['is-default']) {
$x = q("select `pub_keywords` from `profile` where uid = %d and `is-default` = 1 limit 1",
intval($r[0]['profile_uid'])
);
@ -1673,8 +1667,24 @@ if(! function_exists('profile_sidebar')) {
if (!$block){
$contact_block = contact_block();
}
if(is_array($a->profile) AND !$a->profile['hide-friends']) {
$r = q("SELECT `gcontact`.`updated` FROM `contact` INNER JOIN `gcontact` WHERE `gcontact`.`nurl` = `contact`.`nurl` AND `self` AND `uid` = %d LIMIT 1",
intval($a->profile['uid']));
if(count($r))
$updated = date("c", strtotime($r[0]['updated']));
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0
AND `network` IN ('%s', '%s', '%s', '')",
intval($profile['uid']),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_OSTATUS)
);
if(count($r))
$contacts = intval($r[0]['total']);
}
}
$p = array();
foreach($profile as $k => $v) {
@ -1699,6 +1709,8 @@ if(! function_exists('profile_sidebar')) {
'$homepage' => $homepage,
'$about' => $about,
'$network' => t('Network:'),
'$contacts' => $contacts,
'$updated' => $updated,
'$diaspora' => $diaspora,
'$contact_block' => $contact_block,
));
@ -1818,10 +1830,10 @@ if(! function_exists('get_events')) {
$bd_short = t('F d');
$r = q("SELECT `event`.* FROM `event`
WHERE `event`.`uid` = %d AND `type` != 'birthday' AND `start` < '%s' AND `start` > '%s'
WHERE `event`.`uid` = %d AND `type` != 'birthday' AND `start` < '%s' AND `start` >= '%s'
ORDER BY `start` ASC ",
intval(local_user()),
dbesc(datetime_convert('UTC','UTC','now + 6 days')),
dbesc(datetime_convert('UTC','UTC','now + 7 days')),
dbesc(datetime_convert('UTC','UTC','now - 1 days'))
);
@ -1838,6 +1850,7 @@ if(! function_exists('get_events')) {
}
$classtoday = (($istoday) ? 'event-today' : '');
$skip = 0;
foreach($r as &$rr) {
if($rr['adjust'])
@ -1851,6 +1864,12 @@ if(! function_exists('get_events')) {
$title = t('[No description]');
$strt = datetime_convert('UTC',$rr['convert'] ? $a->timezone : 'UTC',$rr['start']);
if(substr($strt,0,10) < datetime_convert('UTC',$a->timezone,'now','Y-m-d')) {
$skip++;
continue;
}
$today = ((substr($strt,0,10) === datetime_convert('UTC',$a->timezone,'now','Y-m-d')) ? true : false);
$rr['link'] = $md;
@ -1865,7 +1884,7 @@ if(! function_exists('get_events')) {
return replace_macros($tpl, array(
'$baseurl' => $a->get_baseurl(),
'$classtoday' => $classtoday,
'$count' => count($r),
'$count' => count($r) - $skip,
'$event_reminders' => t('Event Reminders'),
'$event_title' => t('Events this week:'),
'$events' => $r,
@ -2169,6 +2188,20 @@ function get_my_url() {
function zrl_init(&$a) {
$tmp_str = get_my_url();
if(validate_url($tmp_str)) {
// Is it a DDoS attempt?
// The check fetches the cached value from gprobe to reduce the load for this system
$urlparts = parse_url($tmp_str);
$result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) {
$result = unserialize($result);
if ($result["network"] == NETWORK_FEED) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return;
}
}
proc_run('php','include/gprobe.php',bin2hex($tmp_str));
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
call_hooks('zrl_init',$arr);
@ -2335,7 +2368,9 @@ function get_itemcachepath() {
if ($temppath != "") {
$itemcache = $temppath."/itemcache";
mkdir($itemcache);
if(!file_exists($itemcache) && !is_dir($itemcache)) {
mkdir($itemcache);
}
if (is_dir($itemcache) AND is_writable($itemcache)) {
set_config("system", "itemcache", $itemcache);

File diff suppressed because it is too large Load diff

View file

@ -18,25 +18,24 @@ Remember the questions you had when you first tried Friendica? A good place to s
**Translations**
The documentation contains help on how to translate Friendica in the /help/translations page.
* Check if the user interface has already been translated to your language.
* If not, we might want to start with translating the /help pages.
The documentation contains help on how to translate Friendica in the [at Transifex](/help/translations) where the UI is translated.
If you don't want to translate the UI, or it is already done to your satisfaction, you might want to work on the translation of the /help files?
**Design**
Are you good at designing things? If you have seen Friendica you probably have ideas to improve it, haven't you?
* If you would like to work with us on enhancing the user interface, please join the [UX Watchdogs forum](https://fc.oscp.info/profile/ux-watchdogs)
* Make plans for a better Friendica interface design and share them with us.
* Tell us if you are able to realize your ideas or what kind of help you need. We can't promise we have the right skills in the group but we'll try.
* Choose a thing to start with, e.g. work on the icon set of your favourite theme
**Programming**
* **Issues:** Have a look at our issue tracker on gihub!
* **Issues:** Have a look at our [issue tracker](https://github.com/friendica/friendica) on gihub!
* Try to reproduce a bug that needs more inquries and write down what you find out.
* If a bug looks fixed, ask the bug reporters for feedback to find out if the bug can be closed.
* Fix a bug if you can.
* Fix a bug if you can. Please make the pull request against the *develop* branch of the repository.
* **Web interface:** The thing many people want most is a better interface, preferably a responsive Friendica theme. This is a piece of work! If you want to get involved here:
* Look at the first steps that were made (e.g. the clean theme). Ask us to find out whom to talk to about their experiences.

View file

@ -3,6 +3,8 @@ Vagrant for Friendica Developers
* [Home](help)
**Getting started**
[Vagrant](https://www.vagrantup.com/) is a virtualization solution for developers. No need to setup up a webserver, database etc. before actually starting. Vagrant creates a virtual machine (an Ubuntu 12.04) for you that you can just run inside VirtualBox and start to work directly on Friendica. What you need to do:
1. Install VirtualBox and vagrant.
@ -20,4 +22,18 @@ If you want to stop vagrant after finishing your work, run the following command
in the development directory.
**Import test data**
If you want some test data in your vagrant Friendica instance import the database dump friendica_test_data.sql like so (inside the VM):
$> mysql -u root -p friendica < /vagrant/friendica_test_data.sql
You will then have the following accounts to login:
* admin, password admin
* friendica1, password friendica
* friendica2, password friendica2 and so on until friendica5
* friendica1 is connected to all others. friendica1 has two groups: group1 with friendica2 and friendica4, group2 with friendica3 and friendica5.
* friendica2 and friendica3 are conntected. friendica4 and friendica5 are connected.
For further documentation of vagrant, please see [the vagrant*docs*](https://docs.vagrantup.com/v2/).

1787
friendica_test_data.sql Normal file

File diff suppressed because one or more lines are too long

BIN
images/rm-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

View file

@ -15,7 +15,7 @@ function user_remove($uid) {
call_hooks('remove_user',$r[0]);
// save username (actually the nickname as it is guaranteed
// save username (actually the nickname as it is guaranteed
// unique), so it cannot be re-registered in the future.
q("insert into userd ( username ) values ( '%s' )",
@ -46,6 +46,10 @@ function user_remove($uid) {
// q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
proc_run('php', "include/notifier.php", "removeme", $uid);
// Send an update to the directory
proc_run('php', "include/directory.php", $r[0]['url']);
if($uid == local_user()) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
@ -191,7 +195,7 @@ if(! function_exists('contact_photo_menu')){
function contact_photo_menu($contact) {
$a = get_app();
$contact_url="";
$pm_url="";
$status_link="";
@ -222,24 +226,24 @@ function contact_photo_menu($contact) {
$contact_url = $a->get_baseurl() . '/contacts/' . $contact['id'];
$posts_link = $a->get_baseurl() . '/network/0?nets=all&cid=' . $contact['id'];
$contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1';
$menu = Array(
'poke' => array(t("Poke"), $poke_link),
'status' => array(t("View Status"), $status_link),
'profile' => array(t("View Profile"), $profile_link),
'photos' => array(t("View Photos"), $photos_link),
'network' => array(t("Network Posts"), $posts_link),
'photos' => array(t("View Photos"), $photos_link),
'network' => array(t("Network Posts"), $posts_link),
'edit' => array(t("Edit Contact"), $contact_url),
'drop' => array(t("Drop Contact"), $contact_drop_link),
'pm' => array(t("Send PM"), $pm_url),
);
$args = array('contact' => $contact, 'menu' => &$menu);
call_hooks('contact_photo_menu', $args);
/* $o = "";
foreach($menu as $k=>$v){
if ($v!="") {
@ -293,3 +297,107 @@ function contacts_not_grouped($uid,$start = 0,$count = 0) {
return $r;
}
function get_contact($url, $uid = 0) {
require_once("include/Scrape.php");
$data = array();
$contactid = 0;
// is it an address in the format user@server.tld?
if (!strstr($url, "http") OR strstr($url, "@")) {
$data = probe_url($url);
$url = $data["url"];
if ($url == "")
return 0;
}
$contact = q("SELECT `id`, `avatar-date` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($url)),
intval($uid));
if (!$contact)
$contact = q("SELECT `id`, `avatar-date` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `uid` = %d",
dbesc($url),
dbesc(normalise_link($url)),
intval($uid));
if ($contact) {
$contactid = $contact[0]["id"];
// Update the contact every 7 days
$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -7 days'));
//$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -12 hours'));
if (!$update_photo)
return($contactid);
}
if (!count($data))
$data = probe_url($url);
// Does this address belongs to a valid network?
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
return 0;
// tempory programming. Can be deleted after 2015-02-07
if (($data["alias"] == "") AND (normalise_link($data["url"]) != normalise_link($url)))
$data["alias"] = normalise_link($url);
if ($contactid == 0) {
q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,
`name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
`batch`, `request`, `confirm`, `poco`,
`writable`, `blocked`, `readonly`, `pending`)
VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
intval($uid),
dbesc(datetime_convert()),
dbesc($data["url"]),
dbesc(normalise_link($data["url"])),
dbesc($data["addr"]),
dbesc($data["alias"]),
dbesc($data["notify"]),
dbesc($data["poll"]),
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc($data["photo"]),
dbesc($data["network"]),
dbesc($data["pubkey"]),
intval(CONTACT_IS_SHARING),
intval($data["priority"]),
dbesc($data["batch"]),
dbesc($data["request"]),
dbesc($data["confirm"]),
dbesc($data["poco"])
);
$contact = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($data["url"])),
intval($uid));
if (!$contact)
return 0;
$contactid = $contact[0]["id"];
}
require_once("Photo.php");
$photos = import_profile_photo($data["photo"],$uid,$contactid);
q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s',
`addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s',
`name-date` = '%s', `uri-date` = '%s', `avatar-date` = '%s' WHERE `id` = %d",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($data["addr"]),
dbesc($data["alias"]),
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contactid)
);
return $contactid;
}

View file

@ -516,7 +516,12 @@ class Photo {
return FALSE;
$string = $this->imageString();
$a = get_app();
$stamp1 = microtime(true);
file_put_contents($path, $string);
$a->save_timestamp($stamp1, "file");
}
public function imageString() {
@ -767,7 +772,12 @@ function get_photo_info($url) {
$filesize = strlen($img_str);
$tempfile = tempnam(get_temppath(), "cache");
$a = get_app();
$stamp1 = microtime(true);
file_put_contents($tempfile, $img_str);
$a->save_timestamp($stamp1, "file");
$data = getimagesize($tempfile);
unlink($tempfile);
@ -851,7 +861,10 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
return(array());
} elseif (strlen($imagedata) == 0) {
logger("Uploading picture from ".$url, LOGGER_DEBUG);
$stamp1 = microtime(true);
$imagedata = @file_get_contents($url);
$a->save_timestamp($stamp1, "file");
}
$maximagesize = get_config('system','maximagesize');
@ -875,7 +888,11 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
*/
$tempfile = tempnam(get_temppath(), "cache");
$stamp1 = microtime(true);
file_put_contents($tempfile, $imagedata);
$a->save_timestamp($stamp1, "file");
$data = getimagesize($tempfile);
if (!isset($data["mime"])) {

View file

@ -364,16 +364,6 @@ function probe_url($url, $mode = PROBE_NORMAL) {
$network = NETWORK_TWITTER;
}
if (strpos($url,'www.facebook.com')) {
$connectornetworks = true;
$network = NETWORK_FACEBOOK;
}
if (strpos($url,'alpha.app.net')) {
$appnet = true;
$network = NETWORK_APPNET;
}
// Twitter is deactivated since twitter closed its old API
//$twitter = ((strpos($url,'twitter.com') !== false) ? true : false);
$lastfm = ((strpos($url,'last.fm/user') !== false) ? true : false);
@ -433,7 +423,7 @@ function probe_url($url, $mode = PROBE_NORMAL) {
// to a contact on incoming messages to prevent spam, and we won't know which one
// to match. So in case of two, one of them is stored as an alias. Only store URL's
// and not webfinger user@host aliases. If they've got more than two non-email style
// aliases, let's hope we're lucky and get one that matches the feed author-uri because
// aliases, let's hope we're lucky and get one that matches the feed author-uri because
// otherwise we're screwed.
foreach($links as $link) {
@ -448,6 +438,10 @@ function probe_url($url, $mode = PROBE_NORMAL) {
}
}
}
// If the profile is different from the url then the url is abviously an alias
if (($alias == "") AND ($profile != "") AND !$at_addr AND (normalise_link($profile) != normalise_link($url)))
$alias = $url;
}
elseif($mode == PROBE_NORMAL) {
@ -522,8 +516,8 @@ function probe_url($url, $mode = PROBE_NORMAL) {
if($j) {
$network = NETWORK_ZOT;
$vcard = array(
'fn' => $j->fullname,
'nick' => $j->nickname,
'fn' => $j->fullname,
'nick' => $j->nickname,
'photo' => $j->photo
);
$profile = $j->url;
@ -565,6 +559,10 @@ function probe_url($url, $mode = PROBE_NORMAL) {
$network = NETWORK_DIASPORA;
elseif($has_lrdd)
$network = NETWORK_OSTATUS;
if(strpos($url,'@'))
$addr = str_replace('acct:', '', $url);
$priority = 0;
if($hcard && ! $vcard) {
@ -758,6 +756,22 @@ function probe_url($url, $mode = PROBE_NORMAL) {
if(($network === NETWORK_FEED) && ($poll) && (! x($vcard,'fn')))
$vcard['fn'] = $url;
if (($notify != "") AND ($poll != "")) {
$baseurl = matching($notify, $poll);
$baseurl2 = matching($baseurl, $profile);
if ($baseurl2 != "")
$baseurl = $baseurl2;
}
if (($baseurl == "") AND ($notify != ""))
$baseurl = matching($profile, $notify);
if (($baseurl == "") AND ($poll != ""))
$baseurl = matching($profile, $poll);
$baseurl = rtrim($baseurl, "/");
$vcard['fn'] = notags($vcard['fn']);
$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
@ -776,11 +790,12 @@ function probe_url($url, $mode = PROBE_NORMAL) {
$result['network'] = $network;
$result['alias'] = $alias;
$result['pubkey'] = $pubkey;
$result['baseurl'] = $baseurl;
logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
// Trying if it maybe a diaspora account
if ($result['network'] == NETWORK_FEED) {
if (($result['network'] == NETWORK_FEED) OR ($result['addr'] == "")) {
require_once('include/bbcode.php');
$address = GetProfileUsername($url, "", true);
$result2 = probe_url($address, $mode);
@ -792,3 +807,20 @@ function probe_url($url, $mode = PROBE_NORMAL) {
return $result;
}
function matching($part1, $part2) {
$len = min(strlen($part1), strlen($part2));
$match = "";
$matching = true;
$i = 0;
while (($i <= $len) AND $matching) {
if (substr($part1, $i, 1) == substr($part2, $i, 1))
$match .= substr($part1, $i, 1);
else
$matching = false;
$i++;
}
return($match);
}

View file

@ -733,8 +733,7 @@
$_REQUEST['body'] = html2bbcode($txt);
}
}
else
} else
$_REQUEST['body'] = requestdata('status');
$_REQUEST['title'] = requestdata('title');
@ -811,14 +810,15 @@
}
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
// upload the image if we have one
$_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_upload.php');
$media = wall_upload_post($a);
if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n".$media;
}
}
if(x($_FILES,'media')) {
// upload the image if we have one
$_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_upload.php');
$media = wall_upload_post($a);
if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n".$media;
}
// set this so that the item_post() function is quiet and doesn't redirect or emit json
@ -848,7 +848,7 @@
// get last public wall message
$lastwall = q("SELECT `item`.*, `i`.`contact-id` as `reply_uid`, `i`.`author-link` AS `item-author`
FROM `item`, `item` as `i`
WHERE `item`.`contact-id` = %d
WHERE `item`.`contact-id` = %d AND `item`.`uid` = %d
AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
AND `i`.`id` = `item`.`parent`
AND `item`.`type`!='activity'
@ -856,6 +856,7 @@
ORDER BY `item`.`created` DESC
LIMIT 1",
intval($user_info['cid']),
intval(api_user()),
dbesc($user_info['url']),
dbesc(normalise_link($user_info['url'])),
dbesc($user_info['url']),
@ -1128,15 +1129,14 @@
$ret = api_format_items($r,$user_info);
// We aren't going to try to figure out at the item, group, and page
// level which items you've seen and which you haven't. If you're looking
// at the network timeline just mark everything seen.
// Set all posts from the query above to seen
$idarray = array();
foreach ($r AS $item)
$idarray[] = intval($item["id"]);
$r = q("UPDATE `item` SET `unseen` = 0
WHERE `unseen` = 1 AND `uid` = %d",
//intval($user_info['uid'])
intval(api_user())
);
$idlist = implode(",", $idarray);
$r = q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` AND `id` IN (%s)", $idlist);
$data = array('$statuses' => $ret);

View file

@ -5,7 +5,7 @@ require_once("include/event.php");
require_once("library/markdown.php");
require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
require_once("include/markdownify/markdownify.php");
require_once("library/html-to-markdown/HTML_To_Markdown.php");
// we don't want to support a bbcode specific markdown interpreter
@ -17,19 +17,21 @@ function diaspora2bb($s) {
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
// Simply remove cr.
// Remove CR to avoid problems with following code
$s = str_replace("\r","",$s);
// <br/> is invalid. Replace it with the valid expression
$s = str_replace(array("<br/>", "</p>", "<p>", '<p dir="ltr">'),array("<br />", "<br />", "<br />", "<br />"),$s);
$s = str_replace("\n"," \n",$s);
$s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s);
// The parser cannot handle paragraphs correctly
$s = str_replace(array("</p>", "<p>", '<p dir="ltr">'),array("<br>", "<br>", "<br>"),$s);
// Escaping the hash tags
$s = preg_replace('/\#([^\s\#])/','&#35;$1',$s);
$s = Markdown($s);
$s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s);
$s = str_replace('&#35;','#',$s);
$s = html2bbcode($s);
@ -56,6 +58,8 @@ function diaspora2bb($s) {
function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$a = get_app();
$OriginalText = $Text;
// Since Diaspora is creating a summary for links, this function removes them before posting
@ -88,41 +92,22 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$Text = $Text."<br />".$tagline;
}
} else {
} else
$Text = bbcode($Text, $preserve_nl, false, 4);
// Libertree doesn't convert a harizontal rule if there isn't a linefeed
$Text = str_replace(array("<hr />", "<hr>"), array("<br /><hr />", "<br><hr>"), $Text);
}
// If a link is followed by a quote then there should be a newline before it
// Maybe we should make this newline at every time before a quote.
$Text = str_replace(array("</a><blockquote>"), array("</a><br><blockquote>"), $Text);
$stamp1 = microtime(true);
// Now convert HTML to Markdown
$md = new Markdownify(false, false, false);
$Text = $md->parseString($Text);
$Text = new HTML_To_Markdown($Text);
// The Markdownify converter converts underscores '_' in URLs to '\_', which
// messes up the URL. Manually fix these
$count = 1;
$pos = bb_find_open_close($Text, '[', ']', $count);
while($pos !== false) {
$start = substr($Text, 0, $pos['start']);
$subject = substr($Text, $pos['start'], $pos['end'] - $pos['start'] + 1);
$end = substr($Text, $pos['end'] + 1);
$a->save_timestamp($stamp1, "parser");
$subject = str_replace('\_', '_', $subject);
$Text = $start . $subject . $end;
$count++;
$pos = bb_find_open_close($Text, '[', ']', $count);
}
// If the text going into bbcode() has a plain URL in it, i.e.
// with no [url] tags around it, it will come out of parseString()
// looking like: <http://url.com>, which gets removed by strip_tags().
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
// Remove all unconverted tags
$Text = strip_tags($Text);
// Libertree has a problem with escaped hashtags.
$Text = str_replace(array('\#'), array('#'), $Text);
// Remove any leading or trailing whitespace, as this will mess up
// the Diaspora signature verification and cause the item to disappear

View file

@ -42,7 +42,7 @@ function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
$title = $matches[1];
//$title = htmlentities($title, ENT_QUOTES, 'UTF-8', false);
$title = bbcode(html_entity_decode($title), false, false, true);
$title = bbcode(html_entity_decode($title, ENT_QUOTES, 'UTF-8'), false, false, true);
$title = str_replace(array("[", "]"), array("&#91;", "&#93;"), $title);
$image = "";
@ -168,6 +168,8 @@ function bb_remove_share_information($Text, $plaintext = false, $nolink = false)
}
function bb_cleanup_share($shared, $plaintext, $nolink) {
$shared[1] = trim($shared[1]);
if (!in_array($shared[2], array("type-link", "type-video")))
return($shared[0]);
@ -178,7 +180,7 @@ function bb_cleanup_share($shared, $plaintext, $nolink) {
return($shared[0]);
if ($nolink)
return(trim($shared[1]));
return($shared[1]);
$title = "";
$link = "";
@ -189,6 +191,9 @@ function bb_cleanup_share($shared, $plaintext, $nolink) {
if (isset($bookmark[1][0]))
$link = $bookmark[1][0];
if (($shared[1] != "") AND (strpos($title, $shared[1]) !== false))
$shared[1] = $title;
if (($title != "") AND ((strpos($shared[1],$title) !== false) OR
(similar_text($shared[1],$title) / strlen($title)) > 0.9))
$title = "";
@ -504,9 +509,7 @@ function bb_ShareAttributes($share, $simplehtml) {
$text = $preshare.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' '.$userid_compact.": <br />".$share[3];
break;
case 3: // Diaspora
$headline = '<div class="shared_header">';
$headline .= '<span><b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').$userid.':</b></span>';
$headline .= "</div>";
$headline .= '<b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').$userid.':</b><br />';
$text = trim($share[1]);
@ -514,7 +517,7 @@ function bb_ShareAttributes($share, $simplehtml) {
$text .= "<hr />";
if (substr(normalise_link($link), 0, 19) != "http://twitter.com/") {
$text .= $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote><br />";
$text .= $headline.'<blockquote>'.trim($share[3])."</blockquote><br />";
if ($link != "")
$text .= '<br /><a href="'.$link.'">[l]</a>';
@ -664,12 +667,20 @@ function GetProfileUsername($profile, $username, $compact = false, $getnetwork =
return($username);
}
function bb_DiasporaLinks($match) {
$a = get_app();
return "[url=".$a->get_baseurl()."/display/".$match[1]."]".$match[2]."[/url]";
}
function bb_RemovePictureLinks($match) {
$text = Cache::get($match[1]);
if(is_null($text)){
$a = get_app();
$stamp1 = microtime(true);
$ch = @curl_init($match[1]);
@curl_setopt($ch, CURLOPT_NOBODY, true);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@ -677,6 +688,8 @@ function bb_RemovePictureLinks($match) {
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$a->save_timestamp($stamp1, "network");
if (substr($curl_info["content_type"], 0, 6) == "image/")
$text = "[url=".$match[1]."]".$match[1]."[/url]";
else {
@ -720,6 +733,8 @@ function bb_CleanPictureLinksSub($match) {
if(is_null($text)){
$a = get_app();
$stamp1 = microtime(true);
$ch = @curl_init($match[1]);
@curl_setopt($ch, CURLOPT_NOBODY, true);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@ -727,6 +742,8 @@ function bb_CleanPictureLinksSub($match) {
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$a->save_timestamp($stamp1, "network");
// if its a link to a picture then embed this picture
if (substr($curl_info["content_type"], 0, 6) == "image/")
$text = "[img]".$match[1]."[/img]";
@ -768,8 +785,6 @@ function bb_CleanPictureLinks($text) {
function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = false, $forplaintext = false) {
$stamp1 = microtime(true);
$a = get_app();
// Hide all [noparse] contained bbtags by spacefying them
@ -831,8 +846,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// removing multiplicated newlines
if (get_config("system", "remove_multiplicated_lines")) {
$search = array("\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ", "[/attachment]\n");
$replace = array("\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ", "[/attachment]");
$search = array("\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ", "[/attachment]\n",
"\n[h1]", "[/h1]\n", "\n[h2]", "[/h2]\n", "\n[h3]", "[/h3]\n", "\n[h4]", "[/h4]\n", "\n[h5]", "[/h5]\n", "\n[h6]", "[/h6]\n");
$replace = array("\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ", "[/attachment]",
"[h1]", "[/h1]", "[h2]", "[/h2]", "[h3]", "[/h3]", "[h4]", "[/h4]", "[h5]", "[/h5]", "[h6]", "[/h6]");
do {
$oldtext = $Text;
$Text = str_replace($search, $replace, $Text);
@ -880,6 +897,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
else
$Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url=$1]$2[/url]',$Text);
// Handle Diaspora posts
$Text = preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi", 'bb_DiasporaLinks', $Text);
// if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
if (!$forplaintext)
$Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text);
@ -909,6 +929,14 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
$Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
// Check for headers
$Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text);
$Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text);
$Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text);
$Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text);
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
// Check for bold text
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
@ -1089,8 +1117,8 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
'<a href="https://www.youtube.com/watch?v=$1" target="_blank">https://www.youtube.com/watch?v=$1</a>', $Text);
if ($tryoembed) {
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
}
$Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text);
@ -1104,7 +1132,6 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
// oembed tag
$Text = oembed_bbcode2html($Text);
@ -1174,16 +1201,8 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
//$Text = str_replace('<br /><li>','<li>', $Text);
// $Text = str_replace('<br /><ul','<ul ', $Text);
// Remove all hashtag addresses
/* if (!$tryoembed AND get_config("system", "remove_hashtags_on_export")) {
$pattern = '/#<a.*?href="(.*?)".*?>(.*?)<\/a>/is';
$Text = preg_replace($pattern, '#$2', $Text);
}
*/
call_hooks('bbcode',$Text);
$a->save_timestamp($stamp1, "parser");
return trim($Text);
}
?>

View file

@ -106,29 +106,17 @@ function table_structure($table) {
}
function print_structure($database) {
echo "-- ------------------------------------------\n";
echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
echo "-- DB_UPDATE_VERSION ".DB_UPDATE_VERSION."\n";
echo "-- ------------------------------------------\n\n\n";
foreach ($database AS $name => $structure) {
echo "\t".'$database["'.$name."\"] = array(\n";
echo "--\n";
echo "-- TABLE $name\n";
echo "--\n";
db_create_table($name, $structure['fields'], true, false, $structure["indexes"]);
echo "\t\t\t".'"fields" => array('."\n";
foreach ($structure["fields"] AS $fieldname => $parameters) {
echo "\t\t\t\t\t".'"'.$fieldname.'" => array(';
$data = "";
foreach ($parameters AS $name => $value) {
if ($data != "")
$data .= ", ";
$data .= '"'.$name.'" => "'.$value.'"';
}
echo $data."),\n";
}
echo "\t\t\t\t\t),\n";
echo "\t\t\t".'"indexes" => array('."\n";
foreach ($structure["indexes"] AS $indexname => $fieldnames) {
echo "\t\t\t\t\t".'"'.$indexname.'" => array("'.implode($fieldnames, '","').'"'."),\n";
}
echo "\t\t\t\t\t)\n";
echo "\t\t\t);\n";
echo "\n";
}
}
@ -231,9 +219,13 @@ function db_field_command($parameters, $create = true) {
if ($parameters["not null"])
$fieldstruct .= " NOT NULL";
if (isset($parameters["default"]))
$fieldstruct .= " DEFAULT '".$parameters["default"]."'";
if (isset($parameters["default"])){
if (strpos(strtolower($parameters["type"]),"int")!==false) {
$fieldstruct .= " DEFAULT ".$parameters["default"];
} else {
$fieldstruct .= " DEFAULT '".$parameters["default"]."'";
}
}
if ($parameters["extra"] != "")
$fieldstruct .= " ".$parameters["extra"];
@ -243,20 +235,28 @@ function db_field_command($parameters, $create = true) {
return($fieldstruct);
}
function db_create_table($name, $fields, $verbose, $action) {
function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
global $a, $db;
$r = true;
$sql = "";
$sql_rows = array();
foreach($fields AS $fieldname => $field) {
if ($sql != "")
$sql .= ",\n";
$sql .= "`".dbesc($fieldname)."` ".db_field_command($field);
$sql_rows[] = "`".dbesc($fieldname)."` ".db_field_command($field);
}
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
if (!is_null($indexes)) {
foreach ($indexes AS $indexname => $fieldnames) {
$sql_index = db_create_index($indexname, $fieldnames, "");
if (!is_null($sql_index)) $sql_rows[] = $sql_index;
}
}
$sql = implode(",\n\t", $sql_rows);
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
if ($verbose)
echo $sql.";\n";
@ -282,7 +282,7 @@ function db_drop_index($indexname) {
return($sql);
}
function db_create_index($indexname, $fieldnames) {
function db_create_index($indexname, $fieldnames, $method="ADD") {
if ($indexname == "PRIMARY")
return;
@ -298,7 +298,13 @@ function db_create_index($indexname, $fieldnames) {
$names .= "`".dbesc($fieldname)."`";
}
$sql = sprintf("ADD INDEX `%s` (%s)", dbesc($indexname), $names);
$method = strtoupper(trim($method));
if ($method!="" && $method!="ADD") {
throw new Exception("Invalid parameter 'method' in db_create_index(): '$method'");
killme();
}
$sql = sprintf("%s INDEX `%s` (%s)", $method, dbesc($indexname), $names);
return($sql);
}
@ -626,6 +632,7 @@ function db_definition() {
"keywords" => array("type" => "text", "not null" => "1"),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -775,6 +782,9 @@ function db_definition() {
"last-child" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "1"),
"mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"rendered-hash" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"rendered-html" => array("type" => "mediumtext", "not null" => "1"),
"global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -1187,6 +1197,10 @@ function db_definition() {
"type" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"),
"term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"aid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
"uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
),
@ -1195,8 +1209,9 @@ function db_definition() {
"oid_otype_type_term" => array("oid","otype","type","term"),
"uid_term_tid" => array("uid","term","tid"),
"type_term" => array("type","term"),
"uid_otype_type_term_tid" => array("uid","otype","type","term","tid"),
"uid_otype_type_term_global_created" => array("uid","otype","type","term","global","created"),
"otype_type_term_tid" => array("otype","type","term","tid"),
"guid" => array("guid"),
)
);
$database["thread"] = array(
@ -1348,7 +1363,29 @@ function dbstructure_run(&$argv, &$argc) {
unset($db_host, $db_user, $db_pass, $db_data);
}
update_structure(true, true);
if ($argc==2) {
switch ($argv[1]) {
case "update":
update_structure(true, true);
return;
case "dumpsql":
print_structure(db_definition());
return;
}
}
// print help
echo $argv[0]." <command>\n";
echo "\n";
echo "commands:\n";
echo "update update database schema\n";
echo "dumpsql dump database schema\n";
return;
}
if (array_search(__file__,get_included_files())===0){

View file

@ -6,6 +6,7 @@ require_once('include/bb2diaspora.php');
require_once('include/contact_selectors.php');
require_once('include/queue_fn.php');
require_once('include/lock.php');
require_once('include/threads.php');
function diaspora_dispatch_public($msg) {
@ -589,7 +590,7 @@ function diaspora_request($importer,$xml) {
intval($importer['uid'])
);
if((count($r)) && (! $r[0]['hide-friends']) && (! $contact['hidden'])) {
if((count($r)) && (!$r[0]['hide-friends']) && (!$contact['hidden']) && intval(get_pconfig($importer['uid'],'system','post_newfriend'))) {
require_once('include/items.php');
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
@ -833,31 +834,6 @@ function diaspora_post($importer,$xml,$msg) {
$str_tags = '';
$tags = get_tags($body);
if(count($tags)) {
foreach($tags as $tag) {
if(strpos($tag,'#') === 0) {
if(strpos($tag,'[url='))
continue;
// don't link tags that are already embedded in links
if(preg_match('/\[(.*?)' . preg_quote($tag,'/') . '(.*?)\]/',$body))
continue;
if(preg_match('/\[(.*?)\]\((.*?)' . preg_quote($tag,'/') . '(.*?)\)/',$body))
continue;
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
}
$cnt = preg_match_all('/@\[url=(.*?)\[\/url\]/ism',$body,$matches,PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
@ -895,19 +871,92 @@ function diaspora_post($importer,$xml,$msg) {
$datarray['visible'] = ((strlen($body)) ? 1 : 0);
DiasporaFetchGuid($datarray);
$message_id = item_store($datarray);
//if($message_id) {
// q("update item set plink = '%s' where id = %d",
// dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id),
// intval($message_id)
// );
//}
return;
}
function DiasporaFetchGuid($item) {
preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
function ($match) use ($item){
return(DiasporaFetchGuidSub($match, $item));
},$item["body"]);
}
function DiasporaFetchGuidSub($match, $item) {
$a = get_app();
$author = parse_url($item["author-link"]);
$authorserver = $author["scheme"]."://".$author["host"];
$owner = parse_url($item["owner-link"]);
$ownerserver = $owner["scheme"]."://".$owner["host"];
if (!diaspora_store_by_guid($match[1], $authorserver))
diaspora_store_by_guid($match[1], $ownerserver);
}
function diaspora_store_by_guid($guid, $server) {
require_once("include/Contact.php");
logger("fetching item ".$guid." from ".$server, LOGGER_DEBUG);
$item = diaspora_fetch_message($guid, $server);
if (!$item)
return false;
$body = $item["body"];
$str_tags = $item["tag"];
$app = $item["app"];
$created = $item["created"];
$author = $item["author"];
$guid = $item["guid"];
$private = $item["private"];
$message_id = $author.':'.$guid;
$r = q("SELECT `id` FROM `item` WHERE `uid` = 0 AND `uri` = '%s' AND `guid` = '%s' LIMIT 1",
dbesc($message_id),
dbesc($guid)
);
if(count($r))
return $r[0]["id"];
$person = find_diaspora_person_by_handle($author);
$datarray = array();
$datarray['uid'] = 0;
$datarray['contact-id'] = get_contact($person['url'], 0);
$datarray['wall'] = 0;
$datarray['network'] = NETWORK_DIASPORA;
$datarray['guid'] = $guid;
$datarray['uri'] = $datarray['parent-uri'] = $message_id;
$datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC','UTC',$created);
$datarray['private'] = $private;
$datarray['parent'] = 0;
$datarray['plink'] = 'https://'.substr($author,strpos($author,'@')+1).'/posts/'.$guid;
$datarray['author-name'] = $person['name'];
$datarray['author-link'] = $person['url'];
$datarray['author-avatar'] = ((x($person,'thumb')) ? $person['thumb'] : $person['photo']);
$datarray['owner-name'] = $datarray['author-name'];
$datarray['owner-link'] = $datarray['author-link'];
$datarray['owner-avatar'] = $datarray['author-avatar'];
$datarray['body'] = $body;
$datarray['tag'] = $str_tags;
$datarray['app'] = $app;
$datarray['visible'] = ((strlen($body)) ? 1 : 0);
DiasporaFetchGuid($datarray);
$message_id = item_store($datarray);
// To-Do:
// Looking if there is some subscribe mechanism in Diaspora to get all comments for this post
return $message_id;
}
function diaspora_fetch_message($guid, $server, $level = 0) {
if ($level > 5)
@ -981,34 +1030,8 @@ function diaspora_fetch_message($guid, $server, $level = 0) {
return false;
$item["tag"] = '';
$tags = get_tags($body);
if(count($tags)) {
foreach($tags as $tag) {
if(strpos($tag,'#') === 0) {
if(strpos($tag,'[url='))
continue;
// don't link tags that are already embedded in links
if(preg_match('/\[(.*?)' . preg_quote($tag,'/') . '(.*?)\]/',$body))
continue;
if(preg_match('/\[(.*?)\]\((.*?)' . preg_quote($tag,'/') . '(.*?)\)/',$body))
continue;
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($item["tag"]))
$item["tag"] .= ',';
$item["tag"] .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
}
$item["body"] = $body;
return $item;
}
@ -1102,7 +1125,8 @@ function diaspora_reshare($importer,$xml,$msg) {
$orig_created = $item["created"];
$orig_author = $item["author"];
$orig_guid = $item["guid"];
//$create_original_post = ($body != "");
$create_original_post = ($body != "");
$orig_url = $a->get_baseurl()."/display/".$orig_guid;
}
}
@ -1144,6 +1168,8 @@ function diaspora_reshare($importer,$xml,$msg) {
$prefix = "[share author='".str_replace(array("'", "[", "]"), array("&#x27;", "&#x5B;", "&#x5D;"),$person['name']).
"' profile='".$person['url'].
"' avatar='".((x($person,'thumb')) ? $person['thumb'] : $person['photo']).
"' guid='".$orig_guid.
"' posted='".$orig_created.
"' link='".str_replace(array("'", "[", "]"), array("&#x27;", "&#x5B;", "&#x5D;"),$orig_url)."']";
$datarray['author-name'] = $contact['name'];
$datarray['author-link'] = $contact['url'];
@ -1164,12 +1190,13 @@ function diaspora_reshare($importer,$xml,$msg) {
$datarray['visible'] = ((strlen($body)) ? 1 : 0);
// Store the original item of a reshare
// Deactivated by now. Items without a matching contact can't be shown via "mod/display.php" by now.
if ($create_original_post) {
require_once("include/Contact.php");
$datarray2 = $datarray;
$datarray2['uid'] = 0;
$datarray2['contact-id'] = 0;
$datarray2['contact-id'] = get_contact($person['url'], 0);
$datarray2['guid'] = $orig_guid;
$datarray2['uri'] = $datarray2['parent-uri'] = $orig_author.':'.$orig_guid;
$datarray2['changed'] = $datarray2['created'] = $datarray2['edited'] = datetime_convert('UTC','UTC',$orig_created);
@ -1183,11 +1210,13 @@ function diaspora_reshare($importer,$xml,$msg) {
$datarray2['owner-avatar'] = $datarray2['author-avatar'];
$datarray2['body'] = $body;
DiasporaFetchGuid($datarray2);
$message_id = item_store($datarray2);
logger("Store original item ".$orig_guid." under message id ".$message_id);
}
DiasporaFetchGuid($datarray);
$message_id = item_store($datarray);
return;
@ -1280,6 +1309,7 @@ function diaspora_asphoto($importer,$xml,$msg) {
$datarray['app'] = 'Diaspora/Cubbi.es';
DiasporaFetchGuid($datarray);
$message_id = item_store($datarray);
//if($message_id) {
@ -1403,34 +1433,6 @@ function diaspora_comment($importer,$xml,$msg) {
$datarray = array();
$str_tags = '';
$tags = get_tags($body);
if(count($tags)) {
foreach($tags as $tag) {
if(strpos($tag,'#') === 0) {
if(strpos($tag,'[url='))
continue;
// don't link tags that are already embedded in links
if(preg_match('/\[(.*?)' . preg_quote($tag,'/') . '(.*?)\]/',$body))
continue;
if(preg_match('/\[(.*?)\]\((.*?)' . preg_quote($tag,'/') . '(.*?)\)/',$body))
continue;
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
}
$datarray['uid'] = $importer['uid'];
$datarray['contact-id'] = $contact['id'];
$datarray['type'] = 'remote-comment';
@ -1454,12 +1456,12 @@ function diaspora_comment($importer,$xml,$msg) {
$datarray['author-link'] = $person['url'];
$datarray['author-avatar'] = ((x($person,'thumb')) ? $person['thumb'] : $person['photo']);
$datarray['body'] = $body;
$datarray['tag'] = $str_tags;
// We can't be certain what the original app is if the message is relayed.
if(($parent_item['origin']) && (! $parent_author_signature))
$datarray['app'] = 'Diaspora';
DiasporaFetchGuid($datarray);
$message_id = item_store($datarray);
//if($message_id) {
@ -1854,11 +1856,12 @@ function diaspora_photo($importer,$xml,$msg,$attempt=1) {
array($remote_photo_name, 'scaled_full_' . $remote_photo_name));
if(strpos($parent_item['body'],$link_text) === false) {
$r = q("update item set `body` = '%s', `visible` = 1 where `id` = %d and `uid` = %d",
$r = q("UPDATE `item` SET `body` = '%s', `visible` = 1 WHERE `id` = %d AND `uid` = %d",
dbesc($link_text . $parent_item['body']),
intval($parent_item['id']),
intval($parent_item['uid'])
);
update_thread($parent_item['id']);
}
return;
@ -1933,7 +1936,7 @@ function diaspora_like($importer,$xml,$msg) {
if($positive === 'false') {
logger('diaspora_like: received a like with positive set to "false"');
logger('diaspora_like: unlike received with no corresponding like...ignoring');
return;
return;
}
@ -1949,26 +1952,28 @@ function diaspora_like($importer,$xml,$msg) {
who sent the salmon
*/
$signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
// Diaspora has changed the way they are signing the likes.
// Just to make sure that we don't miss any likes we will check the old and the current way.
$old_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
$signed_data = $positive . ';' . $guid . ';' . $target_type . ';' . $parent_guid . ';' . $diaspora_handle;
$key = $msg['key'];
if($parent_author_signature) {
if ($parent_author_signature) {
// If a parent_author_signature exists, then we've received the like
// relayed from the top-level post owner. There's no need to check the
// author_signature if the parent_author_signature is valid
$parent_author_signature = base64_decode($parent_author_signature);
if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
if (intval(get_config('system','ignore_diaspora_like_signature')))
logger('diaspora_like: top-level owner verification failed. Proceeding anyway.');
else {
logger('diaspora_like: top-level owner verification failed.');
return;
}
if (!rsa_verify($signed_data,$parent_author_signature,$key,'sha256') AND
!rsa_verify($old_signed_data,$parent_author_signature,$key,'sha256')) {
logger('diaspora_like: top-level owner verification failed.');
return;
}
}
else {
} else {
// If there's no parent_author_signature, then we've received the like
// from the like creator. In that case, the person is "like"ing
// our post, so he/she must be a contact of ours and his/her public key
@ -1976,13 +1981,11 @@ function diaspora_like($importer,$xml,$msg) {
$author_signature = base64_decode($author_signature);
if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
if (intval(get_config('system','ignore_diaspora_like_signature')))
logger('diaspora_like: like creator verification failed. Proceeding anyway');
else {
logger('diaspora_like: like creator verification failed.');
return;
}
if (!rsa_verify($signed_data,$author_signature,$key,'sha256') AND
!rsa_verify($old_signed_data,$author_signature,$key,'sha256')) {
logger('diaspora_like: like creator verification failed.');
return;
}
}
@ -2319,7 +2322,7 @@ function diaspora_profile($importer,$xml,$msg) {
if (unxmlify($xml->searchable) == "true") {
require_once('include/socgraph.php');
poco_check($contact['url'], $name, NETWORK_DIASPORA, $images[0], $about, $location, $gender, $keywords, "",
datetime_convert(), $contact['id'], $importer['uid']);
datetime_convert(), 2, $contact['id'], $importer['uid']);
}
$profileurl = "";
@ -2509,6 +2512,26 @@ function diaspora_is_reshare($body) {
if ($body == $attributes)
return(false);
$guid = "";
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$guid = $matches[1];
preg_match('/guid="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$guid = $matches[1];
if ($guid != "") {
$r = q("SELECT `contact-id` FROM `item` WHERE `guid` = '%s' AND `network` IN ('%s', '%s') LIMIT 1",
dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA);
if ($r) {
$ret= array();
$ret["root_handle"] = diaspora_handle_from_contact($r[0]["contact-id"]);
$ret["root_guid"] = $guid;
return($ret);
}
}
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")

View file

@ -23,12 +23,15 @@ function notification($params) {
$site_admin = sprintf( t('%s Administrator'), $sitename);
$nickname = "";
$sender_name = $product;
$sender_name = $sitename;
$hostname = $a->get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
$sender_email = t('noreply') . '@' . $hostname;
$sender_email = $a->config['sender_email'];
if (empty($sender_email)) {
$sender_email = t('noreply') . '@' . $hostname;
}
$user = q("SELECT `nickname` FROM `user` WHERE `uid` = %d", intval($params['uid']));
if ($user)

View file

@ -41,7 +41,23 @@ function gprobe_run(&$argv, &$argc){
if(! count($r)) {
// Is it a DDoS attempt?
$urlparts = parse_url($url);
$result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) {
$result = unserialize($result);
if ($result["network"] == NETWORK_FEED) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return;
}
}
$arr = probe_url($url);
if (is_null($result))
Cache::set("gprobe:".$urlparts["host"],serialize($arr));
if(count($arr) && x($arr,'network') && $arr['network'] === NETWORK_DFRN) {
q("insert into `gcontact` (`name`,`url`,`nurl`,`photo`)
values ( '%s', '%s', '%s', '%s') ",

View file

@ -88,9 +88,6 @@ function deletenode(&$doc, $node)
function html2bbcode($message)
{
//$file = tempnam("/tmp/", "html");
//file_put_contents($file, $message);
$message = str_replace("\r", "", $message);
$message = str_replace(array(
@ -207,12 +204,19 @@ function html2bbcode($message)
//node2bbcode($doc, 'tr', array(), "[tr]", "[/tr]");
//node2bbcode($doc, 'td', array(), "[td]", "[/td]");
node2bbcode($doc, 'h1', array(), "\n\n[size=xx-large][b]", "[/b][/size]\n");
node2bbcode($doc, 'h2', array(), "\n\n[size=x-large][b]", "[/b][/size]\n");
node2bbcode($doc, 'h3', array(), "\n\n[size=large][b]", "[/b][/size]\n");
node2bbcode($doc, 'h4', array(), "\n\n[size=medium][b]", "[/b][/size]\n");
node2bbcode($doc, 'h5', array(), "\n\n[size=small][b]", "[/b][/size]\n");
node2bbcode($doc, 'h6', array(), "\n\n[size=x-small][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h1', array(), "\n\n[size=xx-large][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h2', array(), "\n\n[size=x-large][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h3', array(), "\n\n[size=large][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h4', array(), "\n\n[size=medium][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h5', array(), "\n\n[size=small][b]", "[/b][/size]\n");
//node2bbcode($doc, 'h6', array(), "\n\n[size=x-small][b]", "[/b][/size]\n");
node2bbcode($doc, 'h1', array(), "\n\n[h1]", "[/h1]\n");
node2bbcode($doc, 'h2', array(), "\n\n[h2]", "[/h2]\n");
node2bbcode($doc, 'h3', array(), "\n\n[h3]", "[/h3]\n");
node2bbcode($doc, 'h4', array(), "\n\n[h4]", "[/h4]\n");
node2bbcode($doc, 'h5', array(), "\n\n[h5]", "[/h5]\n");
node2bbcode($doc, 'h6', array(), "\n\n[h6]", "[/h6]\n");
node2bbcode($doc, 'a', array('href'=>'/mailto:(.+)/'), '[mail=$1]', '[/mail]');
node2bbcode($doc, 'a', array('href'=>'/(.+)/'), '[url=$1]', '[/url]');

View file

@ -113,12 +113,6 @@ function html2plain($html, $wraplength = 75, $compact = false)
$message = str_replace("\r", "", $html);
// replace all hashtag addresses
/* if (get_config("system", "remove_hashtags_on_export")) {
$pattern = '/#<a.*?href="(.*?)".*?>(.*?)<\/a>/is';
$message = preg_replace($pattern, '#$2', $message);
}
*/
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;

View file

@ -1210,8 +1210,8 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : '');
$arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : '');
$arr['origin'] = ((x($arr,'origin')) ? intval($arr['origin']) : 0 );
$arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(30));
$arr['network'] = ((x($arr,'network')) ? trim($arr['network']) : '');
$arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $arr['network']));
$arr['postopts'] = ((x($arr,'postopts')) ? trim($arr['postopts']) : '');
$arr['resource-id'] = ((x($arr,'resource-id')) ? trim($arr['resource-id']) : '');
$arr['event-id'] = ((x($arr,'event-id')) ? intval($arr['event-id']) : 0 );
@ -1239,6 +1239,9 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
logger("item_store: Set network to ".$arr["network"]." for ".$arr["uri"], LOGGER_DEBUG);
}
// Check for hashtags in the body and repair or add hashtag links
item_body_set_hashtags($arr);
$arr['thr-parent'] = $arr['parent-uri'];
if($arr['parent-uri'] === $arr['uri']) {
$parent_id = 0;
@ -1343,6 +1346,20 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
return 0;
}
// Is this item available in the global items (with uid=0)?
if ($arr["uid"] == 0) {
$arr["global"] = true;
q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($arr["guid"]));
} else {
$isglobal = q("SELECT `global` FROM `item` WHERE `uid` = 0 AND `guid` = '%s'", dbesc($arr["guid"]));
$arr["global"] = (count($isglobal) > 0);
}
// Fill the cache field
put_item_in_cache($arr);
call_hooks('post_remote',$arr);
if(x($arr,'cancel')) {
@ -1376,16 +1393,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$current_post = $r[0]['id'];
logger('item_store: created item ' . $current_post);
// Add every contact to the global contact table
// Contacts from the statusnet connector are also added since you could add them in OStatus as well.
if (!$arr['private'] AND in_array($arr["network"],
array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_STATUSNET, ""))) {
poco_check($arr["author-link"], $arr["author-name"], $arr["network"], $arr["author-avatar"], "", "", "", "", "", $arr["received"], $arr["contact-id"], $arr["uid"]);
// Maybe its a body with a shared item? Then extract a global contact from it.
poco_contact_from_body($arr["body"], $arr["received"], $arr["contact-id"], $arr["uid"]);
}
// Set "success_update" to the date of the last time we heard from this contact
// This can be used to filter for inactive contacts and poco.
// Only do this for public postings to avoid privacy problems, since poco data is public.
@ -1395,56 +1402,12 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
dbesc($arr['received']),
intval($arr['contact-id'])
);
// Only check for notifications on start posts
if ($arr['parent-uri'] === $arr['uri']) {
add_thread($r[0]['id']);
logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
// Send a notification for every new post?
$r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
intval($arr['contact-id']),
intval($arr['uid'])
);
if(count($r)) {
logger('item_store: Send notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
$u = q("SELECT * FROM user WHERE uid = %d LIMIT 1",
intval($arr['uid']));
$item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d",
intval($current_post),
intval($arr['uid'])
);
$a = get_app();
require_once('include/enotify.php');
notification(array(
'type' => NOTIFY_SHARE,
'notify_flags' => $u[0]['notify-flags'],
'language' => $u[0]['language'],
'to_name' => $u[0]['username'],
'to_email' => $u[0]['email'],
'uid' => $u[0]['uid'],
'item' => $item[0],
'link' => $a->get_baseurl().'/display/'.urlencode($arr['guid']),
'source_name' => $item[0]['author-name'],
'source_link' => $item[0]['author-link'],
'source_photo' => $item[0]['author-avatar'],
'verb' => ACTIVITY_TAG,
'otype' => 'item'
));
logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
}
}
} else {
logger('item_store: could not locate created item');
return 0;
}
if(count($r) > 1) {
logger('item_store: duplicated post occurred. Removing duplicates.');
logger('item_store: duplicated post occurred. Removing duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `id` != %d ",
dbesc($arr['uri']),
intval($arr['uid']),
@ -1488,13 +1451,18 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$arr['deleted'] = $parent_deleted;
// update the commented timestamp on the parent
q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($parent_id)
);
update_thread($parent_id);
// Only update "commented" if it is really a comment
if (($arr['verb'] == ACTIVITY_POST) OR !get_config("system", "like_no_comment"))
q("UPDATE `item` SET `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($parent_id)
);
else
q("UPDATE `item` SET `changed` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),
intval($parent_id)
);
if($dsprsig) {
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
@ -1520,39 +1488,157 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$deleted = tag_deliver($arr['uid'],$current_post);
// current post can be deleted if is for a communuty page and no mention are
// current post can be deleted if is for a community page and no mention are
// in it.
if (!$deleted AND !$dontcache) {
// Store the fresh generated item into the cache
$cachefile = get_cachefile(urlencode($arr["guid"])."-".hash("md5", $arr['body']));
if (($cachefile != '') AND !file_exists($cachefile)) {
$s = prepare_text($arr['body']);
$a = get_app();
$stamp1 = microtime(true);
file_put_contents($cachefile, $s);
$a->save_timestamp($stamp1, "file");
logger('item_store: put item '.$current_post.' into cachefile '.$cachefile);
}
$r = q('SELECT * FROM `item` WHERE id = %d', intval($current_post));
if (count($r) == 1) {
call_hooks('post_remote_end', $r[0]);
} else {
} else
logger('item_store: new item not found in DB, id ' . $current_post);
}
}
create_tags_from_item($current_post, $dontcache);
// Add every contact of the post to the global contact table
poco_store($arr);
create_tags_from_item($current_post);
create_files_from_item($current_post);
// Only check for notifications on start posts
if ($arr['parent-uri'] === $arr['uri']) {
add_thread($current_post);
logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
// Send a notification for every new post?
$r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
intval($arr['contact-id']),
intval($arr['uid'])
);
$send_notification = count($r);
if (!$send_notification) {
$tags = q("SELECT `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` = %d AND `uid` = %d",
intval(TERM_OBJ_POST), intval($current_post), intval(TERM_MENTION), intval($arr['uid']));
if (count($tags)) {
foreach ($tags AS $tag) {
$r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `notify_new_posts`",
normalise_link($tag["url"]), intval($arr['uid']));
if (count($r))
$send_notification = true;
}
}
}
if ($send_notification) {
logger('item_store: Send notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
$u = q("SELECT * FROM user WHERE uid = %d LIMIT 1",
intval($arr['uid']));
$item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d",
intval($current_post),
intval($arr['uid'])
);
$a = get_app();
require_once('include/enotify.php');
notification(array(
'type' => NOTIFY_SHARE,
'notify_flags' => $u[0]['notify-flags'],
'language' => $u[0]['language'],
'to_name' => $u[0]['username'],
'to_email' => $u[0]['email'],
'uid' => $u[0]['uid'],
'item' => $item[0],
'link' => $a->get_baseurl().'/display/'.urlencode($arr['guid']),
'source_name' => $item[0]['author-name'],
'source_link' => $item[0]['author-link'],
'source_photo' => $item[0]['author-avatar'],
'verb' => ACTIVITY_TAG,
'otype' => 'item'
));
logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
}
} else {
update_thread($parent_id);
add_shadow_entry($arr);
}
if ($notify)
proc_run('php', "include/notifier.php", $notify_type, $current_post);
return $current_post;
}
function item_body_set_hashtags(&$item) {
$tags = get_tags($item["body"]);
// No hashtags?
if(!count($tags))
return(false);
// This sorting is important when there are hashtags that are part of other hashtags
// Otherwise there could be problems with hashtags like #test and #test2
rsort($tags);
$a = get_app();
$URLSearchString = "^\[\]";
// All hashtags should point to the home server
//$item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
// "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["body"]);
//$item["tag"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
// "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["tag"]);
// mask hashtags inside of url, bookmarks and attachments to avoid urls in urls
$item["body"] = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
function ($match){
return("[url=".$match[1]."]".str_replace("#", "&num;", $match[2])."[/url]");
},$item["body"]);
$item["body"] = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism",
function ($match){
return("[bookmark=".$match[1]."]".str_replace("#", "&num;", $match[2])."[/bookmark]");
},$item["body"]);
$item["body"] = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
function ($match){
return("[attachment ".str_replace("#", "&num;", $match[1])."]".$match[2]."[/attachment]");
},$item["body"]);
// Repair recursive urls
$item["body"] = preg_replace("/&num;\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
"&num;$2", $item["body"]);
foreach($tags as $tag) {
if(strpos($tag,'#') !== 0)
continue;
if(strpos($tag,'[url='))
continue;
$basetag = str_replace('_',' ',substr($tag,1));
$newtag = '#[url='.$a->get_baseurl().'/search?tag='.rawurlencode($basetag).']'.$basetag.'[/url]';
$item["body"] = str_replace($tag, $newtag, $item["body"]);
if(!stristr($item["tag"],"/search?tag=".$basetag."]".$basetag."[/url]")) {
if(strlen($item["tag"]))
$item["tag"] = ','.$item["tag"];
$item["tag"] = $newtag.$item["tag"];
}
}
// Convert back the masked hashtags
$item["body"] = str_replace("&num;", "#", $item["body"]);
}
function get_item_guid($id) {
$r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
if (count($r))
@ -2078,6 +2164,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
$photo_timestamp = '';
$photo_url = '';
$birthday = '';
$contact_updated = '';
$hubs = $feed->get_links('hub');
logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA);
@ -2093,9 +2180,16 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
$name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
$new_name = $elems['name'][0]['data'];
// Manually checking for changed contact names
if (($new_name != $contact['name']) AND ($new_name != "") AND ($name_updated <= $contact['name-date'])) {
$name_updated = date("c");
$photo_timestamp = date("c");
}
}
if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
$photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
if ($photo_timestamp == "")
$photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
$photo_url = $elems['link'][0]['attribs']['']['href'];
}
@ -2106,6 +2200,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
if((is_array($contact)) && ($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) {
logger('consume_feed: Updating photo for '.$contact['name'].' from '.$photo_url.' uid: '.$contact['uid']);
$contact_updated = $photo_timestamp;
require_once("include/Photo.php");
$photo_failure = false;
$have_photo = false;
@ -2163,6 +2260,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
}
if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) {
if ($name_updated > $contact_updated)
$contact_updated = $name_updated;
$r = q("select * from contact where uid = %d and id = %d limit 1",
intval($contact['uid']),
intval($contact['id'])
@ -2187,6 +2287,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
}
}
if ($contact_updated AND $new_name AND $photo_url)
poco_check($contact['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $contact['id'], $contact['uid']);
if(strlen($birthday)) {
if(substr($birthday,0,4) != $contact['bdyear']) {
logger('consume_feed: updating birthday: ' . $birthday);
@ -2233,7 +2336,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
$contact['bdyear'] = substr($birthday,0,4);
}
}
$community_page = 0;
@ -2715,6 +2817,10 @@ function item_is_remote_self($contact, &$datarray) {
if ($datarray["app"] == $a->get_hostname())
return false;
// Only forward posts
if ($datarray["verb"] != ACTIVITY_POST)
return false;
if (($contact['network'] != NETWORK_FEED) AND $datarray['private'])
return false;
@ -2795,6 +2901,7 @@ function local_delivery($importer,$data) {
$new_name = '';
$photo_timestamp = '';
$photo_url = '';
$contact_updated = '';
$rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner');
@ -2808,14 +2915,24 @@ function local_delivery($importer,$data) {
if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
$name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
$new_name = $elems['name'][0]['data'];
// Manually checking for changed contact names
if (($new_name != $importer['name']) AND ($new_name != "") AND ($name_updated <= $importer['name-date'])) {
$name_updated = date("c");
$photo_timestamp = date("c");
}
}
if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
$photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
if ($photo_timestamp == "")
$photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
$photo_url = $elems['link'][0]['attribs']['']['href'];
}
}
if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $importer['avatar-date'])) {
$contact_updated = $photo_timestamp;
logger('local_delivery: Updating photo for ' . $importer['name']);
require_once("include/Photo.php");
$photo_failure = false;
@ -2874,6 +2991,9 @@ function local_delivery($importer,$data) {
}
if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) {
if ($name_updated > $contact_updated)
$contact_updated = $name_updated;
$r = q("select * from contact where uid = %d and id = %d limit 1",
intval($importer['importer_uid']),
intval($importer['id'])
@ -2898,7 +3018,8 @@ function local_delivery($importer,$data) {
}
}
if ($contact_updated AND $new_name AND $photo_url)
poco_check($importer['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $importer['id'], $importer['importer_uid']);
// Currently unsupported - needs a lot of work
$reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
@ -2937,6 +3058,7 @@ function local_delivery($importer,$data) {
thumb = '%s',
micro = '%s',
url = '%s',
nurl = '%s',
request = '%s',
confirm = '%s',
notify = '%s',
@ -2948,6 +3070,7 @@ function local_delivery($importer,$data) {
dbesc($newloc['thumb']),
dbesc($newloc['micro']),
dbesc($newloc['url']),
dbesc(normalise_link($newloc['url'])),
dbesc($newloc['request']),
dbesc($newloc['confirm']),
dbesc($newloc['notify']),
@ -4649,8 +4772,8 @@ function drop_item($id,$interactive = true) {
dbesc($item['parent-uri']),
intval($item['uid'])
);
create_tags_from_item($item['parent-uri'], $item['uid']);
create_files_from_item($item['parent-uri'], $item['uid']);
create_tags_from_itemuri($item['parent-uri'], $item['uid']);
create_files_from_itemuri($item['parent-uri'], $item['uid']);
delete_thread_uri($item['parent-uri'], $item['uid']);
// ignore the result
}

View file

@ -1,504 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View file

@ -1,29 +0,0 @@
Markdownify
===========
* handle non-markdownifiable lists (i.e. `<ul><li id="foobar">asdf</li></ul>`)
* organize methods better (i.e. flushlinebreaks & setlinebreaks close to each other)
* take a look at function names etc.
* is the new (in rev. 93) lastclosedtag property needed?
* word wrapping (some work is done but it's still very buggy)
Markdownify Extra
=================
* handle table alignment with KEEP_HTML=false
* handle tables without headings when KEEP_HTML=false is set
* handle Markdown inside non-markdownable tags
Implementation Thoughts
=======================
* non-markdownifiable lists and markdown inside non-markdownable tags as well as the current
table implementation could be rewritten by using a rollback mechanism.
example:
<ul><li>asdf</li><li id="foobar">asdf</li></ul>
we come to `<ul>`, know that this might fail and create a snapshot of our current parser
we keep on parsing and when we reach `<li id="foobar">` we gotta rollback and keep this
list in HTML format.

View file

@ -1,51 +0,0 @@
<?php
error_reporting(E_ALL);
if (!empty($_POST['input'])) {
include 'markdownify_extra.php';
if (!isset($_POST['leap'])) {
$leap = MDFY_LINKS_EACH_PARAGRAPH;
} else {
$leap = $_POST['leap'];
}
if (!isset($_POST['keepHTML'])) {
$keephtml = MDFY_KEEPHTML;
} else {
$keephtml = $_POST['keepHTML'];
}
if (!empty($_POST['extra'])) {
$md = new Markdownify_Extra($leap, MDFY_BODYWIDTH, $keephtml);
} else {
$md = new Markdownify($leap, MDFY_BODYWIDTH, $keephtml);
}
if (ini_get('magic_quotes_gpc')) {
$_POST['input'] = stripslashes($_POST['input']);
}
$output = $md->parseString($_POST['input']);
} else {
$_POST['input'] = '';
}
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>HTML to Markdown Converter</title>
</head>
<body>
<?php if (empty($_POST['input'])): ?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<fieldset>
<legend>HTML Input</legend>
<textarea style="width:100%;" cols="85" rows="40" name="input"><?php echo htmlspecialchars($_POST['input'], ENT_NOQUOTES, 'UTF-8'); ?></textarea>
</fieldset>
<label for="extra">Markdownify Extra: <input name="extra" checked="checked" id="extra" type="checkbox" value="1" /></label>
<label for="leap">Links after each block elem: <input name="leap" id="leap" type="checkbox" value="1" /></label>
<label for="keepHTML">keep HTML: <input name="keepHTML" id="keepHTML" type="checkbox" value="1" checked="checked" /></label>
<input type="submit" name="submit" value="submit" />
</form>
<?php else: ?>
<h1 style="text-align:right;"><a href="<?php echo $_SERVER['PHP_SELF']; ?>">BACK</a></h1>
<pre><?php echo htmlspecialchars($output, ENT_NOQUOTES, 'UTF-8'); ?></pre>
<?php endif; ?>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,33 +0,0 @@
#!/usr/bin/php
<?php
require dirname(__FILE__) .'/markdownify_extra.php';
function param($name, $default = false) {
if (!in_array('--'.$name, $_SERVER['argv']))
return $default;
reset($_SERVER['argv']);
while (each($_SERVER['argv'])) {
if (current($_SERVER['argv']) == '--'.$name)
break;
}
$value = next($_SERVER['argv']);
if ($value === false || substr($value, 0, 2) == '--')
return true;
else
return $value;
}
$input = stream_get_contents(STDIN);
$linksAfterEachParagraph = param('links');
$bodyWidth = param('width');
$keepHTML = param('html', true);
if (param('no_extra')) {
$parser = new Markdownify($linksAfterEachParagraph, $bodyWidth, $keepHTML);
} else {
$parser = new Markdownify_Extra($linksAfterEachParagraph, $bodyWidth, $keepHTML);
}
echo $parser->parseString($input) ."\n";

View file

@ -1,489 +0,0 @@
<?php
/**
* Class to convert HTML to Markdown with PHP Markdown Extra syntax support.
*
* @version 1.0.0 alpha
* @author Milian Wolff (<mail@milianw.de>, <http://milianw.de>)
* @license LGPL, see LICENSE_LGPL.txt and the summary below
* @copyright (C) 2007 Milian Wolff
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* standard Markdownify class
*/
require_once dirname(__FILE__).'/markdownify.php';
class Markdownify_Extra extends Markdownify {
/**
* table data, including rows with content and the maximum width of each col
*
* @var array
*/
var $table = array();
/**
* current col
*
* @var int
*/
var $col = -1;
/**
* current row
*
* @var int
*/
var $row = 0;
/**
* constructor, see Markdownify::Markdownify() for more information
*/
function Markdownify_Extra($linksAfterEachParagraph = MDFY_LINKS_EACH_PARAGRAPH, $bodyWidth = MDFY_BODYWIDTH, $keepHTML = MDFY_KEEPHTML) {
parent::Markdownify($linksAfterEachParagraph, $bodyWidth, $keepHTML);
### new markdownable tags & attributes
# header ids: # foo {bar}
$this->isMarkdownable['h1']['id'] = 'optional';
$this->isMarkdownable['h2']['id'] = 'optional';
$this->isMarkdownable['h3']['id'] = 'optional';
$this->isMarkdownable['h4']['id'] = 'optional';
$this->isMarkdownable['h5']['id'] = 'optional';
$this->isMarkdownable['h6']['id'] = 'optional';
# tables
$this->isMarkdownable['table'] = array();
$this->isMarkdownable['th'] = array(
'align' => 'optional',
);
$this->isMarkdownable['td'] = array(
'align' => 'optional',
);
$this->isMarkdownable['tr'] = array();
array_push($this->ignore, 'thead');
array_push($this->ignore, 'tbody');
array_push($this->ignore, 'tfoot');
# definition lists
$this->isMarkdownable['dl'] = array();
$this->isMarkdownable['dd'] = array();
$this->isMarkdownable['dt'] = array();
# footnotes
$this->isMarkdownable['fnref'] = array(
'target' => 'required',
);
$this->isMarkdownable['footnotes'] = array();
$this->isMarkdownable['fn'] = array(
'name' => 'required',
);
$this->parser->blockElements['fnref'] = false;
$this->parser->blockElements['fn'] = true;
$this->parser->blockElements['footnotes'] = true;
# abbr
$this->isMarkdownable['abbr'] = array(
'title' => 'required',
);
# build RegEx lookahead to decide wether table can pe parsed or not
$inlineTags = array_keys($this->parser->blockElements, false);
$colContents = '(?:[^<]|<(?:'.implode('|', $inlineTags).'|[^a-z]))+';
$this->tableLookaheadHeader = '{
^\s*(?:<thead\s*>)?\s* # open optional thead
<tr\s*>\s*(?: # start required row with headers
<th(?:\s+align=("|\')(?:left|center|right)\1)?\s*> # header with optional align
\s*'.$colContents.'\s* # contents
</th>\s* # close header
)+</tr> # close row with headers
\s*(?:</thead>)? # close optional thead
}sxi';
$this->tdSubstitute = '\s*'.$colContents.'\s* # contents
</td>\s*';
$this->tableLookaheadBody = '{
\s*(?:<tbody\s*>)?\s* # open optional tbody
(?:<tr\s*>\s* # start row
%s # cols to be substituted
</tr>)+ # close row
\s*(?:</tbody>)? # close optional tbody
\s*</table> # close table
}sxi';
}
/**
* handle header tags (<h1> - <h6>)
*
* @param int $level 1-6
* @return void
*/
function handleHeader($level) {
static $id = null;
if ($this->parser->isStartTag) {
if (isset($this->parser->tagAttributes['id'])) {
$id = $this->parser->tagAttributes['id'];
}
} else {
if (!is_null($id)) {
$this->out(' {#'.$id.'}');
$id = null;
}
}
parent::handleHeader($level);
}
/**
* handle <abbr> tags
*
* @param void
* @return void
*/
function handleTag_abbr() {
if ($this->parser->isStartTag) {
$this->stack();
$this->buffer();
} else {
$tag = $this->unstack();
$tag['text'] = $this->unbuffer();
$add = true;
foreach ($this->stack['abbr'] as $stacked) {
if ($stacked['text'] == $tag['text']) {
/** TODO: differing abbr definitions, i.e. different titles for same text **/
$add = false;
break;
}
}
$this->out($tag['text']);
if ($add) {
array_push($this->stack['abbr'], $tag);
}
}
}
/**
* flush stacked abbr tags
*
* @param void
* @return void
*/
function flushStacked_abbr() {
$out = array();
foreach ($this->stack['abbr'] as $k => $tag) {
if (!isset($tag['unstacked'])) {
array_push($out, ' *['.$tag['text'].']: '.$tag['title']);
$tag['unstacked'] = true;
$this->stack['abbr'][$k] = $tag;
}
}
if (!empty($out)) {
$this->out("\n\n".implode("\n", $out));
}
}
/**
* handle <table> tags
*
* @param void
* @return void
*/
function handleTag_table() {
if ($this->parser->isStartTag) {
# check if upcoming table can be converted
if ($this->keepHTML) {
if (preg_match($this->tableLookaheadHeader, $this->parser->html, $matches)) {
# header seems good, now check body
# get align & number of cols
preg_match_all('#<th(?:\s+align=("|\')(left|right|center)\1)?\s*>#si', $matches[0], $cols);
$regEx = '';
$i = 1;
$aligns = array();
foreach ($cols[2] as $align) {
$align = strtolower($align);
array_push($aligns, $align);
if (empty($align)) {
$align = 'left'; # default value
}
$td = '\s+align=("|\')'.$align.'\\'.$i;
$i++;
if ($align == 'left') {
# look for empty align or left
$td = '(?:'.$td.')?';
}
$td = '<td'.$td.'\s*>';
$regEx .= $td.$this->tdSubstitute;
}
$regEx = sprintf($this->tableLookaheadBody, $regEx);
if (preg_match($regEx, $this->parser->html, $matches, null, strlen($matches[0]))) {
# this is a markdownable table tag!
$this->table = array(
'rows' => array(),
'col_widths' => array(),
'aligns' => $aligns,
);
$this->row = 0;
} else {
# non markdownable table
$this->handleTagToText();
}
} else {
# non markdownable table
$this->handleTagToText();
}
} else {
$this->table = array(
'rows' => array(),
'col_widths' => array(),
'aligns' => array(),
);
$this->row = 0;
}
} else {
# finally build the table in Markdown Extra syntax
$separator = array();
# seperator with correct align identifikators
foreach($this->table['aligns'] as $col => $align) {
if (!$this->keepHTML && !isset($this->table['col_widths'][$col])) {
break;
}
$left = ' ';
$right = ' ';
switch ($align) {
case 'left':
$left = ':';
break;
case 'center':
$right = ':';
$left = ':';
case 'right':
$right = ':';
break;
}
array_push($separator, $left.str_repeat('-', $this->table['col_widths'][$col]).$right);
}
$separator = '|'.implode('|', $separator).'|';
$rows = array();
# add padding
array_walk_recursive($this->table['rows'], array(&$this, 'alignTdContent'));
$header = array_shift($this->table['rows']);
array_push($rows, '| '.implode(' | ', $header).' |');
array_push($rows, $separator);
foreach ($this->table['rows'] as $row) {
array_push($rows, '| '.implode(' | ', $row).' |');
}
$this->out(implode("\n".$this->indent, $rows));
$this->table = array();
$this->setLineBreaks(2);
}
}
/**
* properly pad content so it is aligned as whished
* should be used with array_walk_recursive on $this->table['rows']
*
* @param string &$content
* @param int $col
* @return void
*/
function alignTdContent(&$content, $col) {
switch ($this->table['aligns'][$col]) {
default:
case 'left':
$content .= str_repeat(' ', $this->table['col_widths'][$col] - $this->strlen($content));
break;
case 'right':
$content = str_repeat(' ', $this->table['col_widths'][$col] - $this->strlen($content)).$content;
break;
case 'center':
$paddingNeeded = $this->table['col_widths'][$col] - $this->strlen($content);
$left = floor($paddingNeeded / 2);
$right = $paddingNeeded - $left;
$content = str_repeat(' ', $left).$content.str_repeat(' ', $right);
break;
}
}
/**
* handle <tr> tags
*
* @param void
* @return void
*/
function handleTag_tr() {
if ($this->parser->isStartTag) {
$this->col = -1;
} else {
$this->row++;
}
}
/**
* handle <td> tags
*
* @param void
* @return void
*/
function handleTag_td() {
if ($this->parser->isStartTag) {
$this->col++;
if (!isset($this->table['col_widths'][$this->col])) {
$this->table['col_widths'][$this->col] = 0;
}
$this->buffer();
} else {
$buffer = trim($this->unbuffer());
$this->table['col_widths'][$this->col] = max($this->table['col_widths'][$this->col], $this->strlen($buffer));
$this->table['rows'][$this->row][$this->col] = $buffer;
}
}
/**
* handle <th> tags
*
* @param void
* @return void
*/
function handleTag_th() {
if (!$this->keepHTML && !isset($this->table['rows'][1]) && !isset($this->table['aligns'][$this->col+1])) {
if (isset($this->parser->tagAttributes['align'])) {
$this->table['aligns'][$this->col+1] = $this->parser->tagAttributes['align'];
} else {
$this->table['aligns'][$this->col+1] = '';
}
}
$this->handleTag_td();
}
/**
* handle <dl> tags
*
* @param void
* @return void
*/
function handleTag_dl() {
if (!$this->parser->isStartTag) {
$this->setLineBreaks(2);
}
}
/**
* handle <dt> tags
*
* @param void
* @return void
**/
function handleTag_dt() {
if (!$this->parser->isStartTag) {
$this->setLineBreaks(1);
}
}
/**
* handle <dd> tags
*
* @param void
* @return void
*/
function handleTag_dd() {
if ($this->parser->isStartTag) {
if (substr(ltrim($this->parser->html), 0, 3) == '<p>') {
# next comes a paragraph, so we'll need an extra line
$this->out("\n".$this->indent);
} elseif (substr($this->output, -2) == "\n\n") {
$this->output = substr($this->output, 0, -1);
}
$this->out(': ');
$this->indent(' ', false);
} else {
# lookahead for next dt
if (substr(ltrim($this->parser->html), 0, 4) == '<dt>') {
$this->setLineBreaks(2);
} else {
$this->setLineBreaks(1);
}
$this->indent(' ');
}
}
/**
* handle <fnref /> tags (custom footnote references, see markdownify_extra::parseString())
*
* @param void
* @return void
*/
function handleTag_fnref() {
$this->out('[^'.$this->parser->tagAttributes['target'].']');
}
/**
* handle <fn> tags (custom footnotes, see markdownify_extra::parseString()
* and markdownify_extra::_makeFootnotes())
*
* @param void
* @return void
*/
function handleTag_fn() {
if ($this->parser->isStartTag) {
$this->out('[^'.$this->parser->tagAttributes['name'].']:');
$this->setLineBreaks(1);
} else {
$this->setLineBreaks(2);
}
$this->indent(' ');
}
/**
* handle <footnotes> tag (custom footnotes, see markdownify_extra::parseString()
* and markdownify_extra::_makeFootnotes())
*
* @param void
* @return void
*/
function handleTag_footnotes() {
if (!$this->parser->isStartTag) {
$this->setLineBreaks(2);
}
}
/**
* parse a HTML string, clean up footnotes prior
*
* @param string $HTML input
* @return string Markdown formatted output
*/
function parseString($html) {
/** TODO: custom markdown-extra options, e.g. titles & classes **/
# <sup id="fnref:..."><a href"#fn..." rel="footnote">...</a></sup>
# => <fnref target="..." />
$html = preg_replace('@<sup id="fnref:([^"]+)">\s*<a href="#fn:\1" rel="footnote">\s*\d+\s*</a>\s*</sup>@Us', '<fnref target="$1" />', $html);
# <div class="footnotes">
# <hr />
# <ol>
#
# <li id="fn:...">...</li>
# ...
#
# </ol>
# </div>
# =>
# <footnotes>
# <fn name="...">...</fn>
# ...
# </footnotes>
$html = preg_replace_callback('#<div class="footnotes">\s*<hr />\s*<ol>\s*(.+)\s*</ol>\s*</div>#Us', array(&$this, '_makeFootnotes'), $html);
return parent::parseString($html);
}
/**
* replace HTML representation of footnotes with something more easily parsable
*
* @note this is a callback to be used in parseString()
*
* @param array $matches
* @return string
*/
function _makeFootnotes($matches) {
# <li id="fn:1">
# ...
# <a href="#fnref:block" rev="footnote">&#8617;</a></p>
# </li>
# => <fn name="1">...</fn>
# remove footnote link
$fns = preg_replace('@\s*(&#160;\s*)?<a href="#fnref:[^"]+" rev="footnote"[^>]*>&#8617;</a>\s*@s', '', $matches[1]);
# remove empty paragraph
$fns = preg_replace('@<p>\s*</p>@s', '', $fns);
# <li id="fn:1">...</li> -> <footnote nr="1">...</footnote>
$fns = str_replace('<li id="fn:', '<fn name="', $fns);
$fns = '<footnotes>'.$fns.'</footnotes>';
return preg_replace('#</li>\s*(?=(?:<fn|</footnotes>))#s', '</fn>$1', $fns);
}
}

View file

@ -1,618 +0,0 @@
<?php
/**
* parseHTML is a HTML parser which works with PHP 4 and above.
* It tries to handle invalid HTML to some degree.
*
* @version 1.0 beta
* @author Milian Wolff (mail@milianw.de, http://milianw.de)
* @license LGPL, see LICENSE_LGPL.txt and the summary below
* @copyright (C) 2007 Milian Wolff
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
class parseHTML {
/**
* tags which are always empty (<br /> etc.)
*
* @var array<string>
*/
var $emptyTags = array(
'br',
'hr',
'input',
'img',
'area',
'link',
'meta',
'param',
);
/**
* tags with preformatted text
* whitespaces wont be touched in them
*
* @var array<string>
*/
var $preformattedTags = array(
'script',
'style',
'pre',
'code',
);
/**
* supress HTML tags inside preformatted tags (see above)
*
* @var bool
*/
var $noTagsInCode = false;
/**
* html to be parsed
*
* @var string
*/
var $html = '';
/**
* node type:
*
* - tag (see isStartTag)
* - text (includes cdata)
* - comment
* - doctype
* - pi (processing instruction)
*
* @var string
*/
var $nodeType = '';
/**
* current node content, i.e. either a
* simple string (text node), or something like
* <tag attrib="value"...>
*
* @var string
*/
var $node = '';
/**
* wether current node is an opening tag (<a>) or not (</a>)
* set to NULL if current node is not a tag
* NOTE: empty tags (<br />) set this to true as well!
*
* @var bool | null
*/
var $isStartTag = null;
/**
* wether current node is an empty tag (<br />) or not (<a></a>)
*
* @var bool | null
*/
var $isEmptyTag = null;
/**
* tag name
*
* @var string | null
*/
var $tagName = '';
/**
* attributes of current tag
*
* @var array (attribName=>value) | null
*/
var $tagAttributes = null;
/**
* wether the current tag is a block element
*
* @var bool | null
*/
var $isBlockElement = null;
/**
* keep whitespace
*
* @var int
*/
var $keepWhitespace = 0;
/**
* list of open tags
* count this to get current depth
*
* @var array
*/
var $openTags = array();
/**
* list of block elements
*
* @var array
* TODO: what shall we do with <del> and <ins> ?!
*/
var $blockElements = array (
# tag name => <bool> is block
# block elements
'address' => true,
'blockquote' => true,
'center' => true,
'del' => true,
'dir' => true,
'div' => true,
'dl' => true,
'fieldset' => true,
'form' => true,
'h1' => true,
'h2' => true,
'h3' => true,
'h4' => true,
'h5' => true,
'h6' => true,
'hr' => true,
'ins' => true,
'isindex' => true,
'menu' => true,
'noframes' => true,
'noscript' => true,
'ol' => true,
'p' => true,
'pre' => true,
'table' => true,
'ul' => true,
# set table elements and list items to block as well
'thead' => true,
'tbody' => true,
'tfoot' => true,
'td' => true,
'tr' => true,
'th' => true,
'li' => true,
'dd' => true,
'dt' => true,
# header items and html / body as well
'html' => true,
'body' => true,
'head' => true,
'meta' => true,
'link' => true,
'style' => true,
'title' => true,
# unfancy media tags, when indented should be rendered as block
'map' => true,
'object' => true,
'param' => true,
'embed' => true,
'area' => true,
# inline elements
'a' => false,
'abbr' => false,
'acronym' => false,
'applet' => false,
'b' => false,
'basefont' => false,
'bdo' => false,
'big' => false,
'br' => false,
'button' => false,
'cite' => false,
'code' => false,
'del' => false,
'dfn' => false,
'em' => false,
'font' => false,
'i' => false,
'img' => false,
'ins' => false,
'input' => false,
'iframe' => false,
'kbd' => false,
'label' => false,
'q' => false,
'samp' => false,
'script' => false,
'select' => false,
'small' => false,
'span' => false,
'strong' => false,
'sub' => false,
'sup' => false,
'textarea' => false,
'tt' => false,
'var' => false,
);
/**
* get next node, set $this->html prior!
*
* @param void
* @return bool
*/
function nextNode() {
if (empty($this->html)) {
# we are done with parsing the html string
return false;
}
static $skipWhitespace = true;
if ($this->isStartTag && !$this->isEmptyTag) {
array_push($this->openTags, $this->tagName);
if (in_array($this->tagName, $this->preformattedTags)) {
# dont truncate whitespaces for <code> or <pre> contents
$this->keepWhitespace++;
}
}
if ($this->html[0] == '<') {
$token = substr($this->html, 0, 9);
if (substr($token, 0, 2) == '<?') {
# xml prolog or other pi's
/** TODO **/
#trigger_error('this might need some work', E_USER_NOTICE);
$pos = strpos($this->html, '>');
$this->setNode('pi', $pos + 1);
return true;
}
if (substr($token, 0, 4) == '<!--') {
# comment
$pos = strpos($this->html, '-->');
if ($pos === false) {
# could not find a closing -->, use next gt instead
# this is firefox' behaviour
$pos = strpos($this->html, '>') + 1;
} else {
$pos += 3;
}
$this->setNode('comment', $pos);
$skipWhitespace = true;
return true;
}
if ($token == '<!DOCTYPE') {
# doctype
$this->setNode('doctype', strpos($this->html, '>')+1);
$skipWhitespace = true;
return true;
}
if ($token == '<![CDATA[') {
# cdata, use text node
# remove leading <![CDATA[
$this->html = substr($this->html, 9);
$this->setNode('text', strpos($this->html, ']]>')+3);
# remove trailing ]]> and trim
$this->node = substr($this->node, 0, -3);
$this->handleWhitespaces();
$skipWhitespace = true;
return true;
}
if ($this->parseTag()) {
# seems to be a tag
# handle whitespaces
if ($this->isBlockElement) {
$skipWhitespace = true;
} else {
$skipWhitespace = false;
}
return true;
}
}
if ($this->keepWhitespace) {
$skipWhitespace = false;
}
# when we get here it seems to be a text node
$pos = strpos($this->html, '<');
if ($pos === false) {
$pos = strlen($this->html);
}
$this->setNode('text', $pos);
$this->handleWhitespaces();
if ($skipWhitespace && $this->node == ' ') {
return $this->nextNode();
}
$skipWhitespace = false;
return true;
}
/**
* parse tag, set tag name and attributes, see if it's a closing tag and so forth...
*
* @param void
* @return bool
*/
function parseTag() {
static $a_ord, $z_ord, $special_ords;
if (!isset($a_ord)) {
$a_ord = ord('a');
$z_ord = ord('z');
$special_ords = array(
ord(':'), // for xml:lang
ord('-'), // for http-equiv
);
}
$tagName = '';
$pos = 1;
$isStartTag = $this->html[$pos] != '/';
if (!$isStartTag) {
$pos++;
}
# get tagName
while (isset($this->html[$pos])) {
$pos_ord = ord(strtolower($this->html[$pos]));
if (($pos_ord >= $a_ord && $pos_ord <= $z_ord) || (!empty($tagName) && is_numeric($this->html[$pos]))) {
$tagName .= $this->html[$pos];
$pos++;
} else {
$pos--;
break;
}
}
$tagName = strtolower($tagName);
if (empty($tagName) || !isset($this->blockElements[$tagName])) {
# something went wrong => invalid tag
$this->invalidTag();
return false;
}
if ($this->noTagsInCode && end($this->openTags) == 'code' && !($tagName == 'code' && !$isStartTag)) {
# we supress all HTML tags inside code tags
$this->invalidTag();
return false;
}
# get tag attributes
/** TODO: in html 4 attributes do not need to be quoted **/
$isEmptyTag = false;
$attributes = array();
$currAttrib = '';
while (isset($this->html[$pos+1])) {
$pos++;
# close tag
if ($this->html[$pos] == '>' || $this->html[$pos].$this->html[$pos+1] == '/>') {
if ($this->html[$pos] == '/') {
$isEmptyTag = true;
$pos++;
}
break;
}
$pos_ord = ord(strtolower($this->html[$pos]));
if ( ($pos_ord >= $a_ord && $pos_ord <= $z_ord) || in_array($pos_ord, $special_ords)) {
# attribute name
$currAttrib .= $this->html[$pos];
} elseif (in_array($this->html[$pos], array(' ', "\t", "\n"))) {
# drop whitespace
} elseif (in_array($this->html[$pos].$this->html[$pos+1], array('="', "='"))) {
# get attribute value
$pos++;
$await = $this->html[$pos]; # single or double quote
$pos++;
$value = '';
while (isset($this->html[$pos]) && $this->html[$pos] != $await) {
$value .= $this->html[$pos];
$pos++;
}
$attributes[$currAttrib] = $value;
$currAttrib = '';
} else {
$this->invalidTag();
return false;
}
}
if ($this->html[$pos] != '>') {
$this->invalidTag();
return false;
}
if (!empty($currAttrib)) {
# html 4 allows something like <option selected> instead of <option selected="selected">
$attributes[$currAttrib] = $currAttrib;
}
if (!$isStartTag) {
if (!empty($attributes) || $tagName != end($this->openTags)) {
# end tags must not contain any attributes
# or maybe we did not expect a different tag to be closed
$this->invalidTag();
return false;
}
array_pop($this->openTags);
if (in_array($tagName, $this->preformattedTags)) {
$this->keepWhitespace--;
}
}
$pos++;
$this->node = substr($this->html, 0, $pos);
$this->html = substr($this->html, $pos);
$this->tagName = $tagName;
$this->tagAttributes = $attributes;
$this->isStartTag = $isStartTag;
$this->isEmptyTag = $isEmptyTag || in_array($tagName, $this->emptyTags);
if ($this->isEmptyTag) {
# might be not well formed
$this->node = preg_replace('# */? *>$#', ' />', $this->node);
}
$this->nodeType = 'tag';
$this->isBlockElement = $this->blockElements[$tagName];
return true;
}
/**
* handle invalid tags
*
* @param void
* @return void
*/
function invalidTag() {
$this->html = substr_replace($this->html, '&lt;', 0, 1);
}
/**
* update all vars and make $this->html shorter
*
* @param string $type see description for $this->nodeType
* @param int $pos to which position shall we cut?
* @return void
*/
function setNode($type, $pos) {
if ($this->nodeType == 'tag') {
# set tag specific vars to null
# $type == tag should not be called here
# see this::parseTag() for more
$this->tagName = null;
$this->tagAttributes = null;
$this->isStartTag = null;
$this->isEmptyTag = null;
$this->isBlockElement = null;
}
$this->nodeType = $type;
$this->node = substr($this->html, 0, $pos);
$this->html = substr($this->html, $pos);
}
/**
* check if $this->html begins with $str
*
* @param string $str
* @return bool
*/
function match($str) {
return substr($this->html, 0, strlen($str)) == $str;
}
/**
* truncate whitespaces
*
* @param void
* @return void
*/
function handleWhitespaces() {
if ($this->keepWhitespace) {
# <pre> or <code> before...
return;
}
# truncate multiple whitespaces to a single one
$this->node = preg_replace('#\s+#s', ' ', $this->node);
}
/**
* normalize self::node
*
* @param void
* @return void
*/
function normalizeNode() {
$this->node = '<';
if (!$this->isStartTag) {
$this->node .= '/'.$this->tagName.'>';
return;
}
$this->node .= $this->tagName;
foreach ($this->tagAttributes as $name => $value) {
$this->node .= ' '.$name.'="'.str_replace('"', '&quot;', $value).'"';
}
if ($this->isEmptyTag) {
$this->node .= ' /';
}
$this->node .= '>';
}
}
/**
* indent a HTML string properly
*
* @param string $html
* @param string $indent optional
* @return string
*/
function indentHTML($html, $indent = " ", $noTagsInCode = false) {
$parser = new parseHTML;
$parser->noTagsInCode = $noTagsInCode;
$parser->html = $html;
$html = '';
$last = true; # last tag was block elem
$indent_a = array();
while($parser->nextNode()) {
if ($parser->nodeType == 'tag') {
$parser->normalizeNode();
}
if ($parser->nodeType == 'tag' && $parser->isBlockElement) {
$isPreOrCode = in_array($parser->tagName, array('code', 'pre'));
if (!$parser->keepWhitespace && !$last && !$isPreOrCode) {
$html = rtrim($html)."\n";
}
if ($parser->isStartTag) {
$html .= implode($indent_a);
if (!$parser->isEmptyTag) {
array_push($indent_a, $indent);
}
} else {
array_pop($indent_a);
if (!$isPreOrCode) {
$html .= implode($indent_a);
}
}
$html .= $parser->node;
if (!$parser->keepWhitespace && !($isPreOrCode && $parser->isStartTag)) {
$html .= "\n";
}
$last = true;
} else {
if ($parser->nodeType == 'tag' && $parser->tagName == 'br') {
$html .= $parser->node."\n";
$last = true;
continue;
} elseif ($last && !$parser->keepWhitespace) {
$html .= implode($indent_a);
$parser->node = ltrim($parser->node);
}
$html .= $parser->node;
if (in_array($parser->nodeType, array('comment', 'pi', 'doctype'))) {
$html .= "\n";
} else {
$last = false;
}
}
}
return $html;
}
/*
# testcase / example
error_reporting(E_ALL);
$html = '<p>Simple block on one line:</p>
<div>foo</div>
<p>And nested without indentation:</p>
<div>
<div>
<div>
foo
</div>
<div style=">"/>
</div>
<div>bar</div>
</div>
<p>And with attributes:</p>
<div>
<div id="foo">
</div>
</div>
<p>This was broken in 1.0.2b7:</p>
<div class="inlinepage">
<div class="toggleableend">
foo
</div>
</div>';
#$html = '<a href="asdfasdf" title=\'asdf\' foo="bar">asdf</a>';
echo indentHTML($html);
die();
*/

View file

@ -125,8 +125,10 @@ function nav_info(&$a) {
if(strlen($gdir))
$gdirpath = $gdir;
}
elseif(! get_config('system','no_community_page'))
elseif(get_config('system','community_page_style') == CP_USERS_ON_SERVER)
$nav['community'] = array('community', t('Community'), "", t('Conversations on this site'));
elseif(get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
$nav['community'] = array('community', t('Community'), "", t('Conversations on the network'));
$nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory'));

View file

@ -50,6 +50,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_
$check_cert = get_config('system','verifyssl');
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
@curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
$prx = get_config('system','proxy');
if(strlen($prx)) {
@ -71,6 +72,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_
$base = $s;
$curl_info = @curl_getinfo($ch);
@curl_close($ch);
$http_code = $curl_info['http_code'];
logger('fetch_url '.$url.': '.$http_code." ".$s, LOGGER_DATA);
$header = '';
@ -94,7 +96,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_
$newurl = $new_location_info["scheme"]."://".$new_location_info["host"].$old_location_info["path"];
$matches = array();
if (preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches)) {
if (preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches)) {
$newurl = trim(array_pop($matches));
}
if(strpos($newurl,'/') === 0)
@ -110,7 +112,6 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_
$body = substr($s,strlen($header));
$a->set_curl_headers($header);
@curl_close($ch);
$a->save_timestamp($stamp1, "network");
@ -158,6 +159,7 @@ function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0)
$check_cert = get_config('system','verifyssl');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
$prx = get_config('system','proxy');
if(strlen($prx)) {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
@ -259,43 +261,43 @@ function http_status_exit($val) {
if(! function_exists('convert_xml_element_to_array')) {
function convert_xml_element_to_array($xml_element, &$recursion_depth=0) {
// If we're getting too deep, bail out
if ($recursion_depth > 512) {
return(null);
}
// If we're getting too deep, bail out
if ($recursion_depth > 512) {
return(null);
}
if (!is_string($xml_element) &&
!is_array($xml_element) &&
(get_class($xml_element) == 'SimpleXMLElement')) {
$xml_element_copy = $xml_element;
$xml_element = get_object_vars($xml_element);
}
if (!is_string($xml_element) &&
!is_array($xml_element) &&
(get_class($xml_element) == 'SimpleXMLElement')) {
$xml_element_copy = $xml_element;
$xml_element = get_object_vars($xml_element);
}
if (is_array($xml_element)) {
$result_array = array();
if (count($xml_element) <= 0) {
return (trim(strval($xml_element_copy)));
}
if (is_array($xml_element)) {
$result_array = array();
if (count($xml_element) <= 0) {
return (trim(strval($xml_element_copy)));
}
foreach($xml_element as $key=>$value) {
foreach($xml_element as $key=>$value) {
$recursion_depth++;
$result_array[strtolower($key)] =
convert_xml_element_to_array($value, $recursion_depth);
$recursion_depth--;
}
if ($recursion_depth == 0) {
$temp_array = $result_array;
$result_array = array(
strtolower($xml_element_copy->getName()) => $temp_array,
);
}
$recursion_depth++;
$result_array[strtolower($key)] =
convert_xml_element_to_array($value, $recursion_depth);
$recursion_depth--;
}
if ($recursion_depth == 0) {
$temp_array = $result_array;
$result_array = array(
strtolower($xml_element_copy->getName()) => $temp_array,
);
}
return ($result_array);
return ($result_array);
} else {
return (trim(strval($xml_element)));
}
} else {
return (trim(strval($xml_element)));
}
}}
// Given an email style address, perform webfinger lookup and
@ -868,13 +870,6 @@ function scale_external_images($srctext, $include_link = true, $scale_replace =
if(! $i)
return $srctext;
$cachefile = get_cachefile(hash("md5", $scaled));
if ($cachefile != '') {
$stamp1 = microtime(true);
file_put_contents($cachefile, $i);
$a->save_timestamp($stamp1, "file");
}
// guess mimetype from headers or filename
$type = guess_image_type($mtch[1],true);
@ -969,8 +964,8 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
if(!$contents) return array();
if(!function_exists('xml_parser_create')) {
logger('xml2array: parser function missing');
return array();
logger('xml2array: parser function missing');
return array();
}
@ -1013,29 +1008,29 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
// Go through the tags.
$repeated_tag_index = array(); // Multiple tags with same name will be turned into an array
foreach($xml_values as $data) {
unset($attributes,$value); // Remove existing values, or there will be trouble
unset($attributes,$value); // Remove existing values, or there will be trouble
// This command will extract these variables into the foreach scope
// tag(string), type(string), level(int), attributes(array).
extract($data); // We could use the array by itself, but this cooler.
// This command will extract these variables into the foreach scope
// tag(string), type(string), level(int), attributes(array).
extract($data); // We could use the array by itself, but this cooler.
$result = array();
$attributes_data = array();
$result = array();
$attributes_data = array();
if(isset($value)) {
if($priority == 'tag') $result = $value;
else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
}
if(isset($value)) {
if($priority == 'tag') $result = $value;
else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
}
//Set the attributes too.
if(isset($attributes) and $get_attributes) {
foreach($attributes as $attr => $val) {
if($priority == 'tag') $attributes_data[$attr] = $val;
else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
}
}
//Set the attributes too.
if(isset($attributes) and $get_attributes) {
foreach($attributes as $attr => $val) {
if($priority == 'tag') $attributes_data[$attr] = $val;
else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
}
}
// See tag status and do the needed.
// See tag status and do the needed.
if($namespaces && strpos($tag,':')) {
$namespc = substr($tag,0,strrpos($tag,':'));
$tag = strtolower(substr($tag,strlen($namespc)+1));
@ -1044,72 +1039,72 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
$tag = strtolower($tag);
if($type == "open") { // The starting of the tag '<tag>'
$parent[$level-1] = &$current;
if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
$current[$tag] = $result;
if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
$repeated_tag_index[$tag.'_'.$level] = 1;
$parent[$level-1] = &$current;
if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
$current[$tag] = $result;
if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
$repeated_tag_index[$tag.'_'.$level] = 1;
$current = &$current[$tag];
$current = &$current[$tag];
} else { // There was another element with the same tag name
} else { // There was another element with the same tag name
if(isset($current[$tag][0])) { // If there is a 0th element it is already an array
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
$repeated_tag_index[$tag.'_'.$level]++;
} else { // This section will make the value an array if multiple tags with the same name appear together
$current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
$repeated_tag_index[$tag.'_'.$level] = 2;
if(isset($current[$tag][0])) { // If there is a 0th element it is already an array
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
$repeated_tag_index[$tag.'_'.$level]++;
} else { // This section will make the value an array if multiple tags with the same name appear together
$current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
$repeated_tag_index[$tag.'_'.$level] = 2;
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
}
$last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
$current = &$current[$tag][$last_item_index];
}
}
$last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
$current = &$current[$tag][$last_item_index];
}
} elseif($type == "complete") { // Tags that ends in 1 line '<tag />'
//See if the key is already taken.
if(!isset($current[$tag])) { //New Key
$current[$tag] = $result;
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
} elseif($type == "complete") { // Tags that ends in 1 line '<tag />'
//See if the key is already taken.
if(!isset($current[$tag])) { //New Key
$current[$tag] = $result;
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
} else { // If taken, put all things inside a list(array)
if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
} else { // If taken, put all things inside a list(array)
if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
// ...push the new element into that array.
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
// ...push the new element into that array.
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
if($priority == 'tag' and $get_attributes and $attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag.'_'.$level]++;
if($priority == 'tag' and $get_attributes and $attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag.'_'.$level]++;
} else { // If it is not an array...
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $get_attributes) {
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
} else { // If it is not an array...
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $get_attributes) {
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
if($attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
}
$repeated_tag_index[$tag.'_'.$level]++; // 0 and 1 indexes are already taken
}
}
if($attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
}
$repeated_tag_index[$tag.'_'.$level]++; // 0 and 1 indexes are already taken
}
}
} elseif($type == 'close') { // End of tag '</tag>'
$current = &$parent[$level-1];
}
} elseif($type == 'close') { // End of tag '</tag>'
$current = &$parent[$level-1];
}
}
return($xml_array);
@ -1151,32 +1146,36 @@ function original_url($url, $depth=1, $fetchbody = false) {
$url = substr($url, 0, -1);
}
if ($depth > 10)
return($url);
if ($depth > 10)
return($url);
$url = trim($url, "'");
$url = trim($url, "'");
$siteinfo = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$stamp1 = microtime(true);
$siteinfo = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
curl_close($ch);
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
curl_close($ch);
if ((($curl_info['http_code'] == "301") OR ($curl_info['http_code'] == "302"))
AND (($curl_info['redirect_url'] != "") OR ($curl_info['location'] != ""))) {
if ($curl_info['redirect_url'] != "")
return(original_url($curl_info['redirect_url'], ++$depth, $fetchbody));
else
return(original_url($curl_info['location'], ++$depth, $fetchbody));
}
$a->save_timestamp($stamp1, "network");
if ((($curl_info['http_code'] == "301") OR ($curl_info['http_code'] == "302"))
AND (($curl_info['redirect_url'] != "") OR ($curl_info['location'] != ""))) {
if ($curl_info['redirect_url'] != "")
return(original_url($curl_info['redirect_url'], ++$depth, $fetchbody));
else
return(original_url($curl_info['location'], ++$depth, $fetchbody));
}
// Check for redirects in the meta elements of the body if there are no redirects in the header.
if (!$fetchbody)
@ -1190,6 +1189,8 @@ function original_url($url, $depth=1, $fetchbody = false) {
if (($curl_info["content_type"] != "") AND !strstr(strtolower($curl_info["content_type"]),"html"))
return($url);
$stamp1 = microtime(true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
@ -1201,33 +1202,35 @@ function original_url($url, $depth=1, $fetchbody = false) {
$body = curl_exec($ch);
curl_close($ch);
if (trim($body) == "")
$a->save_timestamp($stamp1, "network");
if (trim($body) == "")
return($url);
// Check for redirect in meta elements
$doc = new DOMDocument();
@$doc->loadHTML($body);
$doc = new DOMDocument();
@$doc->loadHTML($body);
$xpath = new DomXPath($doc);
$xpath = new DomXPath($doc);
$list = $xpath->query("//meta[@content]");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$list = $xpath->query("//meta[@content]");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
if (@$attr["http-equiv"] == 'refresh') {
$path = $attr["content"];
$pathinfo = explode(";", $path);
$content = "";
foreach ($pathinfo AS $value)
if (substr(strtolower($value), 0, 4) == "url=")
return(original_url(substr($value, 4), ++$depth));
}
}
if (@$attr["http-equiv"] == 'refresh') {
$path = $attr["content"];
$pathinfo = explode(";", $path);
$content = "";
foreach ($pathinfo AS $value)
if (substr(strtolower($value), 0, 4) == "url=")
return(original_url(substr($value, 4), ++$depth));
}
}
return($url);
return($url);
}
if (!function_exists('short_link')) {

View file

@ -11,7 +11,6 @@ function oembed_replacecb($matches){
function oembed_fetch_url($embedurl, $no_rich_type = false){
$embedurl = trim($embedurl, "'");
$embedurl = trim($embedurl, '"');
@ -163,6 +162,7 @@ function oembed_format_object($j){
// add link to source if not present in "rich" type
if ($j->type!='rich' || !strpos($j->html,$embedurl) ){
$ret .= "<h4>";
if (isset($j->title)) {
if (isset($j->provider_name))
$ret .= $j->provider_name.": ";
@ -189,11 +189,12 @@ function oembed_format_object($j){
}
//if (isset($j->author_name)) $ret.=" by ".$j->author_name;
//if (isset($j->provider_name)) $ret.=" on ".$j->provider_name;
$ret .= "</h4>";
} else {
// add <a> for html2bbcode conversion
$ret .= "<a href='$embedurl' rel='oembed'>$embedurl</a>";
$ret.="<br style='clear:left'></span>";
}
$ret.="<br style='clear:left'></span>";
return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
}

View file

@ -176,7 +176,7 @@ function onepoll_run(&$argv, &$argc){
return;
}
if(! strstr($handshake_xml,'<?xml')) {
if(! strstr($handshake_xml,'<')) {
logger('poller: response from ' . $url . ' did not contain XML.');
mark_for_death($contact);
@ -284,13 +284,13 @@ function onepoll_run(&$argv, &$argc){
}
elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
logger("onepoll: mail: Fetching", LOGGER_DEBUG);
logger("Mail: Fetching", LOGGER_DEBUG);
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
if($mail_disabled)
return;
logger("onepoll: Mail: Enabled", LOGGER_DEBUG);
logger("Mail: Enabled", LOGGER_DEBUG);
$mbox = null;
$x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
@ -312,7 +312,9 @@ function onepoll_run(&$argv, &$argc){
intval($mailconf[0]['id']),
intval($importer_uid)
);
}
logger("Mail: Connected to " . $mailconf[0]['user']);
} else
logger("Mail: Connection error ".$mailconf[0]['user']." ".print_r(imap_errors()));
}
if($mbox) {
@ -523,7 +525,10 @@ function onepoll_run(&$argv, &$argc){
}
}
}
}
} else
logger("Mail: no mails for ".$mailconf[0]['user']);
logger("Mail: closing connection for ".$mailconf[0]['user']);
imap_close($mbox);
}
}
@ -537,7 +542,7 @@ function onepoll_run(&$argv, &$argc){
if($xml) {
logger('poller: received xml : ' . $xml, LOGGER_DATA);
if((! strstr($xml,'<?xml')) && (! strstr($xml,'<rss'))) {
if(! strstr($xml,'<')) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),

View file

@ -52,7 +52,7 @@ function complete_conversation($itemid, $conversation_url, $only_add_conversatio
$a->last_ostatus_conversation_url = $conversation_url;
$messages = q("SELECT `uid`, `parent`, `created` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
$messages = q("SELECT `uid`, `parent`, `created`, `received`, `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
if (!$messages)
return;
$message = $messages[0];
@ -62,8 +62,9 @@ function complete_conversation($itemid, $conversation_url, $only_add_conversatio
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION));
if (!$conversation) {
$r = q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`) VALUES (%d, %d, %d, %d, '%s', '%s')",
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION), dbesc($message["created"]), dbesc($conversation_url));
$r = q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`, `created`, `received`, `guid`) VALUES (%d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s')",
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION),
dbesc($message["created"]), dbesc($conversation_url), dbesc($message["created"]), dbesc($message["received"]), dbesc($message["guid"]));
logger('complete_conversation: Storing conversation url '.$conversation_url.' for id '.$itemid);
}

View file

@ -1,4 +1,14 @@
<?php
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/")
$directory = $_SERVER["PWD"]."/".$directory;
$directory = realpath($directory."/..");
chdir($directory);
}
require_once("boot.php");
@ -74,8 +84,8 @@ function poller_run(&$argv, &$argc){
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// delete user and contact records for recently removed accounts
@ -149,7 +159,6 @@ function poller_run(&$argv, &$argc){
$manual_id = 0;
$generation = 0;
$hub_update = false;
$force = false;
$restart = false;
@ -169,7 +178,7 @@ function poller_run(&$argv, &$argc){
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
@ -182,26 +191,27 @@ function poller_run(&$argv, &$argc){
proc_run('php','include/cronhooks.php');
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
);
$contacts = q("SELECT `contact`.`id` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
AND NOT `network` IN ( '%s', '%s', '%s' )
$sql_extra
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0
AND `user`.`account_expired` = 0 AND `user`.`account_removed` = 0 $abandon_sql ORDER BY RAND()",
$contacts = q("SELECT `contact`.`id` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `rel` IN (%d, %d) AND `poll` != '' AND `network` IN ('%s', '%s', '%s', '%s', '%s', '%s')
$sql_extra
AND NOT `self` AND NOT `contact`.`blocked` AND NOT `contact`.`readonly` AND NOT `contact`.`archive`
AND NOT `user`.`account_expired` AND NOT `user`.`account_removed` $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_FACEBOOK),
dbesc(NETWORK_PUMPIO)
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_FEED),
dbesc(NETWORK_MAIL),
dbesc(NETWORK_MAIL2)
);
if(! count($contacts)) {
@ -224,35 +234,24 @@ function poller_run(&$argv, &$argc){
if($manual_id)
$contact['last-update'] = '0000-00-00 00:00:00';
if($contact['network'] === NETWORK_DFRN)
if(in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS)))
$contact['priority'] = 2;
if(!get_config('system','ostatus_use_priority') and ($contact['network'] === NETWORK_OSTATUS))
$contact['priority'] = 2;
if($contact['priority'] || $contact['subhub']) {
$hub_update = true;
$update = false;
$t = $contact['last-update'];
if($contact['subhub'] AND in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) {
// We should be getting everything via a hub. But just to be sure, let's check once a day.
// (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
// This also lets us update our subscription to the hub, and add or replace hubs in case it
// changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'.
$poll_interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
}
if($contact['subhub']) {
$poll_interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
$hub_update = false;
if($contact['priority'] AND !$force) {
if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force)
$hub_update = true;
}
else
$hub_update = false;
$update = false;
$t = $contact['last-update'];
/**
* Based on $contact['priority'], should we poll this site now? Or later?
@ -281,22 +280,21 @@ function poller_run(&$argv, &$argc){
$update = true;
break;
}
if((! $update) && (! $force))
if(!$update)
continue;
}
// Don't run onepoll.php if the contact isn't pollable
// This check also is inside the onepoll.php - but this will reduce the load
if (in_array($contact["rel"], array(CONTACT_IS_SHARING, CONTACT_IS_FRIEND)) AND ($contact["poll"] != "")
AND !in_array($contact['network'], array(NETWORK_DIASPORA, NETWORK_FACEBOOK, NETWORK_PUMPIO, NETWORK_TWITTER, NETWORK_APPNET))
AND !$contact["self"] AND !$contact["blocked"] AND !$contact["readonly"] AND !$contact["archive"])
proc_run('php','include/onepoll.php',$contact['id']);
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
proc_run('php','include/onepoll.php',$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
logger('poller: end');
return;
}

View file

@ -42,7 +42,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
if(! $url)
return;
$url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender') ;
$url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation') ;
logger('poco_load: ' . $url, LOGGER_DEBUG);
@ -76,6 +76,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
$about = '';
$keywords = '';
$gender = '';
$generation = 0;
$name = $entry->displayName;
@ -115,11 +116,18 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
if(isset($entry->gender))
$gender = $entry->gender;
if(isset($entry->generation) AND ($entry->generation > 0))
$generation = ++$entry->generation;
if(isset($entry->tags))
foreach($entry->tags as $tag)
$keywords = implode(", ", $tag);
poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $cid, $uid, $zcid);
// If you query a Friendica server for its profiles, the network has to be Friendica
if ($uid == 0)
$network = NETWORK_DFRN;
poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid, $uid, $zcid);
// Update the Friendica contacts. Diaspora is doing it via a message. (See include/diaspora.php)
if (($location != "") OR ($about != "") OR ($keywords != "") OR ($gender != ""))
@ -142,16 +150,51 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
}
function poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $cid = 0, $uid = 0, $zcid = 0) {
function poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid = 0, $uid = 0, $zcid = 0) {
$a = get_app();
// Generation:
// 0: No definition
// 1: Profiles on this server
// 2: Contacts of profiles on this server
// 3: Contacts of contacts of profiles on this server
// 4: ...
$gcid = "";
if ($profile_url == "")
return $gcid;
// Don't store the statusnet connector as network
// We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
if ($network == NETWORK_STATUSNET)
$network = "";
// The global contacts should contain the original picture, not the cached one
if (($generation != 1) AND stristr(normalise_link($profile_photo), normalise_link($a->get_baseurl()."/photo/")))
$profile_photo = "";
$r = q("SELECT `network` FROM `contact` WHERE `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
);
if(count($r))
$network = $r[0]["network"];
if (($network == "") OR ($network == NETWORK_OSTATUS)) {
$r = q("SELECT `network`, `url` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
dbesc($profile_url), dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
);
if(count($r)) {
$network = $r[0]["network"];
$profile_url = $r[0]["url"];
}
}
$x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($profile_url))
);
if(count($x))
if(count($x) AND ($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET))
$network = $x[0]["network"];
if (($network == "") OR ($name == "") OR ($profile_photo == "")) {
@ -160,6 +203,7 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
$data = probe_url($profile_url);
$network = $data["network"];
$name = $data["name"];
$profile_url = $data["url"];
$profile_photo = $data["photo"];
}
@ -173,10 +217,10 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
if (($name == "") OR ($profile_photo == ""))
return $gcid;
if (!in_array($network, array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_STATUSNET)))
if (!in_array($network, array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
return $gcid;
logger("profile-check URL: ".$profile_url." name: ".$name." avatar: ".$profile_photo, LOGGER_DEBUG);
logger("profile-check generation: ".$generation." Network: ".$network." URL: ".$profile_url." name: ".$name." avatar: ".$profile_photo, LOGGER_DEBUG);
if(count($x)) {
$gcid = $x[0]['id'];
@ -193,10 +237,13 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
if (($keywords == "") AND ($x[0]['keywords'] != ""))
$keywords = $x[0]['keywords'];
if (($generation == 0) AND ($x[0]['generation'] > 0))
$generation = $x[0]['generation'];
if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo || $x[0]['updated'] < $updated) {
q("update gcontact set `name` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s',
`updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s'
where `nurl` = '%s'",
q("UPDATE `gcontact` SET `name` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s',
`updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d
WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'",
dbesc($name),
dbesc($network),
dbesc($profile_photo),
@ -207,12 +254,14 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
dbesc($about),
dbesc($keywords),
dbesc($gender),
intval($generation),
intval($generation),
dbesc(normalise_link($profile_url))
);
}
} else {
q("insert into `gcontact` (`name`,`network`, `url`,`nurl`,`photo`,`connect`, `updated`, `location`, `about`, `keywords`, `gender`)
values ('%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s', '%s', '%s')",
q("INSERT INTO `gcontact` (`name`,`network`, `url`,`nurl`,`photo`,`connect`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`)
VALUES ('%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s', '%s', '%s', %d)",
dbesc($name),
dbesc($network),
dbesc($profile_url),
@ -223,7 +272,8 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
dbesc($location),
dbesc($about),
dbesc($keywords),
dbesc($gender)
dbesc($gender),
intval($generation)
);
$x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($profile_url))
@ -290,7 +340,65 @@ function sub_poco_from_share($share, $created, $cid, $uid) {
return;
logger("prepare poco_check for profile ".$profile, LOGGER_DEBUG);
poco_check($profile, "", "", "", "", "", "", "", "", $created, $cid, $uid);
poco_check($profile, "", "", "", "", "", "", "", "", $created, 3, $cid, $uid);
}
function poco_store($item) {
// Isn't it public?
if ($item['private'])
return;
// Or is it from a network where we don't store the global contacts?
if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_STATUSNET, "")))
return;
// Is it a global copy?
$store_gcontact = ($item["uid"] == 0);
// Is it a comment on a global copy?
if (!$store_gcontact AND ($item["uri"] != $item["parent-uri"])) {
$q = q("SELECT `id` FROM `item` WHERE `uri`='%s' AND `uid` = 0", $item["parent-uri"]);
$store_gcontact = count($q);
}
if (!$store_gcontact)
return;
// "3" means: We don't know this contact directly (Maybe a reshared item)
$generation = 3;
$network = "";
$profile_url = $item["author-link"];
// Is it a user from our server?
$q = q("SELECT `id` FROM `contact` WHERE `self` AND `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($item["author-link"])));
if (count($q)) {
logger("Our user (generation 1): ".$item["author-link"], LOGGER_DEBUG);
$generation = 1;
$network = NETWORK_DFRN;
} else { // Is it a contact from a user on our server?
$q = q("SELECT `network`, `url` FROM `contact` WHERE `uid` != 0 AND `network` != ''
AND (`nurl` = '%s' OR `alias` IN ('%s', '%s')) AND `network` != '%s' LIMIT 1",
dbesc(normalise_link($item["author-link"])),
dbesc(normalise_link($item["author-link"])),
dbesc($item["author-link"]),
dbesc(NETWORK_STATUSNET));
if (count($q)) {
$generation = 2;
$network = $q[0]["network"];
$profile_url = $q[0]["url"];
logger("Known contact (generation 2): ".$profile_url, LOGGER_DEBUG);
}
}
if ($generation == 3)
logger("Unknown contact (generation 3): ".$item["author-link"], LOGGER_DEBUG);
poco_check($profile_url, $item["author-name"], $network, $item["author-avatar"], "", "", "", "", "", $item["received"], $generation, $item["contact-id"], $item["uid"]);
// Maybe its a body with a shared item? Then extract a global contact from it.
poco_contact_from_body($item["body"], $item["received"], $item["contact-id"], $item["uid"]);
}
function count_common_friends($uid,$cid) {

View file

@ -1,5 +1,5 @@
<?php
function create_tags_from_item($itemid, $dontcache = false) {
function create_tags_from_item($itemid) {
global $a;
$profile_base = $a->get_baseurl();
@ -9,7 +9,7 @@ function create_tags_from_item($itemid, $dontcache = false) {
$searchpath = $a->get_baseurl()."/search?tag=";
$messages = q("SELECT `guid`, `uid`, `id`, `edited`, `deleted`, `title`, `body`, `tag`, `parent` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
$messages = q("SELECT `guid`, `uid`, `id`, `edited`, `deleted`, `created`, `received`, `title`, `body`, `tag`, `parent` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
if (!$messages)
return;
@ -26,18 +26,6 @@ function create_tags_from_item($itemid, $dontcache = false) {
if ($message["deleted"])
return;
if (!$dontcache) {
$cachefile = get_cachefile(urlencode($message["guid"])."-".hash("md5", $message['body']));
if (($cachefile != '') AND !file_exists($cachefile)) {
$s = prepare_text($message['body']);
$stamp1 = microtime(true);
file_put_contents($cachefile, $s);
$a->save_timestamp($stamp1, "file");
logger('create_tags_from_item: put item '.$message["id"].' into cachefile '.$cachefile);
}
}
$taglist = explode(",", $message["tag"]);
$tags = "";
@ -49,6 +37,9 @@ function create_tags_from_item($itemid, $dontcache = false) {
$data = " ".$message["title"]." ".$message["body"]." ".$tags." ";
// ignore anything in a code block
$data = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$data);
$tags = array();
$pattern = "/\W\#([^\[].*?)[\s'\".,:;\?!\[\]\/]/ism";
@ -81,8 +72,22 @@ function create_tags_from_item($itemid, $dontcache = false) {
$term = $tag;
}
$r = q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`) VALUES (%d, %d, %d, %d, '%s', '%s')",
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval($type), dbesc($term), dbesc($link));
if ($message["uid"] == 0) {
$global = true;
q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
} else {
$isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
$global = (count($isglobal) > 0);
}
$r = q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`, `guid`, `created`, `received`, `global`)
VALUES (%d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d)",
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval($type), dbesc($term),
dbesc($link), dbesc($message["guid"]), dbesc($message["created"]), dbesc($message["received"]), intval($global));
// Search for mentions
if ((substr($tag, 0, 1) == '@') AND (strpos($link, $profile_base_friendica) OR strpos($link, $profile_base_diaspora))) {
@ -108,10 +113,39 @@ function create_tags_from_itemuri($itemuri, $uid) {
}
function update_items() {
//$messages = q("SELECT `id` FROM `item` where tag !='' ORDER BY `created` DESC limit 10");
$messages = q("SELECT `id` FROM `item` where tag !=''");
global $db;
foreach ($messages as $message)
create_tags_from_item($message["id"]);
$messages = $db->q("SELECT `oid`,`item`.`guid`, `item`.`created`, `item`.`received` FROM `term` INNER JOIN `item` ON `item`.`id`=`term`.`oid` WHERE `term`.`otype` = 1 AND `term`.`guid` = ''", true);
logger("fetched messages: ".count($messages));
while ($message = $db->qfetch()) {
if ($message["uid"] == 0) {
$global = true;
q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
} else {
$isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
$global = (count($isglobal) > 0);
}
q("UPDATE `term` SET `guid` = '%s', `created` = '%s', `received` = '%s', `global` = %d WHERE `otype` = %d AND `oid` = %d",
dbesc($message["guid"]), dbesc($message["created"]), dbesc($message["received"]),
intval($global), intval(TERM_OBJ_POST), intval($message["oid"]));
}
$db->qclose();
$messages = $db->q("SELECT `guid` FROM `item` WHERE `uid` = 0", true);
logger("fetched messages: ".count($messages));
while ($message = $db->qfetch()) {
q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($message["guid"]));
}
$db->qclose();
}
?>

22
include/tagupdate.php Normal file
View file

@ -0,0 +1,22 @@
<?php
require_once("boot.php");
require_once("include/tags.php");
global $a, $db;
if(is_null($a))
$a = new App;
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);
}
load_config('config');
load_config('system');
update_items();
killme();
?>

View file

@ -270,7 +270,7 @@ if(! function_exists('paginate_data')) {
* @return Array data for pagination template
*/
function paginate_data(&$a, $count=null) {
$stripped = preg_replace('/(&page=[0-9]*)/','',$a->query_string);
$stripped = preg_replace('/([&?]page=[0-9]*)/','',$a->query_string);
$stripped = str_replace('q=','',$stripped);
$stripped = trim($stripped,'/');
@ -385,6 +385,18 @@ function alt_pager(&$a, $i) {
}}
if(! function_exists('scroll_loader')) {
/**
* Loader for infinite scrolling
* @return string html for loader
*/
function scroll_loader() {
$tpl = get_markup_template("scroll_loader.tpl");
return replace_macros($tpl, array(
'wait' => t('Loading more entries...'),
'end' => t('The end')
));
}}
if(! function_exists('expand_acl')) {
/**
@ -740,6 +752,9 @@ if(! function_exists('get_tags')) {
function get_tags($s) {
$ret = array();
// Convert hashtag links to hashtags
$s = preg_replace("/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism", "#$2", $s);
// ignore anything in a code block
$s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
@ -1110,7 +1125,8 @@ function smilies($s, $sample = false) {
':like',
':dislike',
'~friendica',
'red#'
'red#',
'red#matrix'
);
@ -1148,7 +1164,8 @@ function smilies($s, $sample = false) {
'<img class="smiley" src="' . $a->get_baseurl() . '/images/like.gif" alt=":like" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/dislike.gif" alt=":dislike" />',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . $a->get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>',
'<a href="http://redmatrix.me/">red <img class="smiley" src="' . $a->get_baseurl() . '/images/rhash-16.png" alt="red" /></a>'
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . $a->get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . $a->get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>'
);
$params = array('texts' => $texts, 'icons' => $icons, 'string' => $s);
@ -1279,6 +1296,28 @@ function redir_private_images($a, &$item) {
}}
function put_item_in_cache(&$item, $update = false) {
if (($item["rendered-hash"] != hash("md5", $item["body"])) OR ($item["rendered-hash"] == "") OR
($item["rendered-html"] == "") OR get_config("system", "ignore_cache")) {
// The function "redir_private_images" changes the body.
// I'm not sure if we should store it permanently, so we save the old value.
$body = $item["body"];
$a = get_app();
redir_private_images($a, $item);
$item["rendered-html"] = prepare_text($item["body"]);
$item["rendered-hash"] = hash("md5", $item["body"]);
$item["body"] = $body;
if ($update AND ($item["id"] != 0)) {
q("UPDATE `item` SET `rendered-html` = '%s', `rendered-hash` = '%s' WHERE `id` = %d",
dbesc($item["rendered-html"]), dbesc($item["rendered-hash"]), intval($item["id"]));
}
}
}
// Given an item array, convert the body element from bbcode to html and add smilie icons.
// If attach is true, also add icons for item attachments
@ -1330,28 +1369,8 @@ function prepare_body(&$item,$attach = false, $preview = false) {
$item['hashtags'] = $hashtags;
$item['mentions'] = $mentions;
$cachefile = get_cachefile(urlencode($item["guid"])."-".hash("md5", $item['body']));
if (($cachefile != '')) {
if (file_exists($cachefile)) {
$stamp1 = microtime(true);
$s = file_get_contents($cachefile);
$a->save_timestamp($stamp1, "file");
} else {
redir_private_images($a, $item);
$s = prepare_text($item['body']);
$stamp1 = microtime(true);
file_put_contents($cachefile, $s);
$a->save_timestamp($stamp1, "file");
logger('prepare_body: put item '.$item["id"].' into cachefile '.$cachefile);
}
} else {
redir_private_images($a, $item);
$s = prepare_text($item['body']);
}
put_item_in_cache($item, true);
$s = $item["rendered-html"];
require_once("mod/proxy.php");
$s = proxy_parse_html($s);

View file

@ -19,10 +19,6 @@ function add_thread($itemid, $onlyshadow = false) {
logger("add_thread: Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
}
// Store a shadow copy of public items for displaying a global community page?
if (!get_config('system', 'global_community'))
return;
// is it already a copy?
if (($itemid == 0) OR ($item['uid'] == 0))
return;
@ -66,9 +62,11 @@ function add_thread($itemid, $onlyshadow = false) {
if (!$r) {
// Preparing public shadow (removing user specific data)
require_once("include/items.php");
require_once("include/Contact.php");
unset($item[0]['id']);
$item[0]['uid'] = 0;
$item[0]['contact-id'] = 0;
$item[0]['contact-id'] = get_contact($item[0]['author-link'], 0);
$public_shadow = item_store($item[0], false, false, true);
logger("add_thread: Stored public shadow for post ".$itemid." under id ".$public_shadow, LOGGER_DEBUG);
@ -76,6 +74,35 @@ function add_thread($itemid, $onlyshadow = false) {
}
}
function add_shadow_entry($item) {
// Is this a shadow entry?
if ($item['uid'] == 0)
return;
// Is there a shadow parent?
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['parent-uri']));
if (!count($r))
return;
// Is there already a shadow entry?
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['uri']));
if (count($r))
return;
// Preparing public shadow (removing user specific data)
require_once("include/items.php");
require_once("include/Contact.php");
unset($item['id']);
$item['uid'] = 0;
$item['contact-id'] = get_contact($item['author-link'], 0);
$public_shadow = item_store($item, false, false, true);
logger("Stored public shadow for comment ".$item['uri']." under id ".$public_shadow, LOGGER_DEBUG);
}
function update_thread_uri($itemuri, $uid) {
$messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));

View file

@ -115,7 +115,6 @@ if((x($_GET,'zrl')) && (!$install && !$maintenance)) {
*
* What we really need to do is output the raw headers ourselves so we can keep them separate.
*
*/
// header('Link: <' . $a->get_baseurl() . '/amcd>; rel="acct-mgmt";');
@ -498,30 +497,38 @@ $(document).ready(function() {
});
function loadcontent() {
//$("div.loader").show();
if (lockLoadContent) return;
lockLoadContent = true;
$("#scroll-loader").fadeIn('normal');
num+=1;
console.log('Loading page ' + num);
$.get('/network?mode=raw$reload_uri&page=' + num, function(data) {
$(data).insertBefore('#conversation-end');
$("#scroll-loader").hide();
if ($(data).length > 0) {
$(data).insertBefore('#conversation-end');
lockLoadContent = false;
} else {
$("#scroll-end").fadeIn('normal');
}
});
//$("div.loader").fadeOut('normal');
}
var num = $pageno;
var lockLoadContent = false;
$(window).scroll(function(e){
if ($(document).height() != $(window).height()) {
// First method that is expected to work - but has problems with Chrome
if ($(window).scrollTop() == $(document).height() - $(window).height())
if ($(window).scrollTop() > ($(document).height() - $(window).height() * 1.5))
loadcontent();
} else {
// This method works with Chrome - but seems to be much slower in Firefox
if ($(window).scrollTop() > (($("section").height() + $("header").height() + $("footer").height()) - $(window).height()))
if ($(window).scrollTop() > (($("section").height() + $("header").height() + $("footer").height()) - $(window).height() * 1.5))
loadcontent();
}
});

8
js/jquery.js vendored

File diff suppressed because one or more lines are too long

View file

@ -210,7 +210,7 @@
});
eSysmsg.children("info").each(function(){
text = $(this).text();
$.jGrowl(text, { sticky: false, theme: 'info', life: 10000 });
$.jGrowl(text, { sticky: false, theme: 'info', life: 5000 });
});
});
@ -290,7 +290,7 @@
if(livetime) {
clearTimeout(livetime);
}
livetime = setTimeout(liveUpdate, 10000);
livetime = setTimeout(liveUpdate, 5000);
return;
}
if(livetime != null)

11
library/Mobile_Detect/.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
vendor/
nbproject/
/*.buildpath
/*.project
/.settings
/error.log
/export/nicejson
.idea/
*.iml
/coverage
/phpunit.phar

3
library/Mobile_Detect/.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "export/nicejson"]
path = export/nicejson
url = https://github.com/GerHobbelt/nicejson-php.git

View file

@ -0,0 +1,24 @@
<?php
use Symfony\CS\FixerInterface;
$finder = Symfony\CS\Finder\DefaultFinder::create()
->notName('LICENSE')
->notName('README.md')
->notName('.php_cs')
->notName('composer.*')
->notName('phpunit.xml*')
->notName('*.phar')
->exclude('vendor')
->exclude('examples')
->exclude('Symfony/CS/Tests/Fixer')
->notName('ElseifFixer.php')
->exclude('data')
->in(__DIR__)
;
return Symfony\CS\Config\Config::create()
->finder($finder)
;

View file

@ -0,0 +1,17 @@
language: php
php:
- "5.2"
- "5.3"
- "5.4"
- "5.5"
- "5.6"
branches:
only:
- devel
script:
- phpunit -v -c tests/phpunit.xml
notifications:
email: false

View file

@ -0,0 +1,48 @@
MIT License
Copyright (c) <2011-2014> <Serban Ghita> <serbanghita@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Developers Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,219 @@
[![Build Status](https://travis-ci.org/serbanghita/Mobile-Detect.svg?branch=devel)](https://travis-ci.org/serbanghita/Mobile-Detect) [![Latest Stable Version](https://poser.pugx.org/mobiledetect/mobiledetectlib/v/stable.svg)](https://packagist.org/packages/mobiledetect/mobiledetectlib) [![Total Downloads](https://poser.pugx.org/mobiledetect/mobiledetectlib/downloads.svg)](https://packagist.org/packages/mobiledetect/mobiledetectlib) [![Daily Downloads](https://poser.pugx.org/mobiledetect/mobiledetectlib/d/daily.png)](https://packagist.org/packages/mobiledetect/mobiledetectlib) [![License](https://poser.pugx.org/mobiledetect/mobiledetectlib/license.svg)](https://packagist.org/packages/mobiledetect/mobiledetectlib)
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/serbanghita/Mobile-Detect?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
![Mobile Detect](http://demo.mobiledetect.net/logo-github.png)
> Motto: "Every business should have a mobile detection script to detect mobile readers."
<i>Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets).
It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.</i>
> We're commited to make Mobile_Detect the best open-source mobile detection resource and this is why before each release we're running [unit tests](./tests), we also research and update the detection rules on <b>daily</b> and <b>weekly</b> basis.
Your website's _content strategy_ is important! You need a complete toolkit to deliver an experience that is _optimized_, _fast_ and _relevant_ to your users. Mobile_Detect class is a [server-side detection](http://www.w3.org/TR/mwabp/#bp-devcap-detection) tool that can help you with your RWD strategy, it is not a replacement for CSS3 media queries or other forms of client-side feature detection.
##### This month updates
First of all a **BIG THANK YOU** to our growing community for your continuous support and for all the feedback received! I'm still working my way with the current issues and all the emails.
Nick is almost done with all the code for the upcoming `3.0.0` so that I only have to integrate the new parsing engine. We will release minor `2.8.xx` versions until a feature freeze where we will switch to the new branch. You will all be announced before this and hopefully we can make the transition smooth for everyone.
<a href="http://trycatch.us/"><img align="left" src="http://assets.mobiledetect.net/img/try_catch_logo_80px.jpg" hspace="20"></a> Last but not least, special thanks for supporting us to our friends from [TryCatch.us](http://trycatch.us/) who _are set to carefully curate the most talented developers in Europe_!
Thank you all and we're excited for the new release!
##### Download and demo
|Download|Docs|Examples|
|-------------|-------------|-------------|
|[Go to releases](../../tags)|[Become a contributor](../../wiki/Become-a-contributor)|[Code examples](../../wiki/Code-examples)
|[Mobile_Detect.php](./Mobile_Detect.php)|[History](../../wiki/History)|[:iphone: Live demo!](http://is.gd/mobiletest)
|[Composer package](https://packagist.org/packages/mobiledetect/mobiledetectlib)|
##### Help
|Pledgie|Paypal|
|-------|------|
|[Donate :+1:](http://pledgie.com/campaigns/21856)|[Donate :beer:](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mobiledetectlib%40gmail%2ecom&lc=US&item_name=Mobile%20Detect&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted)|
I'm currently paying for hosting and spend a lot of my family time to maintain the project and planning the future releases.
I would highly appreciate any money donations that will keep the research going.
Special thanks to the community :+1: for donations, [BrowserStack](http://browserstack.com) - for providing access to their great platform, [Zend](http://zend.com) - for donating licenses, [Dragos Gavrila](https://twitter.com/grafician) who contributed with the logo.
##### 3rd party modules / [Submit new](../../issues/new?title=New%203rd%20party%20module&body=Name, Link and Description of the module.)
:point_right: Keep `Mobile_Detect.php` class in a separate `module` and do NOT include it in your script core because of the high frequency of updates.
:point_right: When including the class into you `web application` or `module` always use `include_once '../path/to/Mobile_Detect.php` to prevent conflicts.
<table>
<tr>
<td>Varnish Cache</td>
<td>
<p><a href="https://github.com/willemk/varnish-mobiletranslate">Varnish Mobile Detect</a> - Drop-in varnish solution to mobile user detection based on the Mobile-Detect library. Made by <a href="https://github.com/willemk">willemk</a></p>
<p><a href="https://github.com/carlosabalde/mobiledetect2vcl">mobiledetect2vcl</a> - Python script to transform the Mobile Detect JSON database into an UA-based mobile detection VCL subroutine easily integrable in any Varnish Cache configuration. Made by <a href="https://github.com/carlosabalde">Carlos Abalde</a></p>
</td>
</tr>
<tr>
<td>WordPress</td>
<td>
<p><a href="http://wordpress.org/extend/plugins/wp-mobile-detect/">WordPress Mobile Detect</a> - Gives you the ability to wrap that infographic in a `[notdevice][/notdevice]` shortcode so at the server level <code>WordPress</code> will decide to show that content only if the user is NOT on a phone or tablet. Made by <a href="http://profiles.wordpress.org/professor44/">Jesse Friedman</a>.</p>
<p><a href="http://wordpress.org/plugins/mobble/">mobble</a> - provides mobile related conditional functions for your site. e.g. is_iphone(), is_mobile() and is_tablet(). Made by Scott Evans.</p>
<p><a href="https://github.com/iamspacehead/responsage">WordPress Responsage</a> - A small <code>WordPress</code> theme plugin that allows you to make your images responsive. Made by <a href="https://github.com/iamspacehead">Adrian Ciaschetti</a>.</p>
<p><a href="http://wordpress.org/plugins/social-popup/">Social PopUP</a> - This plugin will display a popup or splash screen when a new user visit your site showing a Google+, Twitter and Facebook follow links. It uses Mobile_Detect to detect mobile devices.</p>
</td>
</tr>
<tr>
<td>Drupal</td>
<td>
<p><a href="http://drupal.org/project/mobile_switch">Drupal Mobile Switch</a> - The Mobile Switch <code>Drupal</code> module provides a automatic theme switch functionality for mobile devices,
detected by Browscap or Mobile Detect. Made by <a href="http://drupal.org/user/45267">Siegfried Neumann</a>.</p>
<p><a href="http://drupal.org/project/context_mobile_detect">Drupal Context Mobile Detect</a> - This is a <code>Drupal context</code> module which integrates Context and PHP Mobile Detect library.
Created by <a href="http://drupal.org/user/432492">Artem Shymko</a>.</p>
<p><a href="http://drupal.org/project/mobile_detect">Drupal Mobile Detect</a> - Lightweight mobile detect module for <code>Drupal</code> created by <a href="http://drupal.org/user/325244">Matthew Donadio</a></p>
</td>
</tr>
<tr>
<td>Joomla</td>
<td><p><a href="http://www.yagendoo.com/en/blog/free-mobile-detection-plugin-for-joomla.html">yagendoo Joomla! Mobile Detection Plugin</a> - Lightweight PHP plugin for Joomla! that detects a mobile browser using the Mobile Detect class. Made by <a href="http://www.yagendoo.com/">yagendoo media</a>.</p></td>
</tr>
<tr>
<td>Magento</td>
<td><p><a href="http://www.magentocommerce.com/magento-connect/catalog/product/view/id/16835/">Magento</a> - This <code>Magento helper</code> from Optimise Web enables the use of all functions provided by MobileDetect.net.
Made by <a href="http://www.kathirvel.com">Kathir Vel</a>.</p></td>
</tr>
<tr>
<td>PrestaShop</td>
<td><p><a href="http://www.prestashop.com/">PrestaShop</a> is a free, secure and open source shopping cart platform. Mobile_Detect is included in the default package since 1.5.x.</p></td>
</tr>
<tr>
<td>Zend Framework</td>
<td>
<p><a href="https://github.com/neilime/zf2-mobile-detect.git">ZF2 Mobile-Detect</a> - Zend Framework 2 module that provides Mobile-Detect features (Mobile_Detect class as a service, helper for views and plugin controllers). Made by <a href="https://github.com/neilime">neilime</a></p>
<p><a href="https://github.com/nikolaposa/MobileDetectModule">ZF2 MobileDetectModule</a> - Facilitates integration of a PHP MobileDetect class with some ZF2-based application. Has similar idea like the existing ZF2 Mobile-Detect module, but differs in initialization and provision routine of the actual Mobile_Detect class. Appropriate view helper and controller plugin also have different conceptions. Made by <a href="https://github.com/nikolaposa">Nikola Posa</a></p>
</td>
</tr>
<tr>
<td>Symfony</td>
<td><p><a href="https://github.com/suncat2000/MobileDetectBundle">Symfony2 Mobile Detect Bundle</a> - The bundle for detecting mobile devices, manage mobile view and redirect to the mobile and tablet version.
Made by <a href="https://github.com/suncat2000">Nikolay Ivlev</a>.</p>
<p><a href="https://github.com/jbinfo/MobileDetectServiceProvider">Silex Mobile Detect Service Provider</a> - <code>Silex</code> service provider to interact with Mobile detect class methods. Made by <a href="https://github.com/jbinfo">Lhassan Baazzi</a>.</p>
</td>
</tr>
<tr>
<td>Laravel</td>
<td>
<p><a href="https://github.com/jenssegers/Laravel-Agent">Laravel-Agent</a> a user agent class for Laravel, based on Mobile Detect with some additional functionality. Made by <a href="https://github.com/jenssegers">Jens Segers</a>.</p>
<p><a href="https://github.com/hisorange/browser-detect">BrowserDetect</a> is a browser &amp; mobile detection package, collects and wrap together the best user-agent identifiers for Laravel. Created by <a href="https://github.com/hisorange">Varga Zsolt</a>.</p>
</td>
</tr>
<tr>
<td>ExpressionEngine</td>
<td><p><a href="https://github.com/garethtdavies/detect-mobile">EE2 Detect Mobile</a> - Lightweight PHP plugin for <code>EE2</code> that detects a mobile browser using the Mobile Detect class. Made by <a href="https://github.com/garethtdavies">Gareth Davies</a>.</p></td>
</tr>
<tr>
<td>Yii Framework</td>
<td><p><a href="https://github.com/iamsalnikov/MobileDetect">Yii Extension</a> - Mobile detect plugin for Yii framework. Made by <a href="https://github.com/iamsalnikov">Alexey Salnikov</a>.</p></td>
</tr>
<tr>
<td>CakePHP</td>
<td><p><a href="https://github.com/chronon/CakePHP-MobileDetectComponent-Plugin">CakePHP MobileDetect</a> - <code>plugin</code> component for <code>CakePHP</code> 2.x. Made by <a href="https://github.com/chronon">Gregory Gaskill</a></p></td>
</tr>
<tr>
<td>FuelPHP</td>
<td><a href="https://github.com/rob-bar/special_agent">Special Agent</a> is a FuelPHP package which uses php-mobile-detect to determine whether a device is mobile or not.
It overrides the Fuelphp Agent class its methods. Made by <a href="https://github.com/rob-bar">Robbie Bardjin</a>.</td>
</tr>
<tr>
<td>Typo3</td>
<td><a href="http://docs.typo3.org/typo3cms/extensions/px_mobiledetect/1.0.2/">px_mobiledetect</a> is an extension that helps to detect visitor's mobile device class (if thats tablet or mobile device like smartphone). Made by Alexander Tretyak.</td>
</tr>
<tr>
<td>Statamic</td>
<td><p><a href="https://github.com/sergeifilippov/statamic-mobile-detect">Statamic CMS Mobile Detect</a> - <code>plugin</code>. Made by <a href="https://github.com/haikulab/statamic-mobile-detect">Sergei Filippov of Haiku Lab</a>.</p></td>
</tr>
<tr>
<td>Kohana</td>
<td><p><a href="https://github.com/madeinnordeste/kohana-mobile-detect">Kohana Mobile Detect</a> - an example of implementation of <code>Mobile_Detect</code> class with Kohana framework. Written by <a href="https://github.com/madeinnordeste">Luiz Alberto S. Ribeiro</a>.</p></td>
</tr>
<tr>
<td>mobile-detect.js</td>
<td><p>A <a href="https://github.com/hgoebl/mobile-detect.js">JavaScript port</a> of Mobile-Detect class. Made by <a href="https://github.com/hgoebl">Heinrich Goebl</a></p></td>
</tr>
<tr>
<td>Perl</td>
<td><p><a href="http://www.buzzerstar.com/development/">MobileDetect.pm</a> - <code>Perl module</code> for Mobile Detect. Made by <a href="http://www.buzzerstar.com/">Sebastian Enger</a>.</p></td>
</tr>
<tr>
<td>python</td>
<td><p><a href="http://pypi.python.org/pypi/pymobiledetect">pymobiledetect</a> - Mobile detect <code>python package</code>. Made by Bas van Oostveen.</p></td>
</tr>
<tr>
<td>Ruby</td>
<td><p><a href="https://github.com/ktaragorn/mobile_detect">mobile_detect.rb</a> - A <code>Ruby gem</code> using the JSON data exposed by the php project and implementing a basic subset of the API (as much as can be done by the exposed data). Made by <a href="https://github.com/ktaragorn">Karthik T</a>.</p></td>
</tr>
<tr>
<td>GoMobileDetect</td>
<td><p><a href="https://github.com/Shaked/gomobiledetect">GoMobileDetect</a> - Go port of Mobile Detect class. Made by <a href="https://github.com/Shaked">Shaked</a>.</p></td>
</tr>
<tr>
<td>MemHT</td>
<td><p><a href="http://www.memht.com/">MemHT</a> is a Free PHP CMS and Blog that permit the creation and the management online of websites with few and easy steps. Has the class included in the core.</p></td>
</tr>
<tr>
<td>concrete5</td>
<td><p><a href="https://www.concrete5.org/">concrete5</a> is a CMS that is free and open source. The library is included in the core.</p></td>
</tr>
<tr>
<td>engine7</td>
<td><p><a href="https://github.com/gchiappe/exengine7">ExEngine 7</a> PHP Open Source Framework. The Mobile_Detect class is included in the engine.</p></td>
</tr>
<tr>
<td>Zikula</td>
<td><p><a href="http://zikula.org/">Zikula</a> is a free and open-source Content Management Framework, which allows you to run impressive websites and build powerful online applications. The core uses Mobile-Detect to switch to a special Mobile theme, using jQueryMobile</p></td>
</tr>
<tr>
<td>UserAgentInfo</td>
<td><p><a href="https://github.com/quentin389/UserAgentInfo">UserAgentInfo</a> is a PHP class for parsing user agent strings (HTTP_USER_AGENT). Includes mobile checks, bot checks, browser types/versions and more.
Based on browscap, Mobile_Detect and ua-parser. Created for high traffic websites and fast batch processing. Made by <a href="https://github.com/quentin389">quentin389</a></p></td>
</tr>
<tr>
<td>Craft CMS</td>
<td><p><a href="https://github.com/lewisjenkins/craft-lj-mobiledetect">LJ Mobile Detect</a> is a simple implementation of Mobile Detect for Craft CMS. Made by <a href="https://github.com/lewisjenkins">Lewis Jenkins</a></p></td>
</tr>
</table>

View file

@ -0,0 +1,30 @@
{
"name": "mobiledetect/mobiledetectlib",
"type": "library",
"description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
"keywords": ["mobile", "mobile detect", "mobile detector", "php mobile detect", "detect mobile devices"],
"homepage": "https://github.com/serbanghita/Mobile-Detect",
"license": "MIT",
"authors": [
{
"name": "Serban Ghita",
"email": "serbanghita@gmail.com",
"homepage": "http://mobiledetect.net",
"role": "Developer"
}
],
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"phpunit/phpunit": "*",
"johnkary/phpunit-speedtrap": "~1.0@dev",
"codeclimate/php-test-reporter": "dev-master"
},
"autoload": {
"classmap": ["Mobile_Detect.php"],
"psr-0": {
"Detection": "namespaced/"
}
}
}

View file

@ -0,0 +1,22 @@
<?php
/**
* Little piece of PHP to make Mobile_Detect auto-loadable in PSR-0 compatible PHP autoloaders like
* the Symfony Universal ClassLoader by Fabien Potencier. Since PSR-0 handles an underscore in
* classnames (on the filesystem) as a slash, "Mobile_Detect.php" autoloaders will try to convert
* the classname and path to "Mobile\Detect.php". This script will ensure autoloading with:
* - Namespace: Detection
* - Classname: MobileDetect
* - Namespased: \Detection\MobileDetect
* - Autoload path: ./namespaced
* - Converted path: ./namespaced/Detection/MobileDetect.php
*
* Don't forget to use MobileDetect (instead of Mobile_Detect) as class in code when autoloading.
*
* Thanks to @WietseWind.
* For details please check: https://github.com/serbanghita/Mobile-Detect/pull/120
*/
namespace Detection;
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Mobile_Detect.php';
class MobileDetect extends \Mobile_Detect {}

View file

@ -293,8 +293,8 @@ class OAuthRequest {
}
// fix for friendica redirect system
$http_url = substr($http_url, 0, strpos($http_url,$parameters['q'])+strlen($parameters['q']));
unset( $parameters['q'] );
$http_url = substr($http_url, 0, strpos($http_url,$parameters['pagename'])+strlen($parameters['pagename']));
unset( $parameters['pagename'] );
//echo "<pre>".__function__."\n"; var_dump($http_method, $http_url, $parameters, $_SERVER['REQUEST_URI']); killme();
return new OAuthRequest($http_method, $http_url, $parameters);

3
library/html-to-markdown/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
~*
vendor
composer.lock

View file

@ -0,0 +1,6 @@
language: php
php:
- "5.5"
- "5.4"
- "5.3"
script: phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View file

@ -0,0 +1,598 @@
<?php
/**
* Class HTML_To_Markdown
*
* A helper class to convert HTML to Markdown.
*
* @version 2.2.1
* @author Nick Cernis <nick@cern.is>
* @link https://github.com/nickcernis/html2markdown/ Latest version on GitHub.
* @link http://twitter.com/nickcernis Nick on twitter.
* @license http://www.opensource.org/licenses/mit-license.php MIT
*/
class HTML_To_Markdown
{
/**
* @var DOMDocument The root of the document tree that holds our HTML.
*/
private $document;
/**
* @var string|boolean The Markdown version of the original HTML, or false if conversion failed
*/
private $output;
/**
* @var array Class-wide options users can override.
*/
private $options = array(
'header_style' => 'setext', // Set to "atx" to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // Set to '__' if you prefer the underlined style
'italic_style' => '*', // Set to '_' if you prefer the underlined style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: "meta style script"
);
/**
* Constructor
*
* Set up a new DOMDocument from the supplied HTML, convert it to Markdown, and store it in $this->$output.
*
* @param string $html The HTML to convert to Markdown.
* @param array $overrides [optional] List of style and error display overrides.
*/
public function __construct($html = null, $overrides = null)
{
if ($overrides)
$this->options = array_merge($this->options, $overrides);
if ($html)
$this->convert($html);
}
/**
* Setter for conversion options
*
* @param $name
* @param $value
*/
public function set_option($name, $value)
{
$this->options[$name] = $value;
}
/**
* Convert
*
* Loads HTML and passes to get_markdown()
*
* @param $html
* @return string The Markdown version of the html
*/
public function convert($html)
{
$html = preg_replace('~>\s+<~', '><', $html); // Strip white space between tags to prevent creation of empty #text nodes
$this->document = new DOMDocument();
if ($this->options['suppress_errors'])
libxml_use_internal_errors(true); // Suppress conversion errors (from http://bit.ly/pCCRSX )
$this->document->loadHTML('<?xml encoding="UTF-8">' . $html); // Hack to load utf-8 HTML (from http://bit.ly/pVDyCt )
$this->document->encoding = 'UTF-8';
if ($this->options['suppress_errors'])
libxml_clear_errors();
return $this->get_markdown($html);
}
/**
* Is Child Of?
*
* Is the node a child of the given parent tag?
*
* @param $parent_name string|array The name of the parent node(s) to search for e.g. 'code' or array('pre', 'code')
* @param $node
* @return bool
*/
private static function is_child_of($parent_name, $node)
{
for ($p = $node->parentNode; $p != false; $p = $p->parentNode) {
if (is_null($p))
return false;
if ( is_array($parent_name) && in_array($p->nodeName, $parent_name) )
return true;
if ($p->nodeName == $parent_name)
return true;
}
return false;
}
/**
* Convert Children
*
* Recursive function to drill into the DOM and convert each node into Markdown from the inside out.
*
* Finds children of each node and convert those to #text nodes containing their Markdown equivalent,
* starting with the innermost element and working up to the outermost element.
*
* @param $node
*/
private function convert_children($node)
{
// Don't convert HTML code inside <code> and <pre> blocks to Markdown - that should stay as HTML
if (self::is_child_of(array('pre', 'code'), $node))
return;
// If the node has children, convert those to Markdown first
if ($node->hasChildNodes()) {
$length = $node->childNodes->length;
for ($i = 0; $i < $length; $i++) {
$child = $node->childNodes->item($i);
$this->convert_children($child);
}
}
// Now that child nodes have been converted, convert the original node
$markdown = $this->convert_to_markdown($node);
// Create a DOM text node containing the Markdown equivalent of the original node
$markdown_node = $this->document->createTextNode($markdown);
// Replace the old $node e.g. "<h3>Title</h3>" with the new $markdown_node e.g. "### Title"
$node->parentNode->replaceChild($markdown_node, $node);
}
/**
* Get Markdown
*
* Sends the body node to convert_children() to change inner nodes to Markdown #text nodes, then saves and
* returns the resulting converted document as a string in Markdown format.
*
* @return string|boolean The converted HTML as Markdown, or false if conversion failed
*/
private function get_markdown()
{
// Work on the entire DOM tree (including head and body)
$input = $this->document->getElementsByTagName("html")->item(0);
if (!$input)
return false;
// Convert all children of this root element. The DOMDocument stored in $this->doc will
// then consist of #text nodes, each containing a Markdown version of the original node
// that it replaced.
$this->convert_children($input);
// Sanitize and return the body contents as a string.
$markdown = $this->document->saveHTML(); // stores the DOMDocument as a string
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8'); // Double decode to cover cases like &amp;nbsp; http://www.php.net/manual/en/function.htmlentities.php#99984
$markdown = preg_replace("/<!DOCTYPE [^>]+>/", "", $markdown); // Strip doctype declaration
$unwanted = array('<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '<?xml encoding="UTF-8">', '&#xD;');
$markdown = str_replace($unwanted, '', $markdown); // Strip unwanted tags
$markdown = trim($markdown, "\n\r\0\x0B");
$this->output = $markdown;
return $markdown;
}
/**
* Convert to Markdown
*
* Converts an individual node into a #text node containing a string of its Markdown equivalent.
*
* Example: An <h3> node with text content of "Title" becomes a text node with content of "### Title"
*
* @param $node
* @return string The converted HTML as Markdown
*/
private function convert_to_markdown($node)
{
$tag = $node->nodeName; // the type of element, e.g. h1
$value = $node->nodeValue; // the value of that element, e.g. The Title
// Strip nodes named in remove_nodes
$tags_to_remove = explode(' ', $this->options['remove_nodes']);
if ( in_array($tag, $tags_to_remove) )
return false;
switch ($tag) {
case "p":
$markdown = (trim($value)) ? rtrim($value) . PHP_EOL . PHP_EOL : '';
break;
case "pre":
$markdown = PHP_EOL . $this->convert_code($node) . PHP_EOL;
break;
case "h1":
case "h2":
$markdown = $this->convert_header($tag, $node);
break;
case "h3":
$markdown = "### " . $value . PHP_EOL . PHP_EOL;
break;
case "h4":
$markdown = "#### " . $value . PHP_EOL . PHP_EOL;
break;
case "h5":
$markdown = "##### " . $value . PHP_EOL . PHP_EOL;
break;
case "h6":
$markdown = "###### " . $value . PHP_EOL . PHP_EOL;
break;
case "em":
case "i":
case "strong":
case "b":
$markdown = $this->convert_emphasis($tag, $value);
break;
case "hr":
$markdown = "- - - - - -" . PHP_EOL . PHP_EOL;
break;
case "br":
$markdown = " " . PHP_EOL;
break;
case "blockquote":
$markdown = $this->convert_blockquote($node);
break;
case "code":
$markdown = $this->convert_code($node);
break;
case "ol":
case "ul":
$markdown = $value . PHP_EOL;
break;
case "li":
$markdown = $this->convert_list($node);
break;
case "img":
$markdown = $this->convert_image($node);
break;
case "a":
$markdown = $this->convert_anchor($node);
break;
case "#text":
$markdown = preg_replace('~\s+~', ' ', $value);
$markdown = preg_replace('~^#~', '\\\\#', $markdown);
break;
case "#comment":
$markdown = '';
break;
case "div":
$markdown = ($this->options['strip_tags']) ? $value . PHP_EOL . PHP_EOL : html_entity_decode($node->C14N());
break;
default:
// If strip_tags is false (the default), preserve tags that don't have Markdown equivalents,
// such as <span> nodes on their own. C14N() canonicalizes the node to a string.
// See: http://www.php.net/manual/en/domnode.c14n.php
$markdown = ($this->options['strip_tags']) ? $value : html_entity_decode($node->C14N());
}
return $markdown;
}
/**
* Convert Header
*
* Converts h1 and h2 headers to Markdown-style headers in setext style,
* matching the number of underscores with the length of the title.
*
* e.g. Header 1 Header Two
* ======== ----------
*
* Returns atx headers instead if $this->options['header_style'] is "atx"
*
* e.g. # Header 1 ## Header Two
*
* @param string $level The header level, including the "h". e.g. h1
* @param string $node The node to convert.
* @return string The Markdown version of the header.
*/
private function convert_header($level, $node)
{
$content = $node->nodeValue;
if (!$this->is_child_of('blockquote', $node) && $this->options['header_style'] == "setext") {
$length = (function_exists('mb_strlen')) ? mb_strlen($content, 'utf-8') : strlen($content);
$underline = ($level == "h1") ? "=" : "-";
$markdown = $content . PHP_EOL . str_repeat($underline, $length) . PHP_EOL . PHP_EOL; // setext style
} else {
$prefix = ($level == "h1") ? "# " : "## ";
$markdown = $prefix . $content . PHP_EOL . PHP_EOL; // atx style
}
return $markdown;
}
/**
* Converts inline styles
* This function is used to render strong and em tags
*
* eg <strong>bold text</strong> becomes **bold text** or __bold text__
*
* @param string $tag
* @param string $value
* @return string
*/
private function convert_emphasis($tag, $value)
{
if ($tag == 'i' || $tag == 'em') {
$markdown = $this->options['italic_style'] . $value . $this->options['italic_style'];
} else {
$markdown = $this->options['bold_style'] . $value . $this->options['bold_style'];
}
return $markdown;
}
/**
* Convert Image
*
* Converts <img /> tags to Markdown.
*
* e.g. <img src="/path/img.jpg" alt="alt text" title="Title" />
* becomes ![alt text](/path/img.jpg "Title")
*
* @param $node
* @return string
*/
private function convert_image($node)
{
$src = $node->getAttribute('src');
$alt = $node->getAttribute('alt');
$title = $node->getAttribute('title');
if ($title != "") {
$markdown = '![' . $alt . '](' . $src . ' "' . $title . '")'; // No newlines added. <img> should be in a block-level element.
} else {
$markdown = '![' . $alt . '](' . $src . ')';
}
return $markdown;
}
/**
* Convert Anchor
*
* Converts <a> tags to Markdown.
*
* e.g. <a href="http://modernnerd.net" title="Title">Modern Nerd</a>
* becomes [Modern Nerd](http://modernnerd.net "Title")
*
* @param $node
* @return string
*/
private function convert_anchor($node)
{
$href = $node->getAttribute('href');
$title = $node->getAttribute('title');
$text = $node->nodeValue;
if ($title != "") {
$markdown = '[' . $text . '](' . $href . ' "' . $title . '")';
} else {
$markdown = '[' . $text . '](' . $href . ')';
}
if (! $href)
$markdown = html_entity_decode($node->C14N());
// Append a space if the node after this one is also an anchor
$next_node_name = $this->get_next_node_name($node);
if ($next_node_name == 'a')
$markdown = $markdown . ' ';
return $markdown;
}
/**
* Convert List
*
* Converts <ul> and <ol> lists to Markdown.
*
* @param $node
* @return string
*/
private function convert_list($node)
{
// If parent is an ol, use numbers, otherwise, use dashes
$list_type = $node->parentNode->nodeName;
$value = $node->nodeValue;
if ($list_type == "ul") {
$markdown = "- " . trim($value) . PHP_EOL;
} else {
$number = $this->get_position($node);
$markdown = $number . ". " . trim($value) . PHP_EOL;
}
return $markdown;
}
/**
* Convert Code
*
* Convert code tags by indenting blocks of code and wrapping single lines in backticks.
*
* @param DOMNode $node
* @return string
*/
private function convert_code($node)
{
// Store the content of the code block in an array, one entry for each line
$markdown = '';
$code_content = html_entity_decode($node->C14N());
$code_content = str_replace(array("<code>", "</code>"), "", $code_content);
$code_content = str_replace(array("<pre>", "</pre>"), "", $code_content);
$lines = preg_split('/\r\n|\r|\n/', $code_content);
$total = count($lines);
// If there's more than one line of code, prepend each line with four spaces and no backticks.
if ($total > 1 || $node->nodeName === 'pre') {
// Remove the first and last line if they're empty
$first_line = trim($lines[0]);
$last_line = trim($lines[$total - 1]);
$first_line = trim($first_line, "&#xD;"); //trim XML style carriage returns too
$last_line = trim($last_line, "&#xD;");
if (empty($first_line))
array_shift($lines);
if (empty($last_line))
array_pop($lines);
$count = 1;
foreach ($lines as $line) {
$line = str_replace('&#xD;', '', $line);
$markdown .= " " . $line;
// Add newlines, except final line of the code
if ($count != $total)
$markdown .= PHP_EOL;
$count++;
}
$markdown .= PHP_EOL;
} else { // There's only one line of code. It's a code span, not a block. Just wrap it with backticks.
$markdown .= "`" . $lines[0] . "`";
}
return $markdown;
}
/**
* Convert blockquote
*
* Prepend blockquotes with > chars.
*
* @param $node
* @return string
*/
private function convert_blockquote($node)
{
// Contents should have already been converted to Markdown by this point,
// so we just need to add ">" symbols to each line.
$markdown = '';
$quote_content = trim($node->nodeValue);
$lines = preg_split('/\r\n|\r|\n/', $quote_content);
$total_lines = count($lines);
foreach ($lines as $i => $line) {
$markdown .= "> " . $line . PHP_EOL;
if ($i + 1 == $total_lines)
$markdown .= PHP_EOL;
}
return $markdown;
}
/**
* Get Position
*
* Returns the numbered position of a node inside its parent
*
* @param $node
* @return int The numbered position of the node, starting at 1.
*/
private function get_position($node)
{
// Get all of the nodes inside the parent
$list_nodes = $node->parentNode->childNodes;
$total_nodes = $list_nodes->length;
$position = 1;
// Loop through all nodes and find the given $node
for ($a = 0; $a < $total_nodes; $a++) {
$current_node = $list_nodes->item($a);
if ($current_node->isSameNode($node))
$position = $a + 1;
}
return $position;
}
/**
* Get Next Node Name
*
* Return the name of the node immediately after the passed one.
*
* @param $node
* @return string|null The node name (e.g. 'h1') or null.
*/
private function get_next_node_name($node)
{
$next_node_name = null;
$current_position = $this->get_position($node);
$next_node = $node->parentNode->childNodes->item($current_position);
if ($next_node)
$next_node_name = $next_node->nodeName;
return $next_node_name;
}
/**
* To String
*
* Magic method to return Markdown output when HTML_To_Markdown instance is treated as a string.
*
* @return string
*/
public function __toString()
{
return $this->output();
}
/**
* Output
*
* Getter for the converted Markdown contents stored in $this->output
*
* @return string
*/
public function output()
{
if (!$this->output) {
return '';
} else {
return $this->output;
}
}
}

View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Nick Cernis
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,138 @@
HTML To Markdown for PHP
========================
A helper class that converts HTML to [Markdown](http://daringfireball.net/projects/markdown/) for your sanity and convenience.
[![Build Status](https://travis-ci.org/nickcernis/html-to-markdown.png?branch=master)](https://travis-ci.org/nickcernis/html-to-markdown)
**Version**: 2.2.1
**Requires**: PHP 5.3+
**Author**: [@nickcernis](http://twitter.com/nickcernis)
**License**: [MIT](http://www.opensource.org/licenses/mit-license.php)
### Why convert HTML to Markdown?
*"What alchemy is this?"* you mutter. *"I can see why you'd convert [Markdown to HTML](http://michelf.com/projects/php-markdown/),"* you continue, already labouring the question somewhat, *"but why go the other way?"*
Typically you would convert HTML to Markdown if:
1. You have an existing HTML document that needs to be edited by people with good taste.
2. You want to store new content in HTML format but edit it as Markdown.
3. You want to convert HTML email to plain text email.
4. You know a guy who's been converting HTML to Markdown for years, and now he can speak Elvish. You'd quite like to be able to speak Elvish.
5. You just really like Markdown.
### How to use it
Either include HTML_To_Markdown.php directly:
require_once( dirname( __FILE__) . '/HTML_To_Markdown.php' );
Or, require the library in your composer.json:
{
"require": {
"nickcernis/html-to-markdown": "dev-master"
}
}
Then `composer install` and add `require 'vendor/autoload.php';` to the top of your script.
Next, create a new HTML_To_Markdown instance, passing in your valid HTML code:
$html = "<h3>Quick, to the Batpoles!</h3>";
$markdown = new HTML_To_Markdown($html);
The `$markdown` object now contains the Markdown version of your HTML. Use it like a string:
echo $markdown; // ==> ### Quick, to the Batpoles!
Or access the Markdown output directly:
$string = $markdown->output();
The included `demo` directory contains an HTML->Markdown conversion form to try out.
### Conversion options
By default, HTML To Markdown preserves HTML tags without Markdown equivalents, like `<span>` and `<div>`.
To strip HTML tags that don't have a Markdown equivalent while preserving the content inside them, set `strip_tags` to true, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown($html, array('strip_tags' => true)); // $markdown now contains "Turnips!"
Or more explicitly, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('strip_tags', true);
$markdown->convert($html); // $markdown now contains "Turnips!"
Note that only the tags themselves are stripped, not the content they hold.
To strip tags and their content, pass a space-separated list of tags in `remove_nodes`, like this:
$html = '<span>Turnips!</span><div>Monkeys!</div>';
$markdown = new HTML_To_Markdown($html, array('remove_nodes' => 'span div')); // $markdown now contains ""
### Style options
Bold and italic tags are converted using the asterisk syntax by default. Change this to the underlined syntax using the `bold_style` and `italic_style` options.
$html = '<em>Italic</em> and a <strong>bold</strong>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('italic_style', '_');
$markdown->set_option('bold_style', '__');
$markdown->convert($html); // $markdown now contains "_Italic_ and a __bold__"
### Limitations
- Markdown Extra, MultiMarkdown and other variants aren't supported just Markdown.
### Known issues
- Nested lists and lists containing multiple paragraphs aren't converted correctly.
- Lists inside blockquotes aren't converted correctly.
- Any reported [open issues here](https://github.com/nickcernis/html-to-markdown/issues?state=open).
[Report your issue or request a feature here.](https://github.com/nickcernis/html2markdown/issues/new) Issues with patches or failing tests are especially welcome.
### Style notes
- Setext (underlined) headers are the default for H1 and H2. If you prefer the ATX style for H1 and H2 (# Header 1 and ## Header 2), set `header_style` to 'atx' in the options array when you instantiate the object:
`$markdown = new HTML_To_Markdown( $html, array('header_style'=>'atx') );`
Headers of H3 priority and lower always use atx style.
- Links and images are referenced inline. Footnote references (where image src and anchor href attributes are listed in the footnotes) are not used.
- Blockquotes aren't line wrapped it makes the converted Markdown easier to edit.
### Dependencies
HTML To Markdown requires PHP's [xml](http://www.php.net/manual/en/xml.installation.php), [lib-xml](http://www.php.net/manual/en/libxml.installation.php), and [dom](http://www.php.net/manual/en/dom.installation.php) extensions, all of which are enabled by default on most distributions.
Errors such as "Fatal error: Class 'DOMDocument' not found" on distributions such as CentOS that disable PHP's xml extension can be resolved by installing php-xml.
### Architecture notes
HTML To Markdown is a single file that uses native DOM manipulation libraries (DOMDocument), not regex voodoo, to convert code.
### Contributors
Many thanks to all [contributors](https://github.com/nickcernis/html2markdown/graphs/contributors) so far. Further improvements and feature suggestions are very welcome.
### How it works
HTML To Markdown creates a DOMDocument from the supplied HTML, walks through the tree, and converts each node to a text node containing the equivalent markdown, starting from the most deeply nested node and working inwards towards the root node.
### To-do
- Support for nested lists and lists inside blockquotes.
- Offer an option to preserve tags as HTML if they contain attributes that can't be represented with Markdown (e.g. `style`).
### Trying to convert Markdown to HTML?
Use [PHP Markdown](http://michelf.com/projects/php-markdown/) from Michel Fortin. No guarantees about the Elvish, though.

View file

@ -0,0 +1,4 @@
test:
override:
- phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View file

@ -0,0 +1,25 @@
{
"name": "nickcernis/html-to-markdown",
"type": "library",
"description": "An HTML-to-markdown conversion helper for PHP",
"keywords": ["markdown", "html"],
"homepage": "https://github.com/nickcernis/html-to-markdown",
"license": "MIT",
"authors": [
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net"
}
],
"autoload": {
"classmap": [ "HTML_To_Markdown.php" ]
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"php": ">=5.3.3",
"phpunit/phpunit": "4.*"
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
PHP Markdown Lib
Copyright (c) 2004-2014 Michel Fortin
<http://michelf.ca/>
All rights reserved.
Based on Markdown
Copyright (c) 2003-2006 John Gruber
<http://daringfireball.net/>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.

View file

@ -0,0 +1,10 @@
<?php
# Use this file if you cannot use class autoloading. It will include all the
# files needed for the Markdown parser.
#
# Take a look at the PSR-0-compatible class autoloading implementation
# in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
<?php
# Use this file if you cannot use class autoloading. It will include all the
# files needed for the MarkdownExtra parser.
#
# Take a look at the PSR-0-compatible class autoloading implementation
# in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';
require_once dirname(__FILE__) . '/MarkdownExtra.php';

View file

@ -0,0 +1,38 @@
<?php
#
# Markdown Extra - A text-to-HTML conversion tool for web writers
#
# PHP Markdown Extra
# Copyright (c) 2004-2014 Michel Fortin
# <http://michelf.com/projects/php-markdown/>
#
# Original Markdown
# Copyright (c) 2004-2006 John Gruber
# <http://daringfireball.net/projects/markdown/>
#
namespace Michelf;
# Just force Michelf/Markdown.php to load. This is needed to load
# the temporary implementation class. See below for details.
\Michelf\Markdown::MARKDOWNLIB_VERSION;
#
# Markdown Extra Parser Class
#
# Note: Currently the implementation resides in the temporary class
# \Michelf\MarkdownExtra_TmpImpl (in the same file as \Michelf\Markdown).
# This makes it easier to propagate the changes between the three different
# packaging styles of PHP Markdown. Once this issue is resolved, the
# _MarkdownExtra_TmpImpl will disappear and this one will contain the code.
#
class MarkdownExtra extends \Michelf\_MarkdownExtra_TmpImpl {
### Parser Implementation ###
# Temporarily, the implemenation is in the _MarkdownExtra_TmpImpl class.
# See note above.
}

View file

@ -0,0 +1,9 @@
<?php
# Use this file if you cannot use class autoloading. It will include all the
# files needed for the MarkdownInterface interface.
#
# Take a look at the PSR-0-compatible class autoloading implementation
# in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';

View file

@ -0,0 +1,34 @@
<?php
#
# Markdown - A text-to-HTML conversion tool for web writers
#
# PHP Markdown
# Copyright (c) 2004-2014 Michel Fortin
# <http://michelf.com/projects/php-markdown/>
#
# Original Markdown
# Copyright (c) 2004-2006 John Gruber
# <http://daringfireball.net/projects/markdown/>
#
namespace Michelf;
#
# Markdown Parser Interface
#
interface MarkdownInterface {
#
# Initialize the parser and return the result of its transform method.
# This will work fine for derived classes too.
#
public static function defaultTransform($text);
#
# Main function. Performs some preprocessing on the input text
# and pass it through the document gamut.
#
public function transform($text);
}

View file

@ -0,0 +1,315 @@
PHP Markdown
============
PHP Markdown Lib 1.4.1 - 4 May 2013
by Michel Fortin
<http://michelf.ca/>
based on Markdown by John Gruber
<http://daringfireball.net/>
Introduction
------------
This is a library package that includes the PHP Markdown parser and its
sibling PHP Markdown Extra with additional features.
Markdown is a text-to-HTML conversion tool for web writers. Markdown
allows you to write using an easy-to-read, easy-to-write plain text
format, then convert it to structurally valid XHTML (or HTML).
"Markdown" is actually two things: a plain text markup syntax, and a
software tool, originally written in Perl, that converts the plain text
markup to HTML. PHP Markdown is a port to PHP of the original Markdown
program by John Gruber.
* [Full documentation of the Markdown syntax](<http://daringfireball.net/projects/markdown/>)
- Daring Fireball (John Gruber)
* [Markdown Extra syntax additions](<http://michelf.ca/projects/php-markdown/extra/>)
- Michel Fortin
Requirement
-----------
This library package requires PHP 5.3 or later.
Note: The older plugin/library hybrid package for PHP Markdown and
PHP Markdown Extra is still maintained and will work with PHP 4.0.5 and later.
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
in many situations. You might need to set it to higher values. Later PHP
releases defaults to 1 000 000, which is usually fine.
Usage
-----
This library package is meant to be used with class autoloading. For autoloading
to work, your project needs have setup a PSR-0-compatible autoloader. See the
included Readme.php file for a minimal autoloader setup. (If you cannot use
autoloading, see below.)
With class autoloading in place, putting the 'Michelf' folder in your
include path should be enough for this to work:
use \Michelf\Markdown;
$my_html = Markdown::defaultTransform($my_text);
Markdown Extra syntax is also available the same way:
use \Michelf\MarkdownExtra;
$my_html = MarkdownExtra::defaultTransform($my_text);
If you wish to use PHP Markdown with another text filter function
built to parse HTML, you should filter the text *after* the `transform`
function call. This is an example with [PHP SmartyPants][psp]:
use \Michelf\Markdown, \Michelf\SmartyPants;
$my_html = Markdown::defaultTransform($my_text);
$my_html = SmartyPants::defaultTransform($my_html);
All these examples are using the static `defaultTransform` static function
found inside the parser class. If you want to customize the parser
configuration, you can also instantiate it directly and change some
configuration variables:
use \Michelf\MarkdownExtra;
$parser = new MarkdownExtra;
$parser->fn_id_prefix = "post22-";
$my_html = $parser->transform($my_text);
To learn more, see the full list of [configuration variables].
[configuration variables]: http://michelf.ca/projects/php-markdown/configuration/
### Usage without an autoloader
If you cannot use class autoloading, you can still use `include` or `require`
to access the parser. To load the `\Michelf\Markdown` parser, do it this way:
require_once 'Michelf/Markdown.inc.php';
Or, if you need the `\Michelf\MarkdownExtra` parser:
require_once 'Michelf/MarkdownExtra.inc.php';
While the plain `.php` files depend on autoloading to work correctly, using the
`.inc.php` files instead will eagerly load the dependencies that would be
loaded on demand if you were using autoloading.
Public API and Versioning Policy
---------------------------------
Version numbers are of the form *major*.*minor*.*patch*.
The public API of PHP Markdown consist of the two parser classes `Markdown`
and `MarkdownExtra`, their constructors, the `transform` and `defaultTransform`
functions and their configuration variables. The public API is stable for
a given major version number. It might get additions when the minor version
number increments.
**Protected members are not considered public API.** This is unconventional
and deserves an explanation. Incrementing the major version number every time
the underlying implementation of something changes is going to give
nonessential version numbers for the vast majority of people who just use the
parser. Protected members are meant to create parser subclasses that behave in
different ways. Very few people create parser subclasses. I don't want to
discourage it by making everything private, but at the same time I can't
guarantee any stable hook between versions if you use protected members.
**Syntax changes** will increment the minor number for new features, and the
patch number for small corrections. A *new feature* is something that needs a
change in the syntax documentation. Note that since PHP Markdown Lib includes
two parsers, a syntax change for either of them will increment the minor
number. Also note that there is nothing perfectly backward-compatible with the
Markdown syntax: all inputs are always valid, so new features always replace
something that was previously legal, although generally nonsensical to do.
Bugs
----
To file bug reports please send email to:
<michel.fortin@michelf.ca>
Please include with your report: (1) the example input; (2) the output you
expected; (3) the output PHP Markdown actually produced.
If you have a problem where Markdown gives you an empty result, first check
that the backtrack limit is not too low by running `php --info | grep pcre`.
See Installation and Requirement above for details.
Development and Testing
-----------------------
Pull requests for fixing bugs are welcome. Proposed new features are
going meticulously reviewed -- taking into account backward compatibility,
potential side effects, and future extensibility -- before deciding on
acceptance or rejection.
If you make a pull request that includes changes to the parser please add
tests for what is being changed to [MDTest][] and make a pull request there
too.
[MDTest]: https://github.com/michelf/mdtest/
Donations
---------
If you wish to make a donation that will help me devote more time to
PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to
[1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH].
[michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown
[1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH]: bitcoin:1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH
Version History
---------------
Unreleased
* Added the ability to insert custom HTML attributes everywhere an extra
attribute block is allowed (links, images, headers). Credits to
Peter Droogmans for providing the implementation.
* Added a `url_filter_func` configuration variable which takes a function
that can rewrite any link or image URL to something different.
PHP Markdown Lib 1.4.1 (4 May 2014)
* The HTML block parser will now treat `<figure>` as a block-level element
(as it should) and no longer wrap it in `<p>` or parse it's content with
the as Markdown syntax (although with Extra you can use `markdown="1"`
if you wish to use the Markdown syntax inside it).
* The content of `<style>` elements will now be left alone, its content
won't be interpreted as Markdown.
* Corrected an bug where some inline links with spaces in them would not
work even when surounded with angle brackets:
[link](<s p a c e s>)
* Fixed an issue where email addresses with quotes in them would not always
have the quotes escaped in the link attribute, causing broken links (and
invalid HTML).
* Fixed the case were a link definition following a footnote definition would
be swallowed by the footnote unless it was separated by a blank line.
PHP Markdown Lib 1.4.0 (29 Nov 2013)
* Added support for the `tel:` URL scheme in automatic links.
<tel:+1-111-111-1111>
It gets converted to this (note the `tel:` prefix becomes invisible):
<a href="tel:+1-111-111-1111">+1-111-111-1111</a>
* Added backtick fenced code blocks to MarkdownExtra, originally from
Github-Flavored Markdown.
* Added an interface called MarkdownInterface implemented by both
the Markdown and MarkdownExtra parsers. You can use the interface if
you want to create a mockup parser object for unit testing.
* For those of you who cannot use class autoloading, you can now
include `Michelf/Markdown.inc.php` or `Michelf/MarkdownExtra.inc.php` (note
the `.inc.php` extension) to automatically include other files required
by the parser.
PHP Markdown Lib 1.3 (11 Apr 2013)
This is the first release of PHP Markdown Lib. This package requires PHP
version 5.3 or later and is designed to work with PSR-0 autoloading and,
optionally with Composer. Here is a list of the changes since
PHP Markdown Extra 1.2.6:
* Plugin interface for WordPress and other systems is no longer present in
the Lib package. The classic package is still available if you need it:
<http://michelf.ca/projects/php-markdown/classic/>
* Added `public` and `protected` protection attributes, plus a section about
what is "public API" and what isn't in the Readme file.
* Changed HTML output for footnotes: now instead of adding `rel` and `rev`
attributes, footnotes links have the class name `footnote-ref` and
backlinks `footnote-backref`.
* Fixed some regular expressions to make PCRE not shout warnings about POSIX
collation classes (dependent on your version of PCRE).
* Added optional class and id attributes to images and links using the same
syntax as for headers:
[link](url){#id .class}
![img](url){#id .class}
It work too for reference-style links and images. In this case you need
to put those attributes at the reference definition:
[link][linkref] or [linkref]
![img][linkref]
[linkref]: url "optional title" {#id .class}
* Fixed a PHP notice message triggered when some table column separator
markers are missing on the separator line below column headers.
* Fixed a small mistake that could cause the parser to retain an invalid
state related to parsing links across multiple runs. This was never
observed (that I know of), but it's still worth fixing.
Copyright and License
---------------------
PHP Markdown Lib
Copyright (c) 2004-2014 Michel Fortin
<http://michelf.ca/>
All rights reserved.
Based on Markdown
Copyright (c) 2003-2005 John Gruber
<http://daringfireball.net/>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.

View file

@ -0,0 +1,31 @@
<?php
# This file passes the content of the Readme.md file in the same directory
# through the Markdown filter. You can adapt this sample code in any way
# you like.
# Install PSR-0-compatible class autoloader
spl_autoload_register(function($class){
require preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
});
# Get Markdown class
use \Michelf\Markdown;
# Read file and pass content through the Markdown parser
$text = file_get_contents('Readme.md');
$html = Markdown::defaultTransform($text);
?>
<!DOCTYPE html>
<html>
<head>
<title>PHP Markdown Lib - Readme</title>
</head>
<body>
<?php
# Put HTML content in the document
echo $html;
?>
</body>
</html>

View file

@ -0,0 +1,31 @@
{
"name": "michelf/php-markdown",
"type": "library",
"description": "PHP Markdown",
"homepage": "http://michelf.ca/projects/php-markdown/",
"keywords": ["markdown"],
"license": "BSD-3-Clause",
"authors": [
{
"name": "Michel Fortin",
"email": "michel.fortin@michelf.ca",
"homepage": "http://michelf.ca/",
"role": "Developer"
},
{
"name": "John Gruber",
"homepage": "http://daringfireball.net/"
}
],
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-0": { "Michelf": "" }
},
"extra": {
"branch-alias": {
"dev-lib": "1.4.x-dev"
}
}
}

View file

@ -121,6 +121,8 @@ function admin_content(&$a) {
}
$aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
$aside['diagnostics_probe'] = Array($a->get_baseurl(true).'/probe/', t('probe address'), 'probe');
$aside['diagnostics_webfinger'] = Array($a->get_baseurl(true).'/webfinger/', t('check webfinger'), 'webfinger');
$t = get_markup_template("admin_aside.tpl");
$a->page['aside'] .= replace_macros( $t, array(
@ -128,6 +130,7 @@ function admin_content(&$a) {
'$admtxt' => t('Admin'),
'$plugadmtxt' => t('Plugin Features'),
'$logtxt' => t('Logs'),
'$diagnosticstxt' => t('diagnostics'),
'$h_pending' => t('User registrations waiting for confirmation'),
'$admurl'=> $a->get_baseurl(true)."/admin/"
));
@ -278,7 +281,7 @@ function admin_page_site_post(&$a){
$q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
$r = q($q);
if (!$r) {
notice( "Falied updating '$table_name': " . $db->error );
notice( "Failed updating '$table_name': " . $db->error );
goaway($a->get_baseurl(true) . '/admin/site' );
}
}
@ -309,7 +312,10 @@ function admin_page_site_post(&$a){
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
$hostname = ((x($_POST,'hostname')) ? notags(trim($_POST['hostname'])) : '');
$sender_email = ((x($_POST,'sender_email')) ? notags(trim($_POST['sender_email'])) : '');
$banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
$shortcut_icon = ((x($_POST,'shortcut_icon')) ? notags(trim($_POST['shortcut_icon'])) : '');
$touch_icon = ((x($_POST,'touch_icon')) ? notags(trim($_POST['touch_icon'])) : '');
$info = ((x($_POST,'info')) ? trim($_POST['info']) : false);
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
@ -341,7 +347,8 @@ function admin_page_site_post(&$a){
$no_openid = !((x($_POST,'no_openid')) ? True : False);
$no_regfullname = !((x($_POST,'no_regfullname')) ? True : False);
$no_utf = !((x($_POST,'no_utf')) ? True : False);
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
$community_page_style = ((x($_POST,'community_page_style')) ? intval(trim($_POST['community_page_style'])) : 0);
$max_author_posts_community_page = ((x($_POST,'max_author_posts_community_page')) ? intval(trim($_POST['max_author_posts_community_page'])) : 0);
$verifyssl = ((x($_POST,'verifyssl')) ? True : False);
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
@ -352,13 +359,14 @@ function admin_page_site_post(&$a){
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$dfrn_only = ((x($_POST,'dfrn_only')) ? True : False);
$ostatus_disabled = !((x($_POST,'ostatus_disabled')) ? True : False);
$ostatus_poll_interval = ((x($_POST,'ostatus_poll_interval')) ? intval(trim($_POST['ostatus_poll_interval'])) : 0);
$ostatus_poll_interval = ((x($_POST,'ostatus_poll_interval')) ? intval(trim($_POST['ostatus_poll_interval'])) : 0);
$diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False);
$ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0);
$force_ssl = ((x($_POST,'force_ssl')) ? True : False);
$old_share = ((x($_POST,'old_share')) ? True : False);
$hide_help = ((x($_POST,'hide_help')) ? True : False);
$suppress_language = ((x($_POST,'suppress_language')) ? True : False);
$suppress_tags = ((x($_POST,'suppress_tags')) ? True : False);
$use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False);
$itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : '');
$itemcache_duration = ((x($_POST,'itemcache_duration')) ? intval($_POST['itemcache_duration']) : 0);
@ -368,7 +376,9 @@ function admin_page_site_post(&$a){
$basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : '');
$singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : '');
$proxy_disabled = ((x($_POST,'proxy_disabled')) ? True : False);
$disable_noscrape = ((x($_POST,'disable_noscrape')) ? true : false);
$old_pager = ((x($_POST,'old_pager')) ? True : False);
$only_tag_search = ((x($_POST,'only_tag_search')) ? True : False);
if($ssl_policy != intval(get_config('system','ssl_policy'))) {
if($ssl_policy == SSL_POLICY_FULL) {
q("update `contact` set
@ -415,7 +425,11 @@ function admin_page_site_post(&$a){
set_config('system','maxloadavg',$maxloadavg);
set_config('config','sitename',$sitename);
set_config('config','hostname',$hostname);
set_config('config','sender_email', $sender_email);
set_config('system','suppress_language',$suppress_language);
set_config('system','suppress_tags',$suppress_tags);
set_config('system','shortcut_icon',$shortcut_icon);
set_config('system','touch_icon',$touch_icon);
if ($banner==""){
// don't know why, but del_config doesn't work...
q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
@ -472,7 +486,8 @@ function admin_page_site_post(&$a){
set_config('system','block_extended_register', $no_multi_reg);
set_config('system','no_openid', $no_openid);
set_config('system','no_regfullname', $no_regfullname);
set_config('system','no_community_page', $no_community_page);
set_config('system','community_page_style', $community_page_style);
set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
set_config('system','no_utf', $no_utf);
set_config('system','verifyssl', $verifyssl);
set_config('system','proxyuser', $proxyuser);
@ -480,7 +495,7 @@ function admin_page_site_post(&$a){
set_config('system','curl_timeout', $timeout);
set_config('system','dfrn_only', $dfrn_only);
set_config('system','ostatus_disabled', $ostatus_disabled);
set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
set_config('system','diaspora_enabled', $diaspora_enabled);
set_config('config','private_addons', $private_addons);
@ -495,7 +510,8 @@ function admin_page_site_post(&$a){
set_config('system','temppath', $temppath);
set_config('system','basepath', $basepath);
set_config('system','proxy_disabled', $proxy_disabled);
set_config('system','disable_noscrape', $disable_noscrape);
set_config('system','old_pager', $old_pager);
set_config('system','only_tag_search', $only_tag_search);
info( t('Site settings updated.') . EOL);
goaway($a->get_baseurl(true) . '/admin/site' );
@ -541,14 +557,21 @@ function admin_page_site(&$a) {
}
}
/* Community page style */
$community_page_style_choices = array(
CP_NO_COMMUNITY_PAGE => t("No community page"),
CP_USERS_ON_SERVER => t("Public postings from users of this site"),
CP_GLOBAL_COMMUNITY => t("Global community page")
);
/* OStatus conversation poll choices */
$ostatus_poll_choices = array(
"-2" => t("Never"),
"-1" => t("At post arrival"),
"0" => t("Frequently"),
"60" => t("Hourly"),
"720" => t("Twice daily"),
"1440" => t("Daily")
"-2" => t("Never"),
"-1" => t("At post arrival"),
"0" => t("Frequently"),
"60" => t("Hourly"),
"720" => t("Twice daily"),
"1440" => t("Daily")
);
/* get user names to make the install a personal install of X */
@ -605,7 +628,10 @@ function admin_page_site(&$a) {
// name, label, value, help string, extra data...
'$sitename' => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
'$hostname' => array('hostname', t("Host name"), $a->config['hostname'], ""),
'$sender_email' => array('sender_email', t("Sender Email"), $a->config['sender_email'], "The email address your server shall use to send notification emails from.", "", "", "email"),
'$banner' => array('banner', t("Banner/Logo"), $banner, ""),
'$shortcut_icon' => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'), "Link to an icon that will be used for browsers."),
'$touch_icon' => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'), "Link to an icon that will be used for tablets and mobiles."),
'$info' => array('info',t('Additional Info'), $info, t('For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo.')),
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
@ -638,7 +664,8 @@ function admin_page_site(&$a) {
'$no_openid' => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
'$no_regfullname' => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")),
'$no_utf' => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
'$no_community_page' => array('no_community_page', t("Show Community Page"), !get_config('system','no_community_page'), t("Display a Community page showing all recent public postings on this site.")),
'$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
'$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
'$ostatus_disabled' => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
'$ostatus_poll_interval' => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices),
'$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
@ -653,6 +680,7 @@ function admin_page_site(&$a) {
'$use_fulltext_engine' => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
'$suppress_language' => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
'$suppress_tags' => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
'$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
'$itemcache_duration' => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")),
'$max_comments' => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")),
@ -660,10 +688,10 @@ function admin_page_site(&$a) {
'$temppath' => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."),
'$basepath' => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
'$proxy_disabled' => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
'$old_pager' => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")),
'$only_tag_search' => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
'$relocate_url' => array('relocate_url', t("New base url"), $a->get_baseurl(), "Change base url for this server. Sends relocate message to all DFRN contacts of all users."),
'$disable_noscrape'=> array('disable_noscrape', t("Disable noscrape"), get_config('system','disable_noscrape'), t("The noscrape feature speeds up directory submissions by using JSON data instead of HTML scraping. Disabling it will cause higher load on your server and the directory server.")),
'$form_security_token' => get_form_security_token("admin_site")
));

View file

@ -32,7 +32,7 @@ function bookmarklet_content(&$a) {
'visitor' => 'block',
'profile_uid' => local_user(),
'acl_data' => construct_acl_data($a, $a->user), // For non-Javascript ACL selector
'title' => $_REQUEST["title"],
'title' => trim($_REQUEST["title"], "*"),
'content' => $content
);
$o = status_editor($a,$x, 0, false);

View file

@ -19,7 +19,7 @@ function community_content(&$a, $update = 0) {
return;
}
if(get_config('system','no_community_page')) {
if(get_config('system','community_page_style') == CP_NO_COMMUNITY_PAGE) {
notice( t('Not available.') . EOL);
return;
}
@ -44,7 +44,7 @@ function community_content(&$a, $update = 0) {
// Only public posts can be shown
// OR your own posts if you are a logged in member
if( (! get_config('alt_pager', 'global')) && (! get_pconfig(local_user(),'system','alt_pager')) ) {
if(get_config('system', 'old_pager')) {
$r = q("SELECT COUNT(distinct(`item`.`uri`)) AS `total`
FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
@ -103,10 +103,9 @@ function community_content(&$a, $update = 0) {
$o .= conversation($a,$s,'community',$update);
if(get_config('alt_pager', 'global') || get_pconfig(local_user(),'system','alt_pager') ) {
if(!get_config('system', 'old_pager')) {
$o .= alt_pager($a,count($r));
}
else {
} else {
$o .= paginate($a);
}
@ -114,8 +113,7 @@ function community_content(&$a, $update = 0) {
}
function community_getitems($start, $itemspage) {
// Work in progress
if (get_config('system', 'global_community'))
if (get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
return(community_getpublicitems($start, $itemspage));
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
@ -145,7 +143,7 @@ function community_getpublicitems($start, $itemspage) {
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item` WHERE `item`.`uid` = 0
FROM `item` WHERE `item`.`uid` = 0 AND `item`.`id` = `item`.`parent`
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
ORDER BY `item`.`received` DESC LIMIT %d, %d",

View file

@ -32,7 +32,8 @@ function contacts_init(&$a) {
$a->data['contact'] = $r[0];
$vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array(
'$name' => $a->data['contact']['name'],
'$photo' => $a->data['contact']['photo']
'$photo' => $a->data['contact']['photo'],
'$url' => ($a->data['contact']['network'] == 'dfrn') ? $a->get_baseurl()."/redir/".$a->data['contact']['id'] : $a->data['contact']['url']
));
$follow_widget = '';
}
@ -44,6 +45,9 @@ function contacts_init(&$a) {
$follow_widget = follow_widget();
}
if ($_GET['nets'] == "all")
$_GET['nets'] = "";
$groups_widget .= group_side('contacts','group',false,0,$contact_id);
$findpeople_widget .= findpeople_widget();
$networks_widget .= networks_widget('contacts',$_GET['nets']);
@ -402,6 +406,9 @@ function contacts_content(&$a) {
break;
}
if(!in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
$relation_text = "";
$relation_text = sprintf($relation_text,$contact['name']);
if(($contact['network'] === NETWORK_DFRN) && ($contact['rel'])) {
@ -424,7 +431,7 @@ function contacts_content(&$a) {
$lblsuggest = (($contact['network'] === NETWORK_DFRN) ? t('Suggest friends') : '');
$poll_enabled = (($contact['network'] !== NETWORK_DIASPORA) ? true : false);
$poll_enabled = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_FEED, NETWORK_MAIL, NETWORK_MAIL2));
$nettype = sprintf( t('Network type: %s'),network_to_name($contact['network']));
@ -469,6 +476,16 @@ function contacts_content(&$a) {
$lost_contact = (($contact['archive'] && $contact['term-date'] != '0000-00-00 00:00:00' && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : '');
if ($contact['network'] == NETWORK_FEED)
$fetch_further_information = array('fetch_further_information', t('Fetch further information for feeds'), $contact['fetch_further_information'], t('Fetch further information for feeds'),
array('0'=>t('Disabled'), '1'=>t('Fetch information'), '2'=>t('Fetch information and keywords')));
if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL, NETWORK_MAIL2)))
$poll_interval = contact_poll_interval($contact['priority'],(! $poll_enabled));
if ($contact['network'] == NETWORK_DFRN)
$profile_select = contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false));
$o .= replace_macros($tpl, array(
'$header' => t('Contact Editor'),
'$tab_str' => $tab_str,
@ -489,14 +506,14 @@ function contacts_content(&$a) {
'$lblsuggest' => $lblsuggest,
'$delete' => t('Delete contact'),
'$nettype' => $nettype,
'$poll_interval' => contact_poll_interval($contact['priority'],(! $poll_enabled)),
'$poll_interval' => $poll_interval,
'$poll_enabled' => $poll_enabled,
'$lastupdtext' => t('Last update:'),
'$lost_contact' => $lost_contact,
'$updpub' => t('Update public posts'),
'$last_update' => $last_update,
'$udnow' => t('Update now'),
'$profile_select' => contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false)),
'$profile_select' => $profile_select,
'$contact_id' => $contact['id'],
'$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
'$ignore_text' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ),
@ -507,8 +524,7 @@ function contacts_content(&$a) {
'$archived' => (($contact['archive']) ? t('Currently archived') : ''),
'$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')),
'$notify' => array('notify', t('Notification for new posts'), ($contact['notify_new_posts'] == 1), t('Send a notification of every new post of this contact')),
'$fetch_further_information' => array('fetch_further_information', t('Fetch further information for feeds'), $contact['fetch_further_information'], t('Fetch further information for feeds'),
array('0'=>t('Disabled'), '1'=>t('Fetch information'), '2'=>t('Fetch information and keywords'))),
'$fetch_further_information' => $fetch_further_information,
'$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'],
'$ffi_keyword_blacklist' => array('ffi_keyword_blacklist', t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')),
'$photo' => $contact['photo'],

View file

@ -41,6 +41,18 @@ function display_init(&$a) {
$itemuid = $r[0]["uid"];
}
}
// Is it an item with uid=0?
if ($nick == "") {
$r = q("SELECT `item`.`id`, `item`.`parent`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`network`, `item`.`uid`, `item`.`body`
FROM `item` WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND `item`.`private` = 0 AND `item`.`uid` = 0
AND `item`.`guid` = '%s'", $a->argv[1]);
// AND `item`.`private` = 0 AND `item`.`wall` = 1
}
if (count($r)) {
if ($r[0]["id"] != $r[0]["parent"])
$r = q("SELECT `id`, `author-name`, `author-link`, `author-avatar`, `network`, `body`, `uid` FROM `item`
@ -252,6 +264,18 @@ function display_content(&$a, $update = 0) {
$nick = $r[0]["nickname"];
}
}
if ($nick == "") {
$r = q("SELECT `item`.`id` FROM `item`
WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND `item`.`private` = 0 AND `item`.`uid` = 0
AND `item`.`guid` = '%s'", $a->argv[1]);
// AND `item`.`private` = 0 AND `item`.`wall` = 1
if (count($r)) {
$item_id = $r[0]["id"];
}
}
}
}

View file

@ -38,11 +38,8 @@ function friendica_init(&$a) {
'site_name' => $a->config['sitename'],
'platform' => FRIENDICA_PLATFORM,
'info' => ((x($a->config,'info')) ? $a->config['info'] : ''),
'no_scrape_url' => $a->get_baseurl().'/noscrape'
);
//Enable noscrape?
if(!get_config('system','disable_noscrape'))
$data['no_scrape_url'] = $a->get_baseurl().'/noscrape';
echo json_encode($data);
killme();

View file

@ -1,53 +1,6 @@
<?php
define( 'MARKDOWN_PARSER_CLASS', 'ExtendedMarkdown' );
require_once('library/markdown.php');
class ExtendedMarkdown extends MarkdownExtra_Parser {
function ExtendedMarkdown() {
$this->block_gamut += array(
"doBlockWarning" => 45,
);
parent::MarkdownExtra_Parser();
}
function doBlockWarning($text) {
$text = preg_replace_callback('/
( # Wrap whole match in $1
(?>
^[ ]*![ ]? # "!" at the start of a line
.+\n # rest of the first line
(.+\n)* # subsequent consecutive lines
\n* # blanks
)+
)
/xm', array(&$this, '_doBlockWarning_callback'), $text);
return $text;
}
function _doBlockWarning_callback($matches) {
$bq = $matches[1];
# trim one level of quoting - trim whitespace-only lines
$bq = preg_replace('/^[ ]*![ ]?|^[ ]+$/m', '', $bq);
$bq = $this->runBlockGamut($bq); # recurse
$bq = preg_replace('/^/m', " ", $bq);
# These leading spaces cause problem with <pre> content,
# so we need to fix that:
// $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', array(&$this, '__doBlockWarning_callback2'), $bq);
return "\n" . $this->hashBlock("<div class='md_warning'>\n$bq\n</div>") . "\n\n";
}
function _doBlockWarning_callback2($matches) {
$pre = $matches[1];
$pre = preg_replace('/^ /m', '', $pre);
return $pre;
}
}
if (!function_exists('load_doc_file')) {
function load_doc_file($s) {
@ -66,8 +19,7 @@ if (!function_exists('load_doc_file')) {
}
function help_content(&$a) {
nav_set_selected('help');
global $lang;
@ -93,9 +45,9 @@ function help_content(&$a) {
'$message' => t('Page not found.')
));
}
$html = Markdown($text);
$html = "<style>.md_warning { padding: 1em; border: #ff0000 solid 2px; background-color: #f9a3a3; color: #ffffff;</style>".$html;
return $html;
}

View file

@ -22,6 +22,8 @@ require_once('library/langdet/Text/LanguageDetect.php');
require_once('include/tags.php');
require_once('include/files.php');
require_once('include/threads.php');
require_once('include/text.php');
require_once('include/items.php');
function item_post(&$a) {
@ -33,7 +35,6 @@ function item_post(&$a) {
$uid = local_user();
if(x($_REQUEST,'dropitems')) {
require_once('include/items.php');
$arr_drop = explode(',',$_REQUEST['dropitems']);
drop_items($arr_drop);
$json = array('success' => 1);
@ -232,11 +233,11 @@ function item_post(&$a) {
} else {
// if coming from the API and no privacy settings are set,
// if coming from the API and no privacy settings are set,
// use the user default permissions - as they won't have
// been supplied via a form.
if(($api_source)
if(($api_source)
&& (! array_key_exists('contact_allow',$_REQUEST))
&& (! array_key_exists('group_allow',$_REQUEST))
&& (! array_key_exists('contact_deny',$_REQUEST))
@ -364,7 +365,7 @@ function item_post(&$a) {
// Work around doubled linefeeds in Tinymce 3.5b2
// First figure out if it's a status post that would've been
// created using tinymce. Otherwise leave it alone.
// created using tinymce. Otherwise leave it alone.
/* $plaintext = (local_user() ? intval(get_pconfig(local_user(),'system','plaintext')) || !feature_enabled($profile_uid,'richtext') : 0);
if((! $parent) && (! $api_source) && (! $plaintext)) {
@ -533,7 +534,7 @@ function item_post(&$a) {
* Fold multi-line [code] sequences
*/
$body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
$body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
$body = scale_external_images($body,false);
@ -568,7 +569,7 @@ function item_post(&$a) {
* and we are replying, and there isn't one already
*/
if(($parent_contact) && ($parent_contact['network'] === NETWORK_OSTATUS)
if(($parent_contact) && ($parent_contact['network'] === NETWORK_OSTATUS)
&& ($parent_contact['nick']) && (! in_array('@' . $parent_contact['nick'],$tags))) {
$body = '@' . $parent_contact['nick'] . ' ' . $body;
$tags[] = '@' . $parent_contact['nick'];
@ -581,6 +582,9 @@ function item_post(&$a) {
if(count($tags)) {
foreach($tags as $tag) {
if(strpos($tag,'#') === 0)
continue;
// If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
// Robert Johnson should be first in the $tags array
@ -623,7 +627,7 @@ function item_post(&$a) {
if(count($r)) {
if(strlen($attachments))
$attachments .= ',';
$attachments .= '[attach]href="' . $a->get_baseurl() . '/attach/' . $r[0]['id'] . '" length="' . $r[0]['filesize'] . '" type="' . $r[0]['filetype'] . '" title="' . (($r[0]['filename']) ? $r[0]['filename'] : '') . '"[/attach]';
$attachments .= '[attach]href="' . $a->get_baseurl() . '/attach/' . $r[0]['id'] . '" length="' . $r[0]['filesize'] . '" type="' . $r[0]['filetype'] . '" title="' . (($r[0]['filename']) ? $r[0]['filename'] : '') . '"[/attach]';
}
$body = str_replace($match[1],'',$body);
}
@ -642,7 +646,7 @@ function item_post(&$a) {
$gravity = (($parent) ? 6 : 0 );
// even if the post arrived via API we are considering that it
// even if the post arrived via API we are considering that it
// originated on this site by default for determining relayability.
$origin = ((x($_REQUEST,'origin')) ? intval($_REQUEST['origin']) : 1);
@ -712,6 +716,9 @@ function item_post(&$a) {
if($orig_post)
$datarray['edit'] = true;
// Search for hashtags
item_body_set_hashtags($datarray);
// preview mode - prepare the body for display and send it via json
if($preview) {
@ -739,14 +746,18 @@ function item_post(&$a) {
killme();
}
// Fill the cache field
put_item_in_cache($datarray);
if($orig_post) {
$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc($datarray['title']),
dbesc($datarray['body']),
dbesc($datarray['tag']),
dbesc($datarray['attach']),
dbesc($datarray['file']),
dbesc($datarray['rendered-html']),
dbesc($datarray['rendered-hash']),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($post_id),
@ -771,10 +782,10 @@ function item_post(&$a) {
$post_id = 0;
$r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,`owner-name`,`owner-link`,`owner-avatar`,
`author-name`, `author-link`, `author-avatar`, `created`, `edited`, `commented`, `received`, `changed`, `uri`, `thr-parent`, `title`, `body`, `app`, `location`, `coord`,
`tag`, `inform`, `verb`, `object-type`, `postopts`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach`, `bookmark`,`origin`, `moderated`, `file` )
VALUES( '%s', '%s', %d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s' )",
$r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `author-name`, `author-link`, `author-avatar`,
`created`, `edited`, `commented`, `received`, `changed`, `uri`, `thr-parent`, `title`, `body`, `app`, `location`, `coord`, `tag`, `inform`, `verb`, `object-type`, `postopts`,
`allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach`, `bookmark`,`origin`, `moderated`, `file`, `rendered-html`, `rendered-hash`)
VALUES( '%s', '%s', %d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s')",
dbesc($datarray['guid']),
dbesc($datarray['extid']),
intval($datarray['uid']),
@ -816,130 +827,122 @@ function item_post(&$a) {
intval($datarray['bookmark']),
intval($datarray['origin']),
intval($datarray['moderated']),
dbesc($datarray['file'])
dbesc($datarray['file']),
dbesc($datarray['rendered-html']),
dbesc($datarray['rendered-hash'])
);
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($datarray['uri']));
if(count($r)) {
$post_id = $r[0]['id'];
logger('mod_item: saved item ' . $post_id);
add_thread($post_id);
// update filetags in pconfig
file_tag_update_pconfig($uid,$categories_old,$categories_new,'category');
// Store the fresh generated item into the cache
$cachefile = get_cachefile(urlencode($datarray["guid"])."-".hash("md5", $datarray['body']));
if (($cachefile != '') AND !file_exists($cachefile)) {
$s = prepare_text($datarray['body']);
$stamp1 = microtime(true);
file_put_contents($cachefile, $s);
$a->save_timestamp($stamp1, "file");
logger('mod_item: put item '.$r[0]['id'].' into cachefile '.$cachefile);
}
if($parent) {
// This item is the last leaf and gets the comment box, clear any ancestors
$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d ",
dbesc(datetime_convert()),
intval($parent)
);
update_thread($parent, true);
// Inherit ACLs from the parent item.
$r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d
WHERE `id` = %d",
dbesc($parent_item['allow_cid']),
dbesc($parent_item['allow_gid']),
dbesc($parent_item['deny_cid']),
dbesc($parent_item['deny_gid']),
intval($parent_item['private']),
intval($post_id)
);
if($contact_record != $author) {
notification(array(
'type' => NOTIFY_COMMENT,
'notify_flags' => $user['notify-flags'],
'language' => $user['language'],
'to_name' => $user['username'],
'to_email' => $user['email'],
'uid' => $user['uid'],
'item' => $datarray,
'link' => $a->get_baseurl().'/display/'.urlencode($datarray['guid']),
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
'verb' => ACTIVITY_POST,
'otype' => 'item',
'parent' => $parent,
'parent_uri' => $parent_item['uri']
));
}
// Store the comment signature information in case we need to relay to Diaspora
store_diaspora_comment_sig($datarray, $author, ($self ? $a->user['prvkey'] : false), $parent_item, $post_id);
} else {
$parent = $post_id;
if($contact_record != $author) {
notification(array(
'type' => NOTIFY_WALL,
'notify_flags' => $user['notify-flags'],
'language' => $user['language'],
'to_name' => $user['username'],
'to_email' => $user['email'],
'uid' => $user['uid'],
'item' => $datarray,
'link' => $a->get_baseurl().'/display/'.urlencode($datarray['guid']),
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
'verb' => ACTIVITY_POST,
'otype' => 'item'
));
}
}
// fallback so that parent always gets set to non-zero.
if(! $parent)
$parent = $post_id;
$r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1
WHERE `id` = %d",
intval($parent),
dbesc(($parent == $post_id) ? $uri : $parent_item['uri']),
dbesc($a->get_baseurl().'/display/'.urlencode($datarray['guid'])),
dbesc(datetime_convert()),
intval($post_id)
);
// photo comments turn the corresponding item visible to the profile wall
// This way we don't see every picture in your new photo album posted to your wall at once.
// They will show up as people comment on them.
if(! $parent_item['visible']) {
$r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
intval($parent_item['id'])
);
update_thread($parent_item['id']);
}
}
else {
if(!count($r)) {
logger('mod_item: unable to retrieve post that was just stored.');
notice( t('System error. Post not saved.') . EOL);
goaway($a->get_baseurl() . "/" . $return_path );
// NOTREACHED
}
$post_id = $r[0]['id'];
logger('mod_item: saved item ' . $post_id);
$datarray["id"] = $post_id;
$datarray["plink"] = $a->get_baseurl().'/display/'.urlencode($datarray["guid"]);
// update filetags in pconfig
file_tag_update_pconfig($uid,$categories_old,$categories_new,'category');
if($parent) {
// This item is the last leaf and gets the comment box, clear any ancestors
$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d ",
dbesc(datetime_convert()),
intval($parent)
);
update_thread($parent, true);
// Inherit ACLs from the parent item.
$r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d
WHERE `id` = %d",
dbesc($parent_item['allow_cid']),
dbesc($parent_item['allow_gid']),
dbesc($parent_item['deny_cid']),
dbesc($parent_item['deny_gid']),
intval($parent_item['private']),
intval($post_id)
);
if($contact_record != $author) {
notification(array(
'type' => NOTIFY_COMMENT,
'notify_flags' => $user['notify-flags'],
'language' => $user['language'],
'to_name' => $user['username'],
'to_email' => $user['email'],
'uid' => $user['uid'],
'item' => $datarray,
'link' => $a->get_baseurl().'/display/'.urlencode($datarray['guid']),
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
'verb' => ACTIVITY_POST,
'otype' => 'item',
'parent' => $parent,
'parent_uri' => $parent_item['uri']
));
}
// Store the comment signature information in case we need to relay to Diaspora
store_diaspora_comment_sig($datarray, $author, ($self ? $a->user['prvkey'] : false), $parent_item, $post_id);
} else {
$parent = $post_id;
if($contact_record != $author) {
notification(array(
'type' => NOTIFY_WALL,
'notify_flags' => $user['notify-flags'],
'language' => $user['language'],
'to_name' => $user['username'],
'to_email' => $user['email'],
'uid' => $user['uid'],
'item' => $datarray,
'link' => $a->get_baseurl().'/display/'.urlencode($datarray['guid']),
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
'verb' => ACTIVITY_POST,
'otype' => 'item'
));
}
}
// fallback so that parent always gets set to non-zero.
if(! $parent)
$parent = $post_id;
$r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1
WHERE `id` = %d",
intval($parent),
dbesc(($parent == $post_id) ? $uri : $parent_item['uri']),
dbesc($a->get_baseurl().'/display/'.urlencode($datarray['guid'])),
dbesc(datetime_convert()),
intval($post_id)
);
// photo comments turn the corresponding item visible to the profile wall
// This way we don't see every picture in your new photo album posted to your wall at once.
// They will show up as people comment on them.
if(! $parent_item['visible']) {
$r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
intval($parent_item['id'])
);
update_thread($parent_item['id']);
}
// update the commented timestamp on the parent
q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
@ -947,10 +950,8 @@ function item_post(&$a) {
dbesc(datetime_convert()),
intval($parent)
);
update_thread($parent);
$datarray['id'] = $post_id;
$datarray['plink'] = $a->get_baseurl().'/display/'.urlencode($datarray['guid']);
if ($post_id != $parent)
update_thread($parent);
call_hooks('post_local_end', $datarray);
@ -961,10 +962,10 @@ function item_post(&$a) {
$addr = trim($recip);
if(! strlen($addr))
continue;
$disclaimer = '<hr />' . sprintf( t('This message was sent to you by %s, a member of the Friendica social network.'),$a->user['username'])
$disclaimer = '<hr />' . sprintf( t('This message was sent to you by %s, a member of the Friendica social network.'),$a->user['username'])
. '<br />';
$disclaimer .= sprintf( t('You may visit them online at %s'), $a->get_baseurl() . '/profile/' . $a->user['nickname']) . EOL;
$disclaimer .= t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
$disclaimer .= t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
if (!$datarray['title']=='') {
$subject = email_header_encode($datarray['title'],'UTF-8');
} else {
@ -983,14 +984,16 @@ function item_post(&$a) {
'htmlVersion' => $message,
'textVersion' => html2plain($html.$disclaimer),
);
enotify::send($params);
Emailer::send($params);
}
}
}
create_tags_from_item($post_id);
create_files_from_item($post_id);
update_thread($post_id);
if ($post_id == $parent)
add_thread($post_id);
// This is a real juggling act on shared hosting services which kill your processes
// e.g. dreamhost. We used to start delivery to our native delivery agents in the background
@ -1040,10 +1043,9 @@ function item_content(&$a) {
$o = '';
if(($a->argc == 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) {
require_once('include/items.php');
$o = drop_item($a->argv[2], !is_ajax());
if (is_ajax()){
// ajax return: [<item id>, 0 (no perm) | <owner id>]
// ajax return: [<item id>, 0 (no perm) | <owner id>]
echo json_encode(array(intval($a->argv[2]), intval($o)));
killme();
}
@ -1052,9 +1054,9 @@ function item_content(&$a) {
}
/**
* This function removes the tag $tag from the text $body and replaces it with
* the appropiate link.
*
* This function removes the tag $tag from the text $body and replaces it with
* the appropiate link.
*
* @param unknown_type $body the text to replace the tag in
* @param unknown_type $inform a comma-seperated string containing everybody to inform
* @param unknown_type $str_tags string to add the tag to
@ -1068,29 +1070,6 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $netwo
$replaced = false;
$r = null;
//is it a hash tag?
if(strpos($tag,'#') === 0) {
//if the tag is replaced...
if(strpos($tag,'[url='))
//...do nothing
return $replaced;
//base tag has the tags name only
$basetag = str_replace('_',' ',substr($tag,1));
//create text for link
$newtag = '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
//replace tag by the link
$body = str_replace($tag, $newtag, $body);
$replaced = true;
//is the link already in str_tags?
if(! stristr($str_tags,$newtag)) {
//append or set str_tags
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= $newtag;
}
return $replaced;
}
//is it a person tag?
if(strpos($tag,'@') === 0) {
//is it already replaced?

View file

@ -22,7 +22,7 @@ function network_init(&$a) {
parse_str($query_string, $query_array);
array_shift($query_array);
// fetch last used network view and redirect if needed
if(! $is_a_date_query) {
$sel_tabs = network_query_get_sel_tab($a);
@ -627,7 +627,7 @@ die("ss");
}
else {
if( (! get_config('alt_pager', 'global')) && (! get_pconfig(local_user(),'system','alt_pager')) ) {
if(get_config('system', 'old_pager')) {
$r = q("SELECT COUNT(*) AS `total`
FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = $sql_table.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
@ -705,12 +705,16 @@ die("ss");
// Fetch a page full of parent items for this page
if($update) {
if (!get_config("system", "like_no_comment"))
$sql_extra4 = "(`item`.`deleted` = 0 OR `item`.`verb` = '".ACTIVITY_LIKE."' OR `item`.`verb` = '".ACTIVITY_DISLIKE."')";
else
$sql_extra4 = "`item`.`deleted` = 0 AND `item`.`verb` = '".ACTIVITY_POST."'";
$r = q("SELECT `item`.`parent` AS `item_id`, `item`.`network` AS `item_network`, `contact`.`uid` AS `contact_uid`
FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND
(`item`.`deleted` = 0 OR `item`.`verb` = '" . ACTIVITY_LIKE ."' OR `item`.`verb` = '" . ACTIVITY_DISLIKE . "')
and `item`.`moderated` = 0 and `item`.`unseen` = 1
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND $sql_extra4
AND `item`.`moderated` = 0 AND `item`.`unseen` = 1
$sql_extra3 $sql_extra $sql_nets ORDER BY `item_id` DESC LIMIT 100",
intval(local_user())
);
@ -815,10 +819,11 @@ die("ss");
$o .= conversation($a,$items,$mode,$update);
if(!$update) {
if( get_config('alt_pager', 'global') || get_pconfig(local_user(),'system','alt_pager') ) {
if(get_pconfig(local_user(),'system','infinite_scroll')) {
$o .= scroll_loader();
} elseif(!get_config('system', 'old_pager')) {
$o .= alt_pager($a,count($items));
}
else {
} else {
$o .= paginate($a);
}
}

View file

@ -1,30 +1,27 @@
<?php
function noscrape_init(&$a) {
if(get_config('system','disable_noscrape'))
killme();
if($a->argc > 1)
$which = $a->argv[1];
else
else
killme();
$profile = 0;
if((local_user()) && ($a->argc > 2) && ($a->argv[2] === 'view')) {
$which = $a->user['nickname'];
$profile = $a->argv[1];
}
profile_load($a,$which,$profile);
if(!$a->profile['net-publish'])
killme();
$keywords = ((x($a->profile,'pub_keywords')) ? $a->profile['pub_keywords'] : '');
$keywords = str_replace(array('#',',',' ',',,'),array('',' ',',',','),$keywords);
$keywords = explode(',', $keywords);
$json_info = array(
'fn' => $a->profile['name'],
'key' => $a->profile['pubkey'],
@ -33,19 +30,36 @@ function noscrape_init(&$a) {
'photo' => $a->profile['photo'],
'tags' => $keywords
);
if(is_array($a->profile) AND !$a->profile['hide-friends']) {
$r = q("SELECT `gcontact`.`updated` FROM `contact` INNER JOIN `gcontact` WHERE `gcontact`.`nurl` = `contact`.`nurl` AND `self` AND `uid` = %d LIMIT 1",
intval($a->profile['uid']));
if(count($r))
$json_info["updated"] = date("c", strtotime($r[0]['updated']));
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0
AND `network` IN ('%s', '%s', '%s', '')",
intval($a->profile['uid']),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_OSTATUS)
);
if(count($r))
$json_info["contacts"] = intval($r[0]['total']);
}
//These are optional fields.
$profile_fields = array('pdesc', 'locality', 'region', 'postal-code', 'country-name', 'gender', 'marital');
$profile_fields = array('pdesc', 'locality', 'region', 'postal-code', 'country-name', 'gender', 'marital', 'about');
foreach($profile_fields as $field)
if(!empty($a->profile[$field])) $json_info["$field"] = $a->profile[$field];
$dfrn_pages = array('request', 'confirm', 'notify', 'poll');
foreach($dfrn_pages as $dfrn)
$json_info["dfrn-{$dfrn}"] = $a->get_baseurl()."/dfrn_{$dfrn}/{$which}";
//Output all the JSON!
header('Content-type: application/json; charset=utf-8');
echo json_encode($json_info);
exit;
}

View file

@ -177,15 +177,19 @@ function notifications_content(&$a) {
$dfrn_text = '';
if($rr['network'] === NETWORK_DFRN || $rr['network'] === NETWORK_DIASPORA) {
if($rr['network'] === NETWORK_DFRN)
if($rr['network'] === NETWORK_DFRN) {
$knowyou = t('Claims to be known to you: ') . (($rr['knowyou']) ? t('yes') : t('no'));
else
$helptext = t('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: ');
} else {
$knowyou = '';
$helptext = t('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: ');
}
$dfrn_text = replace_macros($dfrn_tpl,array(
'$intro_id' => $rr['intro_id'],
'$friend_selected' => $friend_selected,
'$fan_selected' => $fan_selected,
'$approve_as' => t('Approve as: '),
'$approve_as' => $helptext,
'$as_friend' => t('Friend'),
'$as_fan' => (($rr['network'] == NETWORK_DIASPORA) ? t('Sharer') : t('Fan/Admirer'))
));

View file

@ -24,30 +24,30 @@ if(!function_exists('deletenode')) {
}
function completeurl($url, $scheme) {
$urlarr = parse_url($url);
$urlarr = parse_url($url);
if (isset($urlarr["scheme"]))
return($url);
if (isset($urlarr["scheme"]))
return($url);
$schemearr = parse_url($scheme);
$schemearr = parse_url($scheme);
$complete = $schemearr["scheme"]."://".$schemearr["host"];
$complete = $schemearr["scheme"]."://".$schemearr["host"];
if (@$schemearr["port"] != "")
$complete .= ":".$schemearr["port"];
if (@$schemearr["port"] != "")
$complete .= ":".$schemearr["port"];
if(strpos($urlarr['path'],'/') !== 0)
$complete .= '/';
$complete .= $urlarr["path"];
$complete .= $urlarr["path"];
if (@$urlarr["query"] != "")
$complete .= "?".$urlarr["query"];
if (@$urlarr["query"] != "")
$complete .= "?".$urlarr["query"];
if (@$urlarr["fragment"] != "")
$complete .= "#".$urlarr["fragment"];
if (@$urlarr["fragment"] != "")
$complete .= "#".$urlarr["fragment"];
return($complete);
return($complete);
}
function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $count = 1) {
@ -70,6 +70,8 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
$siteinfo["url"] = $url;
$siteinfo["type"] = "link";
$stamp1 = microtime(true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
@ -81,9 +83,11 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
$http_code = $curl_info['http_code'];
curl_close($ch);
$a->save_timestamp($stamp1, "network");
if ((($curl_info['http_code'] == "301") OR ($curl_info['http_code'] == "302") OR ($curl_info['http_code'] == "303") OR ($curl_info['http_code'] == "307"))
AND (($curl_info['redirect_url'] != "") OR ($curl_info['location'] != ""))) {
if ($curl_info['redirect_url'] != "")
@ -110,6 +114,8 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
if (($curl_info["content_type"] != "") AND !strstr(strtolower($curl_info["content_type"]),"html"))
return($siteinfo);
$stamp1 = microtime(true);
// Now fetch the body as well
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -121,9 +127,11 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
$http_code = $curl_info['http_code'];
curl_close($ch);
$a->save_timestamp($stamp1, "network");
// Fetch the first mentioned charset. Can be in body or header
$charset = "";
if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches))
@ -165,25 +173,25 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
$xpath = new DomXPath($doc);
$list = $xpath->query("//meta[@content]");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
if (@$attr["http-equiv"] == 'refresh') {
$path = $attr["content"];
$pathinfo = explode(";", $path);
$content = "";
foreach ($pathinfo AS $value) {
if (substr(strtolower($value), 0, 4) == "url=")
$content = substr($value, 4);
}
if ($content != "") {
$siteinfo = parseurl_getsiteinfo($content, $no_guessing, $do_oembed, ++$count);
return($siteinfo);
}
}
if (@$attr["http-equiv"] == 'refresh') {
$path = $attr["content"];
$pathinfo = explode(";", $path);
$content = "";
foreach ($pathinfo AS $value) {
if (substr(strtolower($value), 0, 4) == "url=")
$content = substr($value, 4);
}
if ($content != "") {
$siteinfo = parseurl_getsiteinfo($content, $no_guessing, $do_oembed, ++$count);
return($siteinfo);
}
}
}
//$list = $xpath->query("head/title");
@ -196,8 +204,8 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
@ -256,8 +264,8 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
@ -285,12 +293,12 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
}
if ((@$siteinfo["image"] == "") AND !$no_guessing) {
$list = $xpath->query("//img[@src]");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$list = $xpath->query("//img[@src]");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$src = completeurl($attr["src"], $url);
$photodata = @getimagesize($src);
@ -309,7 +317,7 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
"height"=>$photodata[1]);
}
}
}
} else {
$src = completeurl($siteinfo["image"], $url);
@ -399,6 +407,15 @@ function parse_url_content(&$a) {
}
}
// add url scheme if missing
$arrurl = parse_url($url);
if (!x($arrurl, 'scheme')) {
if (x($arrurl, 'host'))
$url = "http:".$url;
else
$url = "http://".$url;
}
logger('parse_url: ' . $url);
if($textmode)
@ -454,10 +471,7 @@ function parse_url_content(&$a) {
$sitedata = "";
if($siteinfo["title"] == "") {
$sitedata .= sprintf($template,$url,$url,'') . $str_tags;
killme();
} else {
if($siteinfo["title"] != "") {
$text = $siteinfo["text"];
$title = $siteinfo["title"];
}

View file

@ -102,7 +102,8 @@ function poco_init(&$a) {
intval($itemsPerPage)
);
} elseif($system_mode) {
$r = q("SELECT `contact`.*, `profile`.`about` AS `pabout`, `profile`.`locality` AS `plocation`, `profile`.`pub_keywords`, `profile`.`gender` AS `pgender`
$r = q("SELECT `contact`.*, `profile`.`about` AS `pabout`, `profile`.`locality` AS `plocation`, `profile`.`pub_keywords`, `profile`.`gender` AS `pgender`,
`profile`.`address` AS `paddress`, `profile`.`region` AS `pregion`, `profile`.`postal-code` AS `ppostalcode`, `profile`.`country-name` AS `pcountry`
FROM `contact` INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
WHERE `self` = 1 AND `network` IN ('%s', '%s', '%s', '%s', '') AND `profile`.`is-default`
AND `contact`.`uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) LIMIT %d, %d",
@ -134,9 +135,9 @@ function poco_init(&$a) {
if(x($_GET,'updatedSince') AND !$global)
$ret['updatedSince'] = false;
$ret['startIndex'] = (string) $startIndex;
$ret['itemsPerPage'] = (string) $itemsPerPage;
$ret['totalResults'] = (string) $totalResults;
$ret['startIndex'] = (int) $startIndex;
$ret['itemsPerPage'] = (int) $itemsPerPage;
$ret['totalResults'] = (int) $totalResults;
$ret['entry'] = array();
@ -151,7 +152,9 @@ function poco_init(&$a) {
'currentLocation' => false,
'network' => false,
'gender' => false,
'tags' => false
'tags' => false,
'address' => false,
'generation' => false
);
if((! x($_GET,'fields')) || ($_GET['fields'] === '@all'))
@ -166,11 +169,36 @@ function poco_init(&$a) {
if(is_array($r)) {
if(count($r)) {
foreach($r as $rr) {
if (!isset($rr['generation'])) {
if ($global)
$rr['generation'] = 3;
elseif ($system_mode)
$rr['generation'] = 1;
else
$rr['generation'] = 2;
}
if (($rr['about'] == "") AND isset($rr['pabout']))
$rr['about'] = $rr['pabout'];
if (($rr['location'] == "") AND isset($rr['plocation']))
$rr['location'] = $rr['plocation'];
if ($rr['location'] == "") {
if (isset($rr['plocation']))
$rr['location'] = $rr['plocation'];
if (isset($rr['pregion']) AND ($rr['pregion'] != "")) {
if ($rr['location'] != "")
$rr['location'] .= ", ";
$rr['location'] .= $rr['pregion'];
}
if (isset($rr['pcountry']) AND ($rr['pcountry'] != "")) {
if ($rr['location'] != "")
$rr['location'] .= ", ";
$rr['location'] .= $rr['pcountry'];
}
}
if (($rr['gender'] == "") AND isset($rr['pgender']))
$rr['gender'] = $rr['pgender'];
@ -180,7 +208,7 @@ function poco_init(&$a) {
$entry = array();
if($fields_ret['id'])
$entry['id'] = $rr['id'];
$entry['id'] = (int)$rr['id'];
if($fields_ret['displayName'])
$entry['displayName'] = $rr['name'];
if($fields_ret['aboutMe'])
@ -189,6 +217,8 @@ function poco_init(&$a) {
$entry['currentLocation'] = $rr['location'];
if($fields_ret['gender'])
$entry['gender'] = $rr['gender'];
if($fields_ret['generation'])
$entry['generation'] = (int)$rr['generation'];
if($fields_ret['urls']) {
$entry['urls'] = array(array('value' => $rr['url'], 'type' => 'profile'));
if($rr['addr'] && ($rr['network'] !== NETWORK_MAIL))
@ -235,6 +265,26 @@ function poco_init(&$a) {
$entry['tags'] = array($cleaned);
}
if($fields_ret['address']) {
$entry['address'] = array();
// Deactivated. It just reveals too much data. (Although its from the default profile)
//if (isset($rr['paddress']))
// $entry['address']['streetAddress'] = $rr['paddress'];
if (isset($rr['plocation']))
$entry['address']['locality'] = $rr['plocation'];
if (isset($rr['pregion']))
$entry['address']['region'] = $rr['pregion'];
// See above
//if (isset($rr['ppostalcode']))
// $entry['address']['postalCode'] = $rr['ppostalcode'];
if (isset($rr['pcountry']))
$entry['address']['country'] = $rr['pcountry'];
}
$ret['entry'][] = $entry;
}

View file

@ -246,7 +246,7 @@ function profile_content(&$a, $update = 0) {
$sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
}
if( (! get_config('alt_pager', 'global')) && (! get_pconfig($a->profile['profile_uid'],'system','alt_pager')) ) {
if(get_config('system', 'old_pager')) {
$r = q("SELECT COUNT(*) AS `total`
FROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
$sql_post_table INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
@ -331,7 +331,7 @@ function profile_content(&$a, $update = 0) {
if($is_owner) {
$r = q("UPDATE `item` SET `unseen` = 0
$r = q("UPDATE `item` SET `unseen` = 0
WHERE `wall` = 1 AND `unseen` = 1 AND `uid` = %d",
intval(local_user())
);
@ -340,10 +340,9 @@ function profile_content(&$a, $update = 0) {
$o .= conversation($a,$items,'profile',$update);
if(! $update) {
if( get_config('alt_pager', 'global') || get_pconfig($a->profile['profile_uid'],'system','alt_pager') ) {
if(!get_config('system', 'old_pager')) {
$o .= alt_pager($a,count($items));
}
else {
} else {
$o .= paginate($a);
}
}

View file

@ -485,10 +485,25 @@ function profiles_post(&$a) {
}
if($is_default) {
$location = $locality;
if ($region != "") {
if ($location != "")
$location .= ", ";
$location .= $region;
}
if ($country_name != "") {
if ($location != "")
$location .= ", ";
$location .= $country_name;
}
$r = q("UPDATE `contact` SET `about` = '%s', `location` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `self` = 1 AND `uid` = %d",
dbesc($about),
dbesc($locality),
dbesc($location),
dbesc($pub_keywords),
dbesc($gender),
intval(local_user())

View file

@ -127,71 +127,49 @@ function search_content(&$a) {
if (get_config('system','only_tag_search'))
$tag = true;
if($tag) {
$sql_extra = "";
$sql_table = sprintf("`item` INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d) AS `term` ON `item`.`id` = `term`.`oid` ",
dbesc(protect_sprintf($search)), intval(TERM_OBJ_POST), intval(TERM_HASHTAG));
$sql_order = "`item`.`id`";
} else {
if (get_config('system','use_fulltext_engine')) {
$sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
} else {
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
}
$sql_table = "`item`";
$sql_order = "`item`.`id`";
//$sql_order = "`item`.`received`";
}
// Here is the way permissions work in the search module...
// Only public posts can be shown
// OR your own posts if you are a logged in member
// No items will be shown if the member has a blocked profile wall.
if( (! get_config('alt_pager', 'global')) && (! get_pconfig(local_user(),'system','alt_pager')) ) {
$r = q("SELECT distinct(`item`.`uri`) as `total`
FROM $sql_table INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
INNER JOIN `user` ON `user`.`uid` = `item`.`uid`
WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `user`.`hidewall` = 0)
OR ( `item`.`uid` = %d ))
$sql_extra ",
intval(local_user())
);
// $sql_extra group by `item`.`uri` ",
if($tag) {
logger("Start tag search for '".$search."'", LOGGER_DEBUG);
if(count($r))
$a->set_pager_total(count($r));
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `term`
INNER JOIN `item` ON `item`.`id`=`term`.`oid`
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
AND (`term`.`uid` = 0 OR (`term`.`uid` = %d AND NOT `term`.`global`)) AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`term` = '%s'
ORDER BY term.created DESC LIMIT %d , %d ",
intval(local_user()), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search)),
intval($a->pager['start']), intval($a->pager['itemspage']));
} else {
logger("Start fulltext search for '".$search."'", LOGGER_DEBUG);
if(! count($r)) {
info( t('No results.') . EOL);
return $o;
}
if (get_config('system','use_fulltext_engine')) {
$sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
} else {
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
}
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
AND (`item`.`uid` = 0 OR (`item`.`uid` = %s AND (`item`.`private` OR NOT `item`.`network` IN ('%s', '%s', '%s'))))
$sql_extra
GROUP BY `item`.`uri` ORDER BY `item`.`id` DESC LIMIT %d , %d ",
intval(local_user()), dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA),
intval($a->pager['start']), intval($a->pager['itemspage']));
}
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`,
`user`.`nickname`, `user`.`uid`, `user`.`hidewall`
FROM $sql_table INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
INNER JOIN `user` ON `user`.`uid` = `item`.`uid`
WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `user`.`hidewall` = 0 )
OR ( `item`.`uid` = %d ))
$sql_extra GROUP BY `item`.`uri`
ORDER BY $sql_order DESC LIMIT %d , %d ",
intval(local_user()),
intval($a->pager['start']),
intval($a->pager['itemspage'])
);
// group by `item`.`uri`
if(! count($r)) {
info( t('No results.') . EOL);
return $o;
@ -203,14 +181,12 @@ function search_content(&$a) {
else
$o .= '<h2>Search results for: ' . $search . '</h2>';
logger("Start Conversation for '".$search."'", LOGGER_DEBUG);
$o .= conversation($a,$r,'search',false);
if( get_config('alt_pager', 'global') || get_pconfig(local_user(),'system','alt_pager') ) {
$o .= alt_pager($a,count($r));
}
else {
$o .= paginate($a);
}
$o .= alt_pager($a,count($r));
logger("Done '".$search."'", LOGGER_DEBUG);
return $o;
}

View file

@ -16,6 +16,11 @@ function get_theme_config_file($theme){
function settings_init(&$a) {
if(! local_user()) {
notice( t('Permission denied.') . EOL );
return;
}
// APC deactivated, since there are problems with PHP 5.5
//if (function_exists("apc_delete")) {
// $toDelete = new APCIterator('user', APC_ITER_VALUE);
@ -593,7 +598,7 @@ function settings_content(&$a) {
nav_set_selected('settings');
if(! local_user()) {
notice( t('Permission denied.') . EOL );
#notice( t('Permission denied.') . EOL );
return;
}

View file

@ -1,6 +1,6 @@
<?php
define( 'UPDATE_VERSION' , 1178 );
define( 'UPDATE_VERSION' , 1182 );
/**
*
@ -1630,3 +1630,21 @@ function update_1177() {
);
}
}
function update_1178() {
if (get_config('system','no_community_page'))
set_config('system','community_page_style', CP_NO_COMMUNITY_PAGE);
// Update the central item storage with uid=0
proc_run('php',"include/threadupdate.php");
return UPDATE_SUCCESS;
}
function update_1180() {
// Fill the new fields in the term table.
proc_run('php',"include/tagupdate.php");
return UPDATE_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -63,6 +63,13 @@ SQL="${Q1}${Q2}"
$MYSQL -uroot -proot -e "$SQL"
service mysql restart
#configure rudimentary mail server (local delivery only)
#add Friendica accounts for local user accounts, use email address like vagrant@friendica.dev, read the email with 'mail'.
debconf-set-selections <<< "postfix postfix/mailname string friendica.dev"
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
sudo apt-get install -y postfix mailutils libmailutils-dev
sudo echo -e "friendica1: vagrant\nfriendica2: vagrant\nfriendica3: vagrant\nfriendica4: vagrant\nfriendica5: vagrant" >> /etc/aliases && sudo newaliases
#make the vagrant directory the docroot
sudo rm -rf /var/www/
sudo ln -fs /vagrant /var/www

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -74,12 +74,12 @@ $a->strings["Hide this contact from others"] = "Skrýt tento kontakt před ostat
$a->strings["Replies/likes to your public posts <strong>may</strong> still be visible"] = "Odpovědi/Libí se na Vaše veřejné příspěvky <strong>mohou být</strong> stále viditelné";
$a->strings["Notification for new posts"] = "Upozornění na nové příspěvky";
$a->strings["Send a notification of every new post of this contact"] = "Poslat upozornění při každém novém příspěvku tohoto kontaktu";
$a->strings["Fetch further information for feeds"] = "Načíst další informace pro kanál";
$a->strings["Fetch further information for feeds"] = "Načítat další informace pro kanál";
$a->strings["Disabled"] = "Zakázáno";
$a->strings["Fetch information"] = "Načíst informace";
$a->strings["Fetch information and keywords"] = "Načíst informace a klíčová slova";
$a->strings["Fetch information"] = "Načítat informace";
$a->strings["Fetch information and keywords"] = "Načítat informace a klíčová slova";
$a->strings["Blacklisted keywords"] = "Zakázaná klíčová slova";
$a->strings["Comma separated list of keywords that should not be converted to hashtags, when \"Fetch information and keywords\" is selected"] = "";
$a->strings["Comma separated list of keywords that should not be converted to hashtags, when \"Fetch information and keywords\" is selected"] = "Čárkou oddělený seznam klíčových slov, které by neměly být převáděna na hashtagy, když je zvoleno \"Načítat informace a klíčová slova\"";
$a->strings["Suggestions"] = "Doporučení";
$a->strings["Suggest potential friends"] = "Navrhnout potenciální přátele";
$a->strings["All Contacts"] = "Všechny kontakty";
@ -245,7 +245,7 @@ $a->strings["Suggest Friends"] = "Navrhněte přátelé";
$a->strings["Suggest a friend for %s"] = "Navrhněte přátelé pro uživatele %s";
$a->strings["No valid account found."] = "Nenalezen žádný platný účet.";
$a->strings["Password reset request issued. Check your email."] = "Žádost o obnovení hesla vyřízena. Zkontrolujte Vaši e-mailovou schránku.";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "\n\t\tDrahý %1\$s,\n\t\t\tNa \"%2\$s\" jsme obdrželi požadavek na obnovu vašeho hesla \n\t\tpassword. Pro potvrzení žádosti prosím klikněte na zaslaný verifikační odkaz níže nebo si ho zkopírujte do adresní řádky prohlížeče.\n\n\t\tPokud jste tuto žádost nezasílaliI prosím na uvedený odkaz neklikejte a tento email smažte.\n\n\t\tVaše heslo nebude změněno dokud nebudeme moci oveřit, že jste autorem této žádosti.";
$a->strings["\n\t\tFollow this link to verify your identity:\n\n\t\t%1\$s\n\n\t\tYou will then receive a follow-up message containing the new password.\n\t\tYou may change that password from your account settings page after logging in.\n\n\t\tThe login details are as follows:\n\n\t\tSite Location:\t%2\$s\n\t\tLogin Name:\t%3\$s"] = "\n\t\tKlikněte na následující odkaz pro potvrzení Vaší identity:\n\n\t\t%1\$s\n\n\t\tNásledně obdržíte zprávu obsahující nové heslo.\n\t\tHeslo si můžete si změnit na stránce nastavení účtu poté, co se přihlásíte.\n\n\t\tVaše přihlašovací údaje jsou následující:\n\n\t\tUmístění webu:\t%2\$s\n\t\tPřihlašovací jméno:\t%3\$s";
$a->strings["Password reset requested at %s"] = "Na %s bylo zažádáno o resetování hesla";
$a->strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Žádost nemohla být ověřena. (Možná jste ji odeslali již dříve.) Obnovení hesla se nezdařilo.";
@ -384,6 +384,8 @@ $a->strings["New photo from this URL"] = "Nové foto z této URL adresy";
$a->strings["Remote Self"] = "Remote Self";
$a->strings["Mirror postings from this contact"] = "Zrcadlení správ od tohoto kontaktu";
$a->strings["Mark this contact as remote_self, this will cause friendica to repost new entries from this contact."] = "Označit tento kontakt jako \"remote_self\", s tímto nastavením freindica bude přeposílat všechny nové příspěvky od tohoto kontaktu.";
$a->strings["Login"] = "Přihlásit se";
$a->strings["The post was created"] = "Příspěvek byl vytvořen";
$a->strings["Access denied."] = "Přístup odmítnut";
$a->strings["People Search"] = "Vyhledávání lidí";
$a->strings["No matches"] = "Žádné shody";
@ -397,8 +399,11 @@ $a->strings["Plugins"] = "Pluginy";
$a->strings["Themes"] = "Témata";
$a->strings["DB updates"] = "Aktualizace databáze";
$a->strings["Logs"] = "Logy";
$a->strings["probe address"] = "vyzkoušet adresu";
$a->strings["check webfinger"] = "vyzkoušet webfinger";
$a->strings["Admin"] = "Administrace";
$a->strings["Plugin Features"] = "Funkčnosti rozšíření";
$a->strings["diagnostics"] = "diagnostika";
$a->strings["User registrations waiting for confirmation"] = "Registrace uživatele čeká na potvrzení";
$a->strings["Normal Account"] = "Normální účet";
$a->strings["Soapbox Account"] = "Soapbox účet";
@ -416,6 +421,9 @@ $a->strings["Active plugins"] = "Aktivní pluginy";
$a->strings["Can not parse base url. Must have at least <scheme>://<domain>"] = "Nelze zpracovat výchozí url adresu. Musí obsahovat alespoň <schéma>://<doméma>";
$a->strings["Site settings updated."] = "Nastavení webu aktualizováno.";
$a->strings["No special theme for mobile devices"] = "žádné speciální téma pro mobilní zařízení";
$a->strings["No community page"] = "Komunitní stránka neexistuje";
$a->strings["Public postings from users of this site"] = "Počet veřejných příspěvků od uživatele na této stránce";
$a->strings["Global community page"] = "Globální komunitní stránka";
$a->strings["At post arrival"] = "Při obdržení příspěvku";
$a->strings["Frequently"] = "Často";
$a->strings["Hourly"] = "každou hodinu";
@ -436,8 +444,11 @@ $a->strings["Advanced"] = "Pokročilé";
$a->strings["Performance"] = "Výkonnost";
$a->strings["Relocate - WARNING: advanced function. Could make this server unreachable."] = "Změna umístění - Varování: pokročilá funkčnost. Tímto můžete znepřístupnit server.";
$a->strings["Site name"] = "Název webu";
$a->strings["Host name"] = "";
$a->strings["Host name"] = "Jméno hostitele (host name)";
$a->strings["Sender Email"] = "Email ddesílatele";
$a->strings["Banner/Logo"] = "Banner/logo";
$a->strings["Shortcut icon"] = "Ikona zkratky";
$a->strings["Touch icon"] = "Dotyková ikona";
$a->strings["Additional Info"] = "Dodatečné informace";
$a->strings["For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo."] = "Pro veřejné servery: zde můžete doplnit dodatečné informace, které budou uvedeny v seznamu na dir.friendica.com/siteinfo.";
$a->strings["System language"] = "Systémový jazyk";
@ -448,7 +459,7 @@ $a->strings["Theme for mobile devices"] = "Téma zobrazení pro mobilní zaříz
$a->strings["SSL link policy"] = "Politika SSL odkazů";
$a->strings["Determines whether generated links should be forced to use SSL"] = "Určuje, zda-li budou generované odkazy používat SSL";
$a->strings["Force SSL"] = "Vynutit SSL";
$a->strings["Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops."] = "";
$a->strings["Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops."] = "Vynutit SSL pro všechny ne-SSL žádosti - Upozornění: na některých systémech může dojít k nekonečnému zacyklení.";
$a->strings["Old style 'Share'"] = "Sdílení \"postaru\"";
$a->strings["Deactivates the bbcode element 'share' for repeating items."] = "Deaktivovat bbcode element \"share\" pro opakující se položky.";
$a->strings["Hide help entry from navigation menu"] = "skrýt nápovědu z navigačního menu";
@ -498,8 +509,10 @@ $a->strings["Fullname check"] = "kontrola úplného jména";
$a->strings["Force users to register with a space between firstname and lastname in Full name, as an antispam measure"] = "Přimět uživatele k registraci s mezerou mezi jménu a příjmením v poli Celé jméno, jako antispamové opatření.";
$a->strings["UTF-8 Regular expressions"] = "UTF-8 Regulární výrazy";
$a->strings["Use PHP UTF8 regular expressions"] = "Použít PHP UTF8 regulární výrazy.";
$a->strings["Show Community Page"] = "Zobrazit stránku komunity";
$a->strings["Display a Community page showing all recent public postings on this site."] = "Zobrazit Komunitní stránku zobrazující všechny veřejné příspěvky napsané na této stránce.";
$a->strings["Community Page Style"] = "Styl komunitní stránky";
$a->strings["Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."] = "Typ komunitní stránky k zobrazení. 'Glogální komunita' zobrazuje každý veřejný příspěvek z otevřené distribuované sítě, která dorazí na tento server.";
$a->strings["Posts per user on community page"] = "Počet příspěvků na komunitní stránce";
$a->strings["The maximum number of posts per user on the community page. (Not valid for 'Global Community')"] = "Maximální počet příspěvků na uživatele na komunitní sptránce. (neplatí pro 'Globální komunitu')";
$a->strings["Enable OStatus support"] = "Zapnout podporu OStatus";
$a->strings["Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed."] = "Poskytnout zabudouvanou kompatibilitu s OStatus (StatusNet, GNU Social apod.). Veškerá komunikace s OStatus je veřejná, proto bude občas zobrazeno upozornění.";
$a->strings["OStatus conversation completion interval"] = "Interval dokončení konverzace OStatus";
@ -524,6 +537,8 @@ $a->strings["Use MySQL full text engine"] = "Použít fulltextový vyhledávací
$a->strings["Activates the full text engine. Speeds up search - but can only search for four and more characters."] = "Aktivuje fulltextový vyhledávací stroj. Zrychluje vyhledávání ale pouze pro vyhledávání čtyř a více znaků";
$a->strings["Suppress Language"] = "Potlačit Jazyk";
$a->strings["Suppress language information in meta information about a posting."] = "Potlačit jazykové informace v meta informacích o příspěvcích";
$a->strings["Suppress Tags"] = "Potlačit štítky";
$a->strings["Suppress showing a list of hashtags at the end of the posting."] = "Potlačit zobrazení listu hastagů na konci zprávy.";
$a->strings["Path to item cache"] = "Cesta k položkám vyrovnávací paměti";
$a->strings["Cache duration in seconds"] = "Doba platnosti vyrovnávací paměti v sekundách";
$a->strings["How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1."] = "Jak dlouho by měla vyrovnávací paměť držet data? Výchozí hodnota je 86400 sekund (Jeden den). Pro vypnutí funkce vyrovnávací paměti nastavte hodnotu na -1.";
@ -534,9 +549,11 @@ $a->strings["Temp path"] = "Cesta k dočasným souborům";
$a->strings["Base path to installation"] = "Základní cesta k instalaci";
$a->strings["Disable picture proxy"] = "Vypnutí obrázkové proxy";
$a->strings["The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith."] = "Obrázková proxi zvyšuje výkonnost a soukromí. Neměla by být použita na systémech s pomalým připojením k síti.";
$a->strings["Enable old style pager"] = "Aktivovat \"old style\" stránkování ";
$a->strings["The old style pager has page numbers but slows down massively the page speed."] = " \"old style\" stránkování zobrazuje čísla stránek ale značně zpomaluje rychlost stránky.";
$a->strings["Only search in tags"] = "Hledat pouze ve štítkách";
$a->strings["On large systems the text search can slow down the system extremely."] = "Textové vyhledávání může u rozsáhlých systémů znamenat velmi citelné zpomalení systému.";
$a->strings["New base url"] = "Nová výchozí url adresa";
$a->strings["Disable noscrape"] = "";
$a->strings["The noscrape feature speeds up directory submissions by using JSON data instead of HTML scraping. Disabling it will cause higher load on your server and the directory server."] = "";
$a->strings["Update has been marked successful"] = "Aktualizace byla označena jako úspěšná.";
$a->strings["Database structure update %s was successfully applied."] = "Aktualizace struktury databáze %s byla úspěšně aplikována.";
$a->strings["Executing of database structure update %s failed with error: %s"] = "Provádění aktualizace databáze %s skončilo chybou: %s";
@ -551,7 +568,7 @@ $a->strings["This does not include updates prior to 1139, which did not return a
$a->strings["Mark success (if update was manually applied)"] = "Označit za úspěšné (pokud byla aktualizace aplikována manuálně)";
$a->strings["Attempt to execute this update step automatically"] = "Pokusit se provést tuto aktualizaci automaticky.";
$a->strings["\n\t\t\tDear %1\$s,\n\t\t\t\tthe administrator of %2\$s has set up an account for you."] = "\n\t\t\tDrahý %1\$s,\n\t\t\t\tadministrátor webu %2\$s pro Vás vytvořil uživatelský účet.";
$a->strings["\n\t\t\tThe login details are as follows:\n\n\t\t\tSite Location:\t%1\$s\n\t\t\tLogin Name:\t\t%2\$s\n\t\t\tPassword:\t\t%3\$s\n\n\t\t\tYou may change your password from your account \"Settings\" page after logging\n\t\t\tin.\n\n\t\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\t\tYou may also wish to add some basic information to your default profile\n\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\t\tWe recommend setting your full name, adding a profile photo,\n\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\t\tthan that.\n\n\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\t\tIf you are new and do not know anybody here, they may help\n\t\t\tyou to make some new and interesting friends.\n\n\t\t\tThank you and welcome to %4\$s."] = "";
$a->strings["\n\t\t\tThe login details are as follows:\n\n\t\t\tSite Location:\t%1\$s\n\t\t\tLogin Name:\t\t%2\$s\n\t\t\tPassword:\t\t%3\$s\n\n\t\t\tYou may change your password from your account \"Settings\" page after logging\n\t\t\tin.\n\n\t\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\t\tYou may also wish to add some basic information to your default profile\n\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\t\tWe recommend setting your full name, adding a profile photo,\n\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\t\tthan that.\n\n\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\t\tIf you are new and do not know anybody here, they may help\n\t\t\tyou to make some new and interesting friends.\n\n\t\t\tThank you and welcome to %4\$s."] = "\n\t\t\tVaše přihlašovací údaje jsou následující:\n\n\t\t\tAdresa webu: \t%1\$s\n\t\t\tpřihlašovací jméno:\t\t%2\$s\n\t\t\theslo:\t\t%3\$s\n\n\t\t\tHeslo si můžete změnit na stránce \"Nastavení\" vašeho účtu poté, co se přihlásíte.\n\n\t\t\tProsím věnujte pár chvil revizi dalšího nastavení vašeho účtu na dané stránce.\n\n\t\t\tTaké su můžete přidat nějaké základní informace do svého výchozího profilu (na stránce \"Profily\"), takže ostatní lidé vás snáze najdou. \n\n\t\t\tDoporučujeme Vám uvést celé jméno a i foto. Přidáním nějakých \"klíčových slov\" (velmi užitečné pro hledání nových přátel) a možná také zemi, ve které žijete, pokud nechcete být více konkrétní.\n\n\t\t\tPlně resepktujeme vaše právo na soukromí a nic z výše uvedeného není povinné. Pokud jste zde nový a neznáte zde nikoho, uvedením daných informací můžete získat nové přátele.\n\n\t\t\tDíky a vítejte na %4\$s.";
$a->strings["Registration details for %s"] = "Registrační údaje pro %s";
$a->strings["%s user blocked/unblocked"] = array(
0 => "%s uživatel blokován/odblokován",
@ -881,7 +898,7 @@ $a->strings["No"] = "Ne";
$a->strings["Publish your default profile in the global social directory?"] = "Publikovat Váš výchozí profil v globální sociálním adresáři?";
$a->strings["Hide your contact/friend list from viewers of your default profile?"] = "Skrýt Vaše kontaktní údaje a seznam přátel před návštěvníky ve Vašem výchozím profilu?";
$a->strings["Hide your profile details from unknown viewers?"] = "Skrýt Vaše profilové detaily před neznámými uživateli?";
$a->strings["If enabled, posting public messages to Diaspora and other networks isn't possible."] = "";
$a->strings["If enabled, posting public messages to Diaspora and other networks isn't possible."] = "Pokud je povoleno, není možné zasílání veřejných příspěvků do Diaspory a dalších sítí.";
$a->strings["Allow friends to post to your profile page?"] = "Povolit přátelům umisťování příspěvků na vaši profilovou stránku?";
$a->strings["Allow friends to tag your posts?"] = "Povolit přátelům označovat Vaše příspěvky?";
$a->strings["Allow us to suggest you as a potential friend to new members?"] = "Chcete nám povolit abychom vás navrhovali jako přátelé pro nové členy?";
@ -937,7 +954,7 @@ $a->strings["You receive a friend suggestion"] = "Obdržel jste návrh přátels
$a->strings["You are tagged in a post"] = "Jste označen v příspěvku";
$a->strings["You are poked/prodded/etc. in a post"] = "Byl Jste šťouchnout v příspěvku";
$a->strings["Text-only notification emails"] = "Pouze textové notifikační e-maily";
$a->strings["Send text only notification emails, without the html part"] = "";
$a->strings["Send text only notification emails, without the html part"] = "Posílat pouze textové notifikační e-maily, bez html části.";
$a->strings["Advanced Account/Page Type Settings"] = "Pokročilé nastavení účtu/stránky";
$a->strings["Change the behaviour of this account for special situations"] = "Změnit chování tohoto účtu ve speciálních situacích";
$a->strings["Relocate"] = "Změna umístění";
@ -986,7 +1003,7 @@ $a->strings[" - please do not use this form. Instead, enter %s into your Diaspo
$a->strings["Your Identity Address:"] = "Verze PHP pro příkazový řádek na Vašem systému nemá povolen \"register_argc_argv\".";
$a->strings["Submit Request"] = "Odeslat žádost";
$a->strings["Registration successful. Please check your email for further instructions."] = "Registrace úspěšná. Zkontrolujte prosím svůj e-mail pro další instrukce.";
$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "";
$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "Nepovedlo se odeslat emailovou zprávu. Zde jsou detaily Vašeho účtu:<br> login: %s<br> heslo: %s<br><br>Své heslo můžete změnit po přihlášení.";
$a->strings["Your registration can not be processed."] = "Vaši registraci nelze zpracovat.";
$a->strings["Your registration is pending approval by the site owner."] = "Vaše registrace čeká na schválení vlastníkem serveru.";
$a->strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Došlo k překročení maximálního povoleného počtu registrací za den na tomto serveru. Zkuste to zítra znovu.";
@ -1243,7 +1260,6 @@ $a->strings["show fewer"] = "zobrazit méně";
$a->strings["Update %s failed. See error logs."] = "Aktualizace %s selhala. Zkontrolujte protokol chyb.";
$a->strings["Create a New Account"] = "Vytvořit nový účet";
$a->strings["Logout"] = "Odhlásit se";
$a->strings["Login"] = "Přihlásit se";
$a->strings["Nickname or Email address: "] = "Přezdívka nebo e-mailová adresa:";
$a->strings["Password: "] = "Heslo: ";
$a->strings["Remember me"] = "Pamatuj si mne";
@ -1569,6 +1585,7 @@ $a->strings["Apps"] = "Aplikace";
$a->strings["Addon applications, utilities, games"] = "Doplňkové aplikace, nástroje, hry";
$a->strings["Search site content"] = "Hledání na stránkách tohoto webu";
$a->strings["Conversations on this site"] = "Konverzace na tomto webu";
$a->strings["Conversations on the network"] = "Konverzace v síti";
$a->strings["Directory"] = "Adresář";
$a->strings["People directory"] = "Adresář";
$a->strings["Information"] = "Informace";
@ -1591,9 +1608,9 @@ $a->strings["Site setup and configuration"] = "Nastavení webu a konfigurace";
$a->strings["Navigation"] = "Navigace";
$a->strings["Site map"] = "Mapa webu";
$a->strings["User not found."] = "Uživatel nenalezen";
$a->strings["Daily posting limit of %d posts reached. The post was rejected."] = "";
$a->strings["Weekly posting limit of %d posts reached. The post was rejected."] = "";
$a->strings["Monthly posting limit of %d posts reached. The post was rejected."] = "";
$a->strings["Daily posting limit of %d posts reached. The post was rejected."] = "Bylo dosaženo denního limitu %d odeslaných příspěvků. Příspěvek byl odmítnut.";
$a->strings["Weekly posting limit of %d posts reached. The post was rejected."] = "Bylo týdenního limitu %d odeslaných příspěvků. Příspěvek byl odmítnut.";
$a->strings["Monthly posting limit of %d posts reached. The post was rejected."] = "Bylo dosaženo měsíčního limitu %d odeslaných příspěvků. Příspěvek byl odmítnut.";
$a->strings["There is no status with this id."] = "Není tu žádný status s tímto id.";
$a->strings["There is no conversation with this id."] = "Nemáme žádnou konverzaci s tímto id.";
$a->strings["Invalid request."] = "Neplatný požadavek.";
@ -1618,7 +1635,7 @@ $a->strings["An error occurred during registration. Please try again."] = "Došl
$a->strings["An error occurred creating your default profile. Please try again."] = "Došlo k chybě při vytváření Vašeho výchozího profilu. Zkuste to prosím znovu.";
$a->strings["Friends"] = "Přátelé";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tThank you for registering at %2\$s. Your account has been created.\n\t"] = "\n\t\tDrahý %1\$s,\n\t\t\tDěkujeme Vám za registraci na %2\$s. Váš účet byl vytvořen.\n\t";
$a->strings["\n\t\tThe login details are as follows:\n\t\t\tSite Location:\t%3\$s\n\t\t\tLogin Name:\t%1\$s\n\t\t\tPassword:\t%5\$s\n\n\t\tYou may change your password from your account \"Settings\" page after logging\n\t\tin.\n\n\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\tYou may also wish to add some basic information to your default profile\n\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\tWe recommend setting your full name, adding a profile photo,\n\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\tthan that.\n\n\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\tIf you are new and do not know anybody here, they may help\n\t\tyou to make some new and interesting friends.\n\n\n\t\tThank you and welcome to %2\$s."] = "";
$a->strings["\n\t\tThe login details are as follows:\n\t\t\tSite Location:\t%3\$s\n\t\t\tLogin Name:\t%1\$s\n\t\t\tPassword:\t%5\$s\n\n\t\tYou may change your password from your account \"Settings\" page after logging\n\t\tin.\n\n\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\tYou may also wish to add some basic information to your default profile\n\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\tWe recommend setting your full name, adding a profile photo,\n\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\tthan that.\n\n\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\tIf you are new and do not know anybody here, they may help\n\t\tyou to make some new and interesting friends.\n\n\n\t\tThank you and welcome to %2\$s."] = "\n\t\tVaše přihlašovací údaje jsou následující:\n\t\t\tAdresa webu:\t%3\$s\n\t\t\tpřihlašovací jméno:\t%1\$s\n\t\t\theslo:\t%5\$s\n\n\t\tHeslo si můžete změnit na stránce \"Nastavení\" vašeho účtu poté, co se přihlásíte.\n\n\t\tProsím věnujte pár chvil revizi dalšího nastavení vašeho účtu na dané stránce.\n\n\t\tTaké su můžete přidat nějaké základní informace do svého výchozího profilu (na stránce \"Profily\"), takže ostatní lidé vás snáze najdou.\n\n\t\tDoporučujeme Vám uvést celé jméno a i foto. Přidáním nějakých \"klíčových slov\" (velmi užitečné pro hledání nových přátel) a možná také zemi, ve které žijete, pokud nechcete být více konkrétní.\n\n\t\tPlně resepktujeme vaše právo na soukromí a nic z výše uvedeného není povinné.\n\t\tPokud jste zde nový a neznáte zde nikoho, uvedením daných informací můžete získat nové přátele.\n\n\n\t\tDíky a vítejte na %2\$s.";
$a->strings["Sharing notification from Diaspora network"] = "Sdílení oznámení ze sítě Diaspora";
$a->strings["Attachments:"] = "Přílohy:";
$a->strings["Do you really want to delete this item?"] = "Opravdu chcete smazat tuto položku?";
@ -1784,10 +1801,10 @@ $a->strings["Local Directory"] = "Lokální Adresář";
$a->strings["Set zoomfactor for Earth Layers"] = "Nastavit faktor přiblížení pro Earth Layers";
$a->strings["Show/hide boxes at right-hand column:"] = "Zobrazit/skrýt boxy na pravém sloupci:";
$a->strings["Set style"] = "Nastavit styl";
$a->strings["greenzero"] = "";
$a->strings["purplezero"] = "";
$a->strings["easterbunny"] = "";
$a->strings["darkzero"] = "";
$a->strings["comix"] = "";
$a->strings["slackr"] = "";
$a->strings["Variations"] = "";
$a->strings["greenzero"] = "zelená nula";
$a->strings["purplezero"] = "fialová nula";
$a->strings["easterbunny"] = "velikonoční zajíček";
$a->strings["darkzero"] = "tmavá nula";
$a->strings["comix"] = "komiksová";
$a->strings["slackr"] = "flákač";
$a->strings["Variations"] = "Variace";

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,7 @@ $a->strings["Contact has been ignored"] = "Kontakt wurde ignoriert";
$a->strings["Contact has been unignored"] = "Kontakt wird nicht mehr ignoriert";
$a->strings["Contact has been archived"] = "Kontakt wurde archiviert";
$a->strings["Contact has been unarchived"] = "Kontakt wurde aus dem Archiv geholt";
$a->strings["Do you really want to delete this contact?"] = "Möchtest du wirklich diesen Kontakt löschen?";
$a->strings["Do you really want to delete this contact?"] = "Möchtest Du wirklich diesen Kontakt löschen?";
$a->strings["Yes"] = "Ja";
$a->strings["Cancel"] = "Abbrechen";
$a->strings["Contact has been removed."] = "Kontakt wurde entfernt.";
@ -53,7 +53,7 @@ $a->strings["Communications lost with this contact!"] = "Verbindungen mit diesem
$a->strings["Contact Editor"] = "Kontakt Editor";
$a->strings["Submit"] = "Senden";
$a->strings["Profile Visibility"] = "Profil-Sichtbarkeit";
$a->strings["Please choose the profile you would like to display to %s when viewing your profile securely."] = "Bitte wähle eines deiner Profile das angezeigt werden soll, wenn %s dein Profil aufruft.";
$a->strings["Please choose the profile you would like to display to %s when viewing your profile securely."] = "Bitte wähle eines Deiner Profile das angezeigt werden soll, wenn %s Dein Profil aufruft.";
$a->strings["Contact Information / Notes"] = "Kontakt Informationen / Notizen";
$a->strings["Edit contact notes"] = "Notizen zum Kontakt bearbeiten";
$a->strings["Visit %s's profile [%s]"] = "Besuche %ss Profil [%s]";
@ -62,22 +62,22 @@ $a->strings["Ignore contact"] = "Ignoriere den Kontakt";
$a->strings["Repair URL settings"] = "URL Einstellungen reparieren";
$a->strings["View conversations"] = "Unterhaltungen anzeigen";
$a->strings["Delete contact"] = "Lösche den Kontakt";
$a->strings["Last update:"] = "letzte Aktualisierung:";
$a->strings["Last update:"] = "Letzte Aktualisierung: ";
$a->strings["Update public posts"] = "Öffentliche Beiträge aktualisieren";
$a->strings["Update now"] = "Jetzt aktualisieren";
$a->strings["Currently blocked"] = "Derzeit geblockt";
$a->strings["Currently ignored"] = "Derzeit ignoriert";
$a->strings["Currently archived"] = "Momentan archiviert";
$a->strings["Hide this contact from others"] = "Verberge diesen Kontakt vor anderen";
$a->strings["Hide this contact from others"] = "Verbirg diesen Kontakt von anderen";
$a->strings["Replies/likes to your public posts <strong>may</strong> still be visible"] = "Antworten/Likes auf deine öffentlichen Beiträge <strong>könnten</strong> weiterhin sichtbar sein";
$a->strings["Notification for new posts"] = "Benachrichtigung bei neuen Beiträgen";
$a->strings["Send a notification of every new post of this contact"] = "Sende eine Benachrichtigung wann immer dieser Kontakt einen neuen Beitrag schreibt.";
$a->strings["Send a notification of every new post of this contact"] = "Sende eine Benachrichtigung, wann immer dieser Kontakt einen neuen Beitrag schreibt.";
$a->strings["Fetch further information for feeds"] = "Weitere Informationen zu Feeds holen";
$a->strings["Disabled"] = "Deaktiviert";
$a->strings["Fetch information"] = "Beziehe Information";
$a->strings["Fetch information and keywords"] = "Beziehe Information und Schlüsselworte";
$a->strings["Blacklisted keywords"] = "Blacklistete Schlüsselworte ";
$a->strings["Comma separated list of keywords that should not be converted to hashtags, when \"Fetch information and keywords\" is selected"] = "Komma-Separierte Liste mit Schlüsselworten die nicht in Hashtags konvertiert werden wenn \"Beziehe Information und Schlüsselworte\" aktiviert wurde";
$a->strings["Comma separated list of keywords that should not be converted to hashtags, when \"Fetch information and keywords\" is selected"] = "Komma-Separierte Liste mit Schlüsselworten, die nicht in Hashtags konvertiert werden, wenn \"Beziehe Information und Schlüsselworte\" aktiviert wurde";
$a->strings["Suggestions"] = "Kontaktvorschläge";
$a->strings["Suggest potential friends"] = "Freunde vorschlagen";
$a->strings["All Contacts"] = "Alle Kontakte";
@ -94,7 +94,7 @@ $a->strings["Hidden"] = "Verborgen";
$a->strings["Only show hidden contacts"] = "Nur verborgene Kontakte anzeigen";
$a->strings["Mutual Friendship"] = "Beidseitige Freundschaft";
$a->strings["is a fan of yours"] = "ist ein Fan von dir";
$a->strings["you are a fan of"] = "du bist Fan von";
$a->strings["you are a fan of"] = "Du bist Fan von";
$a->strings["Edit contact"] = "Kontakt bearbeiten";
$a->strings["Contacts"] = "Kontakte";
$a->strings["Search your contacts"] = "Suche in deinen Kontakten";
@ -104,7 +104,7 @@ $a->strings["Update"] = "Aktualisierungen";
$a->strings["Delete"] = "Löschen";
$a->strings["No profile"] = "Kein Profil";
$a->strings["Manage Identities and/or Pages"] = "Verwalte Identitäten und/oder Seiten";
$a->strings["Toggle between different identities or community/group pages which share your account details or which you have been granted \"manage\" permissions"] = "Zwischen verschiedenen Identitäten oder Gemeinschafts-/Gruppenseiten wechseln, die deine Kontoinformationen teilen oder zu denen du „Verwalten“-Befugnisse bekommen hast.";
$a->strings["Toggle between different identities or community/group pages which share your account details or which you have been granted \"manage\" permissions"] = "Zwischen verschiedenen Identitäten oder Gemeinschafts-/Gruppenseiten wechseln, die Deine Kontoinformationen teilen oder zu denen Du „Verwalten“-Befugnisse bekommen hast.";
$a->strings["Select an identity to manage: "] = "Wähle eine Identität zum Verwalten aus: ";
$a->strings["Post successful."] = "Beitrag erfolgreich veröffentlicht.";
$a->strings["Permission denied"] = "Zugriff verweigert";
@ -120,37 +120,37 @@ $a->strings["Access to this profile has been restricted."] = "Der Zugriff zu die
$a->strings["Item has been removed."] = "Eintrag wurde entfernt.";
$a->strings["Welcome to Friendica"] = "Willkommen bei Friendica";
$a->strings["New Member Checklist"] = "Checkliste für neue Mitglieder";
$a->strings["We would like to offer some tips and links to help make your experience enjoyable. Click any item to visit the relevant page. A link to this page will be visible from your home page for two weeks after your initial registration and then will quietly disappear."] = "Wir möchten dir einige Tipps und Links anbieten, die dir helfen könnten, den Einstieg angenehmer zu machen. Klicke auf ein Element, um die entsprechende Seite zu besuchen. Ein Link zu dieser Seite hier bleibt für dich an Deiner Pinnwand für zwei Wochen nach dem Registrierungsdatum sichtbar und wird dann verschwinden.";
$a->strings["We would like to offer some tips and links to help make your experience enjoyable. Click any item to visit the relevant page. A link to this page will be visible from your home page for two weeks after your initial registration and then will quietly disappear."] = "Wir möchten Dir einige Tipps und Links anbieten, die Dir helfen könnten, den Einstieg angenehmer zu machen. Klicke auf ein Element, um die entsprechende Seite zu besuchen. Ein Link zu dieser Seite hier bleibt für Dich an Deiner Pinnwand für zwei Wochen nach dem Registrierungsdatum sichtbar und wird dann verschwinden.";
$a->strings["Getting Started"] = "Einstieg";
$a->strings["Friendica Walk-Through"] = "Friendica Rundgang";
$a->strings["On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join."] = "Auf der <em>Quick Start</em> Seite findest du eine kurze Einleitung in die einzelnen Funktionen deines Profils und die Netzwerk-Reiter, wo du interessante Foren findest und neue Kontakte knüpfst.";
$a->strings["On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join."] = "Auf der <em>Quick Start</em> Seite findest Du eine kurze Einleitung in die einzelnen Funktionen Deines Profils und die Netzwerk-Reiter, wo Du interessante Foren findest und neue Kontakte knüpfst.";
$a->strings["Settings"] = "Einstellungen";
$a->strings["Go to Your Settings"] = "Gehe zu deinen Einstellungen";
$a->strings["On your <em>Settings</em> page - change your initial password. Also make a note of your Identity Address. This looks just like an email address - and will be useful in making friends on the free social web."] = "Ändere bitte unter <em>Einstellungen</em> dein Passwort. Außerdem merke dir deine Identifikationsadresse. Diese sieht aus wie eine E-Mail-Adresse und wird benötigt, um Freundschaften mit anderen im Friendica Netzwerk zu schliessen.";
$a->strings["Review the other settings, particularly the privacy settings. An unpublished directory listing is like having an unlisted phone number. In general, you should probably publish your listing - unless all of your friends and potential friends know exactly how to find you."] = "Überprüfe die restlichen Einstellungen, insbesondere die Einstellungen zur Privatsphäre. Wenn du dein Profil nicht veröffentlichst, ist das als wenn du deine Telefonnummer nicht ins Telefonbuch einträgst. Im Allgemeinen solltest du es veröffentlichen - außer all deine Freunde und potentiellen Freunde wissen genau, wie sie dich finden können.";
$a->strings["Review the other settings, particularly the privacy settings. An unpublished directory listing is like having an unlisted phone number. In general, you should probably publish your listing - unless all of your friends and potential friends know exactly how to find you."] = "Überprüfe die restlichen Einstellungen, insbesondere die Einstellungen zur Privatsphäre. Wenn Du Dein Profil nicht veröffentlichst, ist das als wenn Du Deine Telefonnummer nicht ins Telefonbuch einträgst. Im Allgemeinen solltest Du es veröffentlichen - außer all Deine Freunde und potentiellen Freunde wissen genau, wie sie Dich finden können.";
$a->strings["Upload Profile Photo"] = "Profilbild hochladen";
$a->strings["Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not."] = "Lade ein Profilbild hoch falls du es noch nicht getan hast. Studien haben gezeigt, dass es zehnmal wahrscheinlicher ist neue Freunde zu finden, wenn du ein Bild von dir selbst verwendest, als wenn du dies nicht tust.";
$a->strings["Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not."] = "Lade ein Profilbild hoch, falls Du es noch nicht getan hast. Studien haben gezeigt, dass es zehnmal wahrscheinlicher ist neue Freunde zu finden, wenn Du ein Bild von Dir selbst verwendest, als wenn Du dies nicht tust.";
$a->strings["Edit Your Profile"] = "Editiere dein Profil";
$a->strings["Edit your <strong>default</strong> profile to your liking. Review the settings for hiding your list of friends and hiding the profile from unknown visitors."] = "Editiere dein <strong>Standard</strong> Profil nach deinen Vorlieben. Überprüfe die Einstellungen zum Verbergen deiner Freundesliste vor unbekannten Betrachtern des Profils.";
$a->strings["Edit your <strong>default</strong> profile to your liking. Review the settings for hiding your list of friends and hiding the profile from unknown visitors."] = "Editiere Dein <strong>Standard</strong> Profil nach Deinen Vorlieben. Überprüfe die Einstellungen zum Verbergen Deiner Freundesliste vor unbekannten Betrachtern des Profils.";
$a->strings["Profile Keywords"] = "Profil Schlüsselbegriffe";
$a->strings["Set some public keywords for your default profile which describe your interests. We may be able to find other people with similar interests and suggest friendships."] = "Trage ein paar öffentliche Stichwörter in dein Standardprofil ein, die deine Interessen beschreiben. Eventuell sind wir in der Lage Leute zu finden, die deine Interessen teilen und können dir dann Kontakte vorschlagen.";
$a->strings["Set some public keywords for your default profile which describe your interests. We may be able to find other people with similar interests and suggest friendships."] = "Trage ein paar öffentliche Stichwörter in Dein Standardprofil ein, die Deine Interessen beschreiben. Eventuell sind wir in der Lage Leute zu finden, die Deine Interessen teilen und können Dir dann Kontakte vorschlagen.";
$a->strings["Connecting"] = "Verbindungen knüpfen";
$a->strings["Facebook"] = "Facebook";
$a->strings["Authorise the Facebook Connector if you currently have a Facebook account and we will (optionally) import all your Facebook friends and conversations."] = "Richte die Verbindung zu Facebook ein, wenn du im Augenblick ein Facebook-Konto hast, und (optional) deine Facebook-Freunde und -Unterhaltungen importieren willst.";
$a->strings["<em>If</em> this is your own personal server, installing the Facebook addon may ease your transition to the free social web."] = "<em>Wenn</em> dies dein privater Server ist, könnte die Installation des Facebook Connectors deinen Umzug ins freie soziale Netz angenehmer gestalten.";
$a->strings["Authorise the Facebook Connector if you currently have a Facebook account and we will (optionally) import all your Facebook friends and conversations."] = "Richte die Verbindung zu Facebook ein, wenn Du im Augenblick ein Facebook-Konto hast und (optional) Deine Facebook-Freunde und -Unterhaltungen importieren willst.";
$a->strings["<em>If</em> this is your own personal server, installing the Facebook addon may ease your transition to the free social web."] = "<em>Wenn</em> dies Dein privater Server ist, könnte die Installation des Facebook Connectors Deinen Umzug ins freie soziale Netz angenehmer gestalten.";
$a->strings["Importing Emails"] = "Emails Importieren";
$a->strings["Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX"] = "Gib deine E-Mail-Zugangsinformationen auf der Connector-Einstellungsseite ein, falls du E-Mails aus deinem Posteingang importieren und mit Freunden und Mailinglisten interagieren willlst.";
$a->strings["Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX"] = "Gib Deine E-Mail-Zugangsinformationen auf der Connector-Einstellungsseite ein, falls Du E-Mails aus Deinem Posteingang importieren und mit Freunden und Mailinglisten interagieren willst.";
$a->strings["Go to Your Contacts Page"] = "Gehe zu deiner Kontakt-Seite";
$a->strings["Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the <em>Add New Contact</em> dialog."] = "Die Kontakte-Seite ist die Einstiegsseite, von der aus du Kontakte verwalten und dich mit Freunden in anderen Netzwerken verbinden kannst. Normalerweise gibst du dazu einfach ihre Adresse oder die URL der Seite im Kasten <em>Neuen Kontakt hinzufügen</em> ein.";
$a->strings["Go to Your Site's Directory"] = "Gehe zum Verzeichnis deiner Friendica Instanz";
$a->strings["The Directory page lets you find other people in this network or other federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on their profile page. Provide your own Identity Address if requested."] = "Über die Verzeichnisseite kannst du andere Personen auf diesem Server oder anderen verknüpften Seiten finden. Halte nach einem <em>Verbinden</em> oder <em>Folgen</em> Link auf deren Profilseiten Ausschau und gib deine eigene Profiladresse an, falls du danach gefragt wirst.";
$a->strings["Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the <em>Add New Contact</em> dialog."] = "Die Kontakte-Seite ist die Einstiegsseite, von der aus Du Kontakte verwalten und Dich mit Freunden in anderen Netzwerken verbinden kannst. Normalerweise gibst Du dazu einfach ihre Adresse oder die URL der Seite im Kasten <em>Neuen Kontakt hinzufügen</em> ein.";
$a->strings["Go to Your Site's Directory"] = "Gehe zum Verzeichnis Deiner Friendica Instanz";
$a->strings["The Directory page lets you find other people in this network or other federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on their profile page. Provide your own Identity Address if requested."] = "Über die Verzeichnisseite kannst Du andere Personen auf diesem Server oder anderen verknüpften Seiten finden. Halte nach einem <em>Verbinden</em> oder <em>Folgen</em> Link auf deren Profilseiten Ausschau und gib Deine eigene Profiladresse an, falls Du danach gefragt wirst.";
$a->strings["Finding New People"] = "Neue Leute kennenlernen";
$a->strings["On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours."] = "Im seitlichen Bedienfeld der Kontakteseite gibt es diverse Werkzeuge, um neue Freunde zu finden. Wir können Menschen mit den gleichen Interessen finden, anhand von Namen oder Interessen suchen oder aber aufgrund vorhandener Kontakte neue Freunde vorschlagen.\nAuf einer brandneuen - soeben erstellten - Seite starten die Kontaktvorschläge innerhalb von 24 Stunden.";
$a->strings["Groups"] = "Gruppen";
$a->strings["Group Your Contacts"] = "Gruppiere deine Kontakte";
$a->strings["Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page."] = "Sobald du einige Freunde gefunden hast, organisiere sie in Gruppen zur privaten Kommunikation im Seitenmenü der Kontakte-Seite. Du kannst dann mit jeder dieser Gruppen von der Netzwerkseite aus privat interagieren.";
$a->strings["Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page."] = "Sobald Du einige Freunde gefunden hast, organisiere sie in Gruppen zur privaten Kommunikation im Seitenmenü der Kontakte-Seite. Du kannst dann mit jeder dieser Gruppen von der Netzwerkseite aus privat interagieren.";
$a->strings["Why Aren't My Posts Public?"] = "Warum sind meine Beiträge nicht öffentlich?";
$a->strings["Friendica respects your privacy. By default, your posts will only show up to people you've added as friends. For more information, see the help section from the link above."] = "Friendica respektiert deine Privatsphäre. Mit der Grundeinstellung werden deine Beiträge ausschließlich deinen Kontakten angezeigt. Für weitere Informationen diesbezüglich lies dir bitte den entsprechenden Abschnitt in der Hilfe unter dem obigen Link durch.";
$a->strings["Friendica respects your privacy. By default, your posts will only show up to people you've added as friends. For more information, see the help section from the link above."] = "Friendica respektiert Deine Privatsphäre. Mit der Grundeinstellung werden Deine Beiträge ausschließlich Deinen Kontakten angezeigt. Für weitere Informationen diesbezüglich lies Dir bitte den entsprechenden Abschnitt in der Hilfe unter dem obigen Link durch.";
$a->strings["Getting Help"] = "Hilfe bekommen";
$a->strings["Go to the Help Section"] = "Zum Hilfe Abschnitt gehen";
$a->strings["Our <strong>help</strong> pages may be consulted for detail on other program features and resources."] = "Unsere <strong>Hilfe</strong> Seiten können herangezogen werden, um weitere Einzelheiten zu andern Programm Features zu erhalten.";
@ -192,7 +192,7 @@ $a->strings["Wall Photos"] = "Pinnwand-Bilder";
$a->strings["System error. Post not saved."] = "Systemfehler. Beitrag konnte nicht gespeichert werden.";
$a->strings["This message was sent to you by %s, a member of the Friendica social network."] = "Diese Nachricht wurde dir von %s geschickt, einem Mitglied des Sozialen Netzwerks Friendica.";
$a->strings["You may visit them online at %s"] = "Du kannst sie online unter %s besuchen";
$a->strings["Please contact the sender by replying to this post if you do not wish to receive these messages."] = "Falls du diese Beiträge nicht erhalten möchtest, kontaktiere bitte den Autor, indem du auf diese Nachricht antwortest.";
$a->strings["Please contact the sender by replying to this post if you do not wish to receive these messages."] = "Falls Du diese Beiträge nicht erhalten möchtest, kontaktiere bitte den Autor, indem Du auf diese Nachricht antwortest.";
$a->strings["%s posted an update."] = "%s hat ein Update veröffentlicht.";
$a->strings["Group created."] = "Gruppe erstellt.";
$a->strings["Could not create group."] = "Konnte die Gruppe nicht erstellen.";
@ -224,9 +224,9 @@ $a->strings["Our site encryption key is apparently messed up."] = "Der Verschlü
$a->strings["Empty site URL was provided or URL could not be decrypted by us."] = "Leere URL für die Seite erhalten oder die URL konnte nicht entschlüsselt werden.";
$a->strings["Contact record was not found for you on our site."] = "Für diesen Kontakt wurde auf unserer Seite kein Eintrag gefunden.";
$a->strings["Site public key not available in contact record for URL %s."] = "Die Kontaktdaten für URL %s enthalten keinen Public Key für den Server.";
$a->strings["The ID provided by your system is a duplicate on our system. It should work if you try again."] = "Die ID, die uns dein System angeboten hat, ist hier bereits vergeben. Bitte versuche es noch einmal.";
$a->strings["The ID provided by your system is a duplicate on our system. It should work if you try again."] = "Die ID, die uns Dein System angeboten hat, ist hier bereits vergeben. Bitte versuche es noch einmal.";
$a->strings["Unable to set your contact credentials on our system."] = "Deine Kontaktreferenzen konnten nicht in unserem System gespeichert werden.";
$a->strings["Unable to update your contact profile details on our system"] = "Die Updates für dein Profil konnten nicht gespeichert werden";
$a->strings["Unable to update your contact profile details on our system"] = "Die Updates für Dein Profil konnten nicht gespeichert werden";
$a->strings["[Name Withheld]"] = "[Name unterdrückt]";
$a->strings["%1\$s has joined %2\$s"] = "%1\$s ist %2\$s beigetreten";
$a->strings["Requested profile is not available."] = "Das angefragte Profil ist nicht vorhanden.";
@ -242,28 +242,28 @@ $a->strings["Friend suggestion sent."] = "Kontaktvorschlag gesendet.";
$a->strings["Suggest Friends"] = "Kontakte vorschlagen";
$a->strings["Suggest a friend for %s"] = "Schlage %s einen Kontakt vor";
$a->strings["No valid account found."] = "Kein gültiges Konto gefunden.";
$a->strings["Password reset request issued. Check your email."] = "Zurücksetzen des Passworts eingeleitet. Bitte überprüfe deine E-Mail.";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "\nHallo %1\$s,\n\nAuf \"%2\$s\" ist eine Anfrage auf das Zurücksetzen deines Passworts gesteööt\nworden. Um diese Anfrage zu verifizieren folge bitte dem unten stehenden\nLink oder kopiere ihn und füge ihn in die Addressleiste deines Browsers ein.\n\nSolltest du die Anfrage NICHT gemacht haben, ignoriere und/oder lösche diese\nEmail bitte.\n\nDein Passwort wird nicht geändern solange wir nicht verifiziert haben, dass\ndu diese Änderung angefragt hast.";
$a->strings["\n\t\tFollow this link to verify your identity:\n\n\t\t%1\$s\n\n\t\tYou will then receive a follow-up message containing the new password.\n\t\tYou may change that password from your account settings page after logging in.\n\n\t\tThe login details are as follows:\n\n\t\tSite Location:\t%2\$s\n\t\tLogin Name:\t%3\$s"] = "\nUm deine Identität zu verifizieren folge bitte dem folgenden Link:\n\n%1\$s\n\nDu wirst eine weitere Email mit deinem neuen Passwort erhalten. Sobald du dich\nangemeldet hast, kannst du dein Passwort in den Einstellungen ändern.\n\nDie Anmeldedetails sind die folgenden:\n\nAdresse der Seite:\t%2\$s\nBenutzername:\t%3\$s";
$a->strings["Password reset request issued. Check your email."] = "Zurücksetzen des Passworts eingeleitet. Bitte überprüfe Deine E-Mail.";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "\nHallo %1\$s,\n\nAuf \"%2\$s\" ist eine Anfrage auf das Zurücksetzen Deines Passworts gestellt\nworden. Um diese Anfrage zu verifizieren, folge bitte dem unten stehenden\nLink oder kopiere und füge ihn in die Adressleiste Deines Browsers ein.\n\nSolltest Du die Anfrage NICHT gemacht haben, ignoriere und/oder lösche diese\nE-Mail bitte.\n\nDein Passwort wird nicht geändert, solange wir nicht verifiziert haben, dass\nDu diese Änderung angefragt hast.";
$a->strings["\n\t\tFollow this link to verify your identity:\n\n\t\t%1\$s\n\n\t\tYou will then receive a follow-up message containing the new password.\n\t\tYou may change that password from your account settings page after logging in.\n\n\t\tThe login details are as follows:\n\n\t\tSite Location:\t%2\$s\n\t\tLogin Name:\t%3\$s"] = "\nUm Deine Identität zu verifizieren, folge bitte dem folgenden Link:\n\n%1\$s\n\nDu wirst eine weitere E-Mail mit Deinem neuen Passwort erhalten. Sobald Du Dich\nangemeldet hast, kannst Du Dein Passwort in den Einstellungen ändern.\n\nDie Anmeldedetails sind die folgenden:\n\nAdresse der Seite:\t%2\$s\nBenutzername:\t%3\$s";
$a->strings["Password reset requested at %s"] = "Anfrage zum Zurücksetzen des Passworts auf %s erhalten";
$a->strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Anfrage konnte nicht verifiziert werden. (Eventuell hast du bereits eine ähnliche Anfrage gestellt.) Zurücksetzen des Passworts gescheitert.";
$a->strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Anfrage konnte nicht verifiziert werden. (Eventuell hast Du bereits eine ähnliche Anfrage gestellt.) Zurücksetzen des Passworts gescheitert.";
$a->strings["Password Reset"] = "Passwort zurücksetzen";
$a->strings["Your password has been reset as requested."] = "Dein Passwort wurde wie gewünscht zurückgesetzt.";
$a->strings["Your new password is"] = "Dein neues Passwort lautet";
$a->strings["Save or copy your new password - and then"] = "Speichere oder kopiere dein neues Passwort - und dann";
$a->strings["click here to login"] = "hier klicken, um dich anzumelden";
$a->strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Du kannst das Passwort in den <em>Einstellungen</em> ändern, sobald du dich erfolgreich angemeldet hast.";
$a->strings["\n\t\t\t\tDear %1\$s,\n\t\t\t\t\tYour password has been changed as requested. Please retain this\n\t\t\t\tinformation for your records (or change your password immediately to\n\t\t\t\tsomething that you will remember).\n\t\t\t"] = "\nHallo %1\$s,\n\ndein Passwort wurde wie gewünscht geändert. Bitte bewahre diese Informationen gut auf (oder ändere dein Passwort zu etwas, das du dir leicht merken kannst).";
$a->strings["\n\t\t\t\tYour login details are as follows:\n\n\t\t\t\tSite Location:\t%1\$s\n\t\t\t\tLogin Name:\t%2\$s\n\t\t\t\tPassword:\t%3\$s\n\n\t\t\t\tYou may change that password from your account settings page after logging in.\n\t\t\t"] = "\nDie Anmeldedaten sind die folgenden:\n\nAdresse der Seite: %1\$s\nLogin Name: %2\$s\nPasswort: %3\$s\n\nDas Passwort kann, und sollte, in den Kontoeinstellungen nach der Anmeldung geändert werden.";
$a->strings["Your password has been changed at %s"] = "Auf %s wurde dein Passwort geändert";
$a->strings["Forgot your Password?"] = "Hast du dein Passwort vergessen?";
$a->strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Gib deine E-Mail-Adresse an und fordere ein neues Passwort an. Es werden dir dann weitere Informationen per Mail zugesendet.";
$a->strings["Save or copy your new password - and then"] = "Speichere oder kopiere Dein neues Passwort - und dann";
$a->strings["click here to login"] = "hier klicken, um Dich anzumelden";
$a->strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Du kannst das Passwort in den <em>Einstellungen</em> ändern, sobald Du Dich erfolgreich angemeldet hast.";
$a->strings["\n\t\t\t\tDear %1\$s,\n\t\t\t\t\tYour password has been changed as requested. Please retain this\n\t\t\t\tinformation for your records (or change your password immediately to\n\t\t\t\tsomething that you will remember).\n\t\t\t"] = "\nHallo %1\$s,\n\nDein Passwort wurde wie gewünscht geändert. Bitte bewahre diese Informationen gut auf (oder ändere Dein Passwort in eines, das Du Dir leicht merken kannst).";
$a->strings["\n\t\t\t\tYour login details are as follows:\n\n\t\t\t\tSite Location:\t%1\$s\n\t\t\t\tLogin Name:\t%2\$s\n\t\t\t\tPassword:\t%3\$s\n\n\t\t\t\tYou may change that password from your account settings page after logging in.\n\t\t\t"] = "\nDie Anmeldedaten sind die folgenden:\n\nAdresse der Seite: %1\$s\nLogin Name: %2\$s\nPasswort: %3\$s\n\nDas Passwort kann und sollte in den Kontoeinstellungen nach der Anmeldung geändert werden.";
$a->strings["Your password has been changed at %s"] = "Auf %s wurde Dein Passwort geändert";
$a->strings["Forgot your Password?"] = "Hast Du Dein Passwort vergessen?";
$a->strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Gib Deine E-Mail-Adresse an und fordere ein neues Passwort an. Es werden Dir dann weitere Informationen per Mail zugesendet.";
$a->strings["Nickname or Email: "] = "Spitzname oder E-Mail:";
$a->strings["Reset"] = "Zurücksetzen";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s mag %2\$ss %3\$s";
$a->strings["%1\$s doesn't like %2\$s's %3\$s"] = "%1\$s mag %2\$ss %3\$s nicht";
$a->strings["{0} wants to be your friend"] = "{0} möchte mit dir in Kontakt treten";
$a->strings["{0} sent you a message"] = "{0} schickte dir eine Nachricht";
$a->strings["{0} wants to be your friend"] = "{0} möchte mit Dir in Kontakt treten";
$a->strings["{0} sent you a message"] = "{0} schickte Dir eine Nachricht";
$a->strings["{0} requested registration"] = "{0} möchte sich registrieren";
$a->strings["{0} commented %s's post"] = "{0} kommentierte einen Beitrag von %s";
$a->strings["{0} liked %s's post"] = "{0} mag %ss Beitrag";
@ -271,7 +271,7 @@ $a->strings["{0} disliked %s's post"] = "{0} mag %ss Beitrag nicht";
$a->strings["{0} is now friends with %s"] = "{0} ist jetzt mit %s befreundet";
$a->strings["{0} posted"] = "{0} hat etwas veröffentlicht";
$a->strings["{0} tagged %s's post with #%s"] = "{0} hat %ss Beitrag mit dem Schlagwort #%s versehen";
$a->strings["{0} mentioned you in a post"] = "{0} hat dich in einem Beitrag erwähnt";
$a->strings["{0} mentioned you in a post"] = "{0} hat Dich in einem Beitrag erwähnt";
$a->strings["No contacts."] = "Keine Kontakte.";
$a->strings["View Contacts"] = "Kontakte anzeigen";
$a->strings["Invalid request identifier."] = "Invalid request identifier.";
@ -289,7 +289,7 @@ $a->strings["suggested by %s"] = "vorgeschlagen von %s";
$a->strings["Post a new friend activity"] = "Neue-Kontakt Nachricht senden";
$a->strings["if applicable"] = "falls anwendbar";
$a->strings["Approve"] = "Genehmigen";
$a->strings["Claims to be known to you: "] = "Behauptet dich zu kennen: ";
$a->strings["Claims to be known to you: "] = "Behauptet Dich zu kennen: ";
$a->strings["yes"] = "ja";
$a->strings["no"] = "nein";
$a->strings["Approve as: "] = "Genehmigen als: ";
@ -334,7 +334,7 @@ $a->strings["Message could not be sent."] = "Nachricht konnte nicht gesendet wer
$a->strings["Message collection failure."] = "Konnte Nachrichten nicht abrufen.";
$a->strings["Message sent."] = "Nachricht gesendet.";
$a->strings["Messages"] = "Nachrichten";
$a->strings["Do you really want to delete this message?"] = "Möchtest du wirklich diese Nachricht löschen?";
$a->strings["Do you really want to delete this message?"] = "Möchtest Du wirklich diese Nachricht löschen?";
$a->strings["Message deleted."] = "Nachricht gelöscht.";
$a->strings["Conversation removed."] = "Unterhaltung gelöscht.";
$a->strings["Please enter a link URL:"] = "Bitte gib die URL des Links ein:";
@ -348,7 +348,7 @@ $a->strings["Please wait"] = "Bitte warten";
$a->strings["No messages."] = "Keine Nachrichten.";
$a->strings["Unknown sender - %s"] = "'Unbekannter Absender - %s";
$a->strings["You and %s"] = "Du und %s";
$a->strings["%s and You"] = "%s und du";
$a->strings["%s and You"] = "%s und Du";
$a->strings["Delete conversation"] = "Unterhaltung löschen";
$a->strings["D, d M Y - g:i A"] = "D, d. M Y - g:i A";
$a->strings["%d message"] = array(
@ -357,14 +357,14 @@ $a->strings["%d message"] = array(
);
$a->strings["Message not available."] = "Nachricht nicht verfügbar.";
$a->strings["Delete message"] = "Nachricht löschen";
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Sichere Kommunikation ist nicht verfügbar. <strong>Eventuell</strong> kannst du auf der Profilseite des Absenders antworten.";
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Sichere Kommunikation ist nicht verfügbar. <strong>Eventuell</strong> kannst Du auf der Profilseite des Absenders antworten.";
$a->strings["Send Reply"] = "Antwort senden";
$a->strings["[Embedded content - reload page to view]"] = "[Eingebetteter Inhalt - Seite neu laden zum Betrachten]";
$a->strings["Contact settings applied."] = "Einstellungen zum Kontakt angewandt.";
$a->strings["Contact update failed."] = "Konnte den Kontakt nicht aktualisieren.";
$a->strings["Repair Contact Settings"] = "Kontakteinstellungen reparieren";
$a->strings["<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working."] = "<strong>ACHTUNG: Das sind Experten-Einstellungen!</strong> Wenn du etwas Falsches eingibst, funktioniert die Kommunikation mit diesem Kontakt evtl. nicht mehr.";
$a->strings["Please use your browser 'Back' button <strong>now</strong> if you are uncertain what to do on this page."] = "Bitte nutze den Zurück-Button deines Browsers <strong>jetzt</strong>, wenn du dir unsicher bist, was du tun willst.";
$a->strings["<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working."] = "<strong>ACHTUNG: Das sind Experten-Einstellungen!</strong> Wenn Du etwas Falsches eingibst, funktioniert die Kommunikation mit diesem Kontakt evtl. nicht mehr.";
$a->strings["Please use your browser 'Back' button <strong>now</strong> if you are uncertain what to do on this page."] = "Bitte nutze den Zurück-Button Deines Browsers <strong>jetzt</strong>, wenn Du Dir unsicher bist, was Du tun willst.";
$a->strings["Return to contact editor"] = "Zurück zum Kontakteditor";
$a->strings["No mirroring"] = "Kein Spiegeln";
$a->strings["Mirror as forwarded posting"] = "Spiegeln als weitergeleitete Beiträge";
@ -380,7 +380,9 @@ $a->strings["Poll/Feed URL"] = "Pull/Feed-URL";
$a->strings["New photo from this URL"] = "Neues Foto von dieser URL";
$a->strings["Remote Self"] = "Entfernte Konten";
$a->strings["Mirror postings from this contact"] = "Spiegle Beiträge dieses Kontakts";
$a->strings["Mark this contact as remote_self, this will cause friendica to repost new entries from this contact."] = "Markiere diesen Kontakt als remote_self (entferntes Konto), dies veranlasst Friendica alle Top-Level Beiträge dieses Kontakts an all deine Kontakte zu senden.";
$a->strings["Mark this contact as remote_self, this will cause friendica to repost new entries from this contact."] = "Markiere diesen Kontakt als remote_self (entferntes Konto), dies veranlasst Friendica alle Top-Level Beiträge dieses Kontakts an all Deine Kontakte zu senden.";
$a->strings["Login"] = "Anmeldung";
$a->strings["The post was created"] = "Der Beitrag wurde angelegt";
$a->strings["Access denied."] = "Zugriff verweigert.";
$a->strings["People Search"] = "Personensuche";
$a->strings["No matches"] = "Keine Übereinstimmungen";
@ -394,8 +396,11 @@ $a->strings["Plugins"] = "Plugins";
$a->strings["Themes"] = "Themen";
$a->strings["DB updates"] = "DB Updates";
$a->strings["Logs"] = "Protokolle";
$a->strings["probe address"] = "Adresse untersuchen";
$a->strings["check webfinger"] = "Webfinger überprüfen";
$a->strings["Admin"] = "Administration";
$a->strings["Plugin Features"] = "Plugin Features";
$a->strings["diagnostics"] = "Diagnose";
$a->strings["User registrations waiting for confirmation"] = "Nutzeranmeldungen die auf Bestätigung warten";
$a->strings["Normal Account"] = "Normales Konto";
$a->strings["Soapbox Account"] = "Marktschreier-Konto";
@ -413,6 +418,9 @@ $a->strings["Active plugins"] = "Aktive Plugins";
$a->strings["Can not parse base url. Must have at least <scheme>://<domain>"] = "Die Basis-URL konnte nicht analysiert werden. Sie muss mindestens aus <protokoll>://<domain> bestehen";
$a->strings["Site settings updated."] = "Seiteneinstellungen aktualisiert.";
$a->strings["No special theme for mobile devices"] = "Kein spezielles Theme für mobile Geräte verwenden.";
$a->strings["No community page"] = "Keine Gemeinschaftsseite";
$a->strings["Public postings from users of this site"] = "Öffentliche Beiträge von Nutzer_innen dieser Seite";
$a->strings["Global community page"] = "Globale Gemeinschaftsseite";
$a->strings["At post arrival"] = "Beim Empfang von Nachrichten";
$a->strings["Frequently"] = "immer wieder";
$a->strings["Hourly"] = "Stündlich";
@ -434,9 +442,12 @@ $a->strings["Performance"] = "Performance";
$a->strings["Relocate - WARNING: advanced function. Could make this server unreachable."] = "Umsiedeln - WARNUNG: Könnte diesen Server unerreichbar machen.";
$a->strings["Site name"] = "Seitenname";
$a->strings["Host name"] = "Host Name";
$a->strings["Sender Email"] = "Absender für Emails";
$a->strings["Banner/Logo"] = "Banner/Logo";
$a->strings["Shortcut icon"] = "Shortcut Icon";
$a->strings["Touch icon"] = "Touch Icon";
$a->strings["Additional Info"] = "Zusätzliche Informationen";
$a->strings["For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo."] = "Für öffentliche Server kannst du hier zusätzliche Informationen angeben, die dann auf dir.friendica.com/siteinfo angezeigt werden.";
$a->strings["For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo."] = "Für öffentliche Server kannst Du hier zusätzliche Informationen angeben, die dann auf Dir.friendica.com/siteinfo angezeigt werden.";
$a->strings["System language"] = "Systemsprache";
$a->strings["System theme"] = "Systemweites Theme";
$a->strings["Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"] = "Vorgabe für das System-Theme - kann von Benutzerprofilen überschrieben werden - <a href='#' id='cnftheme'>Theme-Einstellungen ändern</a>";
@ -460,7 +471,7 @@ $a->strings["JPEG image quality"] = "Qualität des JPEG Bildes";
$a->strings["Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality."] = "Hoch geladene JPEG Bilder werden mit dieser Qualität [0-100] gespeichert. Grundeinstellung ist 100, kein Qualitätsverlust.";
$a->strings["Register policy"] = "Registrierungsmethode";
$a->strings["Maximum Daily Registrations"] = "Maximum täglicher Registrierungen";
$a->strings["If registration is permitted above, this sets the maximum number of new user registrations to accept per day. If register is set to closed, this setting has no effect."] = "Wenn die Registrierung weiter oben erlaubt ist, regelt dies die maximale Anzahl von Neuanmeldungen pro Tag. Wenn die Registrierung geschlossen ist, hat diese Einstellung keinen Effekt.";
$a->strings["If registration is permitted above, this sets the maximum number of new user registrations to accept per day. If register is set to closed, this setting has no effect."] = "Wenn die Registrierung weiter oben erlaubt ist, regelt dies die maximale Anzahl von Neuanmeldungen pro Tag. Wenn die Registrierung geschlossen ist, hat diese Einstellung keinen Effekt.";
$a->strings["Register text"] = "Registrierungstext";
$a->strings["Will be displayed prominently on the registration page."] = "Wird gut sichtbar auf der Registrierungsseite angezeigt.";
$a->strings["Accounts abandoned after x days"] = "Nutzerkonten gelten nach x Tagen als unbenutzt";
@ -495,8 +506,10 @@ $a->strings["Fullname check"] = "Namen auf Vollständigkeit überprüfen";
$a->strings["Force users to register with a space between firstname and lastname in Full name, as an antispam measure"] = "Leerzeichen zwischen Vor- und Nachname im vollständigen Namen erzwingen, um SPAM zu vermeiden.";
$a->strings["UTF-8 Regular expressions"] = "UTF-8 Reguläre Ausdrücke";
$a->strings["Use PHP UTF8 regular expressions"] = "PHP UTF8 Ausdrücke verwenden";
$a->strings["Show Community Page"] = "Gemeinschaftsseite anzeigen";
$a->strings["Display a Community page showing all recent public postings on this site."] = "Zeige die Gemeinschaftsseite mit allen öffentlichen Beiträgen auf diesem Server.";
$a->strings["Community Page Style"] = "Art der Gemeinschaftsseite";
$a->strings["Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."] = "Welche Art der Gemeinschaftsseite soll verwendet werden? Globale Gemeinschaftsseite zeigt alle öffentlichen Beiträge eines offenen dezentralen Netzwerks an die auf diesem Server eintreffen.";
$a->strings["Posts per user on community page"] = "Anzahl der Beiträge pro Benutzer auf der Gemeinschaftsseite";
$a->strings["The maximum number of posts per user on the community page. (Not valid for 'Global Community')"] = "Die Anzahl der Beiträge die von jedem Nutzer maximal auf der Gemeinschaftsseite angezeigt werden sollen. Dieser Parameter wird nicht für die Globale Gemeinschaftsseite genutzt.";
$a->strings["Enable OStatus support"] = "OStatus Unterstützung aktivieren";
$a->strings["Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed."] = "Biete die eingebaute OStatus (iStatusNet, GNU Social, etc.) Unterstützung an. Jede Kommunikation in OStatus ist öffentlich, Privatsphäre Warnungen werden nur bei Bedarf angezeigt.";
$a->strings["OStatus conversation completion interval"] = "Intervall zum Vervollständigen von OStatus Unterhaltungen";
@ -514,13 +527,15 @@ $a->strings["Value is in seconds. Set to 0 for unlimited (not recommended)."] =
$a->strings["Delivery interval"] = "Zustellungsintervall";
$a->strings["Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers."] = "Verzögere im Hintergrund laufende Auslieferungsprozesse um die angegebene Anzahl an Sekunden, um die Systemlast zu verringern. Empfehlungen: 4-5 für Shared-Hosts, 2-3 für VPS, 0-1 für große dedizierte Server.";
$a->strings["Poll interval"] = "Abfrageintervall";
$a->strings["Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval."] = "Verzögere Hintergrundprozesse, um diese Anzahl an Sekunden um die Systemlast zu reduzieren. Bei 0 Sekunden wird das Auslieferungsintervall verwendet.";
$a->strings["Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval."] = "Verzögere Hintergrundprozesse um diese Anzahl an Sekunden, um die Systemlast zu reduzieren. Bei 0 Sekunden wird das Auslieferungsintervall verwendet.";
$a->strings["Maximum Load Average"] = "Maximum Load Average";
$a->strings["Maximum system load before delivery and poll processes are deferred - default 50."] = "Maximale Systemlast bevor Verteil- und Empfangsprozesse verschoben werden - Standard 50";
$a->strings["Use MySQL full text engine"] = "Nutze MySQL full text engine";
$a->strings["Activates the full text engine. Speeds up search - but can only search for four and more characters."] = "Aktiviert die 'full text engine'. Beschleunigt die Suche - aber es kann nur nach vier oder mehr Zeichen gesucht werden.";
$a->strings["Suppress Language"] = "Sprachinformation unterdrücken";
$a->strings["Suppress language information in meta information about a posting."] = "Verhindert das Erzeugen der Meta-Information zur Spracherkennung eines Beitrags.";
$a->strings["Suppress Tags"] = "Tags Unterdrücken";
$a->strings["Suppress showing a list of hashtags at the end of the posting."] = "Unterdrückt die Anzeige von Tags am Ende eines Beitrags.";
$a->strings["Path to item cache"] = "Pfad zum Eintrag Cache";
$a->strings["Cache duration in seconds"] = "Cache-Dauer in Sekunden";
$a->strings["How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1."] = "Wie lange sollen die gecachedten Dateien vorgehalten werden? Grundeinstellung sind 86400 Sekunden (ein Tag). Um den Item Cache zu deaktivieren, setze diesen Wert auf -1.";
@ -531,9 +546,11 @@ $a->strings["Temp path"] = "Temp Pfad";
$a->strings["Base path to installation"] = "Basis-Pfad zur Installation";
$a->strings["Disable picture proxy"] = "Bilder Proxy deaktivieren";
$a->strings["The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith."] = "Der Proxy für Bilder verbessert die Leitung und Privatsphäre der Nutzer. Er sollte nicht auf Systemen verwendet werden, die nur über begrenzte Bandbreite verfügen.";
$a->strings["Enable old style pager"] = "Den Old-Style Pager aktiviren";
$a->strings["The old style pager has page numbers but slows down massively the page speed."] = "Der Old-Style Pager zeigt Seitennummern an, verlangsamt aber auch drastisch das Laden einer Seite.";
$a->strings["Only search in tags"] = "Nur in Tags suchen";
$a->strings["On large systems the text search can slow down the system extremely."] = "Auf großen Knoten kann die Volltext-Suche das System ausbremsen.";
$a->strings["New base url"] = "Neue Basis-URL";
$a->strings["Disable noscrape"] = "Noscrape deaktivieren";
$a->strings["The noscrape feature speeds up directory submissions by using JSON data instead of HTML scraping. Disabling it will cause higher load on your server and the directory server."] = "Das noscrape Feature beschleunigt Verzeichnis einsendungen indem JSON Daten gesendet werden anstelle vom analysieren der HTML Struktur. Wird es deaktiviert, wird mehr Last auf deinem Server und den Verzichnis Servern verursacht.";
$a->strings["Update has been marked successful"] = "Update wurde als erfolgreich markiert";
$a->strings["Database structure update %s was successfully applied."] = "Das Update %s der Struktur der Datenbank wurde erfolgreich angewandt.";
$a->strings["Executing of database structure update %s failed with error: %s"] = "Das Update %s der Struktur der Datenbank schlug mit folgender Fehlermeldung fehl: %s";
@ -547,8 +564,8 @@ $a->strings["Failed Updates"] = "Fehlgeschlagene Updates";
$a->strings["This does not include updates prior to 1139, which did not return a status."] = "Ohne Updates vor 1139, da diese keinen Status zurückgegeben haben.";
$a->strings["Mark success (if update was manually applied)"] = "Als erfolgreich markieren (falls das Update manuell installiert wurde)";
$a->strings["Attempt to execute this update step automatically"] = "Versuchen, diesen Schritt automatisch auszuführen";
$a->strings["\n\t\t\tDear %1\$s,\n\t\t\t\tthe administrator of %2\$s has set up an account for you."] = "\nHallo %1\$s,\n\nauf %2\$s wurde ein Account für dich angelegt.";
$a->strings["\n\t\t\tThe login details are as follows:\n\n\t\t\tSite Location:\t%1\$s\n\t\t\tLogin Name:\t\t%2\$s\n\t\t\tPassword:\t\t%3\$s\n\n\t\t\tYou may change your password from your account \"Settings\" page after logging\n\t\t\tin.\n\n\t\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\t\tYou may also wish to add some basic information to your default profile\n\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\t\tWe recommend setting your full name, adding a profile photo,\n\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\t\tthan that.\n\n\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\t\tIf you are new and do not know anybody here, they may help\n\t\t\tyou to make some new and interesting friends.\n\n\t\t\tThank you and welcome to %4\$s."] = "\nDie Anmelde-Details sind die folgenden:\n\tAdresse der Seite:\t%1\$s\n\tBenutzernamename:\t%2\$s\n\tPasswort:\t%3\$s\n\nDu kannst dein Passwort unter \"Einstellungen\" ändern, sobald du dich\nangemeldet hast.\n\nBitte nimm dir ein paar Minuten um die anderen Einstellungen auf dieser\nSeite zu kontrollieren.\n\nEventuell magst du ja auch einige Informationen über dich in deinem\nProfil veröffentlichen, damit andere Leute dich einfacher finden können.\nBearbeite hierfür einfach dein Standard-Profil (über die Profil-Seite).\n\nWir empfehlen dir, deinen kompletten Namen anzugeben und ein zu dir\npassendes Profilbild zu wählen, damit dich alte Bekannte wieder finden.\nAußerdem ist es nützlich, wenn du auf deinem Profil Schlüsselwörter\nangibst. Das erleichtert es, Leute zu finden, die deine Interessen teilen.\n\nWir respektieren deine Privatsphäre - keine dieser Angaben ist nötig.\nWenn du neu im Netzwerk bist und noch niemanden kennst, dann können sie\nallerdings dabei helfen, neue und interessante Kontakte zu knüpfen.\n\nDanke für deine Aufmerksamkeit und willkommen auf %4\$s.";
$a->strings["\n\t\t\tDear %1\$s,\n\t\t\t\tthe administrator of %2\$s has set up an account for you."] = "\nHallo %1\$s,\n\nauf %2\$s wurde ein Account für Dich angelegt.";
$a->strings["\n\t\t\tThe login details are as follows:\n\n\t\t\tSite Location:\t%1\$s\n\t\t\tLogin Name:\t\t%2\$s\n\t\t\tPassword:\t\t%3\$s\n\n\t\t\tYou may change your password from your account \"Settings\" page after logging\n\t\t\tin.\n\n\t\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\t\tYou may also wish to add some basic information to your default profile\n\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\t\tWe recommend setting your full name, adding a profile photo,\n\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\t\tthan that.\n\n\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\t\tIf you are new and do not know anybody here, they may help\n\t\t\tyou to make some new and interesting friends.\n\n\t\t\tThank you and welcome to %4\$s."] = "\nNachfolgend die Anmelde-Details:\n\tAdresse der Seite:\t%1\$s\n\tBenutzername:\t%2\$s\n\tPasswort:\t%3\$s\n\nDu kannst Dein Passwort unter \"Einstellungen\" ändern, sobald Du Dich\nangemeldet hast.\n\nBitte nimm Dir ein paar Minuten um die anderen Einstellungen auf dieser\nSeite zu kontrollieren.\n\nEventuell magst Du ja auch einige Informationen über Dich in Deinem\nProfil veröffentlichen, damit andere Leute Dich einfacher finden können.\nBearbeite hierfür einfach Dein Standard-Profil (über die Profil-Seite).\n\nWir empfehlen Dir, Deinen kompletten Namen anzugeben und ein zu Dir\npassendes Profilbild zu wählen, damit Dich alte Bekannte wieder finden.\nAußerdem ist es nützlich, wenn Du auf Deinem Profil Schlüsselwörter\nangibst. Das erleichtert es, Leute zu finden, die Deine Interessen teilen.\n\nWir respektieren Deine Privatsphäre - keine dieser Angaben ist nötig.\nWenn Du neu im Netzwerk bist und noch niemanden kennst, dann können sie\nallerdings dabei helfen, neue und interessante Kontakte zu knüpfen.\n\nNun viel Spaß, gute Begegnungen und willkommen auf %4\$s.";
$a->strings["Registration details for %s"] = "Details der Registration von %s";
$a->strings["%s user blocked/unblocked"] = array(
0 => "%s Benutzer geblockt/freigegeben",
@ -563,7 +580,7 @@ $a->strings["User '%s' unblocked"] = "Nutzer '%s' entsperrt";
$a->strings["User '%s' blocked"] = "Nutzer '%s' gesperrt";
$a->strings["Add User"] = "Nutzer hinzufügen";
$a->strings["select all"] = "Alle auswählen";
$a->strings["User registrations waiting for confirm"] = "Neuanmeldungen, die auf deine Bestätigung warten";
$a->strings["User registrations waiting for confirm"] = "Neuanmeldungen, die auf Deine Bestätigung warten";
$a->strings["User waiting for permanent deletion"] = "Nutzer wartet auf permanente Löschung";
$a->strings["Request date"] = "Anfragedatum";
$a->strings["Email"] = "E-Mail";
@ -577,8 +594,8 @@ $a->strings["Last login"] = "Letzte Anmeldung";
$a->strings["Last item"] = "Letzter Beitrag";
$a->strings["Deleted since"] = "Gelöscht seit";
$a->strings["Account"] = "Nutzerkonto";
$a->strings["Selected users will be deleted!\\n\\nEverything these users had posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Die markierten Nutzer werden gelöscht!\\n\\nAlle Beiträge, die diese Nutzer auf dieser Seite veröffentlicht haben, werden permanent gelöscht!\\n\\nBist du sicher?";
$a->strings["The user {0} will be deleted!\\n\\nEverything this user has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Der Nutzer {0} wird gelöscht!\\n\\nAlles was dieser Nutzer auf dieser Seite veröffentlicht hat, wird permanent gelöscht!\\n\\nBist du sicher?";
$a->strings["Selected users will be deleted!\\n\\nEverything these users had posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Die markierten Nutzer werden gelöscht!\\n\\nAlle Beiträge, die diese Nutzer auf dieser Seite veröffentlicht haben, werden permanent gelöscht!\\n\\nBist Du sicher?";
$a->strings["The user {0} will be deleted!\\n\\nEverything this user has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Der Nutzer {0} wird gelöscht!\\n\\nAlles was dieser Nutzer auf dieser Seite veröffentlicht hat, wird permanent gelöscht!\\n\\nBist Du sicher?";
$a->strings["Name of the new user."] = "Name des neuen Nutzers";
$a->strings["Nickname"] = "Spitzname";
$a->strings["Nickname of the new user."] = "Spitznamen für den neuen Nutzer";
@ -613,7 +630,7 @@ $a->strings["Commented Order"] = "Neueste Kommentare";
$a->strings["Sort by Comment Date"] = "Nach Kommentardatum sortieren";
$a->strings["Posted Order"] = "Neueste Beiträge";
$a->strings["Sort by Post Date"] = "Nach Beitragsdatum sortieren";
$a->strings["Posts that mention or involve you"] = "Beiträge, in denen es um dich geht";
$a->strings["Posts that mention or involve you"] = "Beiträge, in denen es um Dich geht";
$a->strings["New"] = "Neue";
$a->strings["Activity Stream - by date"] = "Aktivitäten-Stream - nach Datum";
$a->strings["Shared Links"] = "Geteilte Links";
@ -673,7 +690,7 @@ $a->strings["I don't like this (toggle)"] = "Ich mag das nicht (toggle)";
$a->strings["dislike"] = "mag ich nicht";
$a->strings["Share this"] = "Weitersagen";
$a->strings["share"] = "Teilen";
$a->strings["This is you"] = "Das bist du";
$a->strings["This is you"] = "Das bist Du";
$a->strings["Comment"] = "Kommentar";
$a->strings["Bold"] = "Fett";
$a->strings["Italic"] = "Kursiv";
@ -696,40 +713,40 @@ $a->strings["Wall-to-Wall"] = "Wall-to-Wall";
$a->strings["via Wall-To-Wall:"] = "via Wall-To-Wall:";
$a->strings["Remove My Account"] = "Konto löschen";
$a->strings["This will completely remove your account. Once this has been done it is not recoverable."] = "Dein Konto wird endgültig gelöscht. Es gibt keine Möglichkeit, es wiederherzustellen.";
$a->strings["Please enter your password for verification:"] = "Bitte gib dein Passwort zur Verifikation ein:";
$a->strings["Please enter your password for verification:"] = "Bitte gib Dein Passwort zur Verifikation ein:";
$a->strings["Friendica Communications Server - Setup"] = "Friendica-Server für soziale Netzwerke Setup";
$a->strings["Could not connect to database."] = "Verbindung zur Datenbank gescheitert.";
$a->strings["Could not create table."] = "Tabelle konnte nicht angelegt werden.";
$a->strings["Your Friendica site database has been installed."] = "Die Datenbank deiner Friendicaseite wurde installiert.";
$a->strings["You may need to import the file \"database.sql\" manually using phpmyadmin or mysql."] = "Möglicherweise musst du die Datei \"database.sql\" manuell mit phpmyadmin oder mysql importieren.";
$a->strings["Your Friendica site database has been installed."] = "Die Datenbank Deiner Friendicaseite wurde installiert.";
$a->strings["You may need to import the file \"database.sql\" manually using phpmyadmin or mysql."] = "Möglicherweise musst Du die Datei \"database.sql\" manuell mit phpmyadmin oder mysql importieren.";
$a->strings["Please see the file \"INSTALL.txt\"."] = "Lies bitte die \"INSTALL.txt\".";
$a->strings["System check"] = "Systemtest";
$a->strings["Check again"] = "Noch einmal testen";
$a->strings["Database connection"] = "Datenbankverbindung";
$a->strings["In order to install Friendica we need to know how to connect to your database."] = "Um Friendica installieren zu können, müssen wir wissen, wie wir mit deiner Datenbank Kontakt aufnehmen können.";
$a->strings["Please contact your hosting provider or site administrator if you have questions about these settings."] = "Bitte kontaktiere den Hosting Provider oder den Administrator der Seite, falls du Fragen zu diesen Einstellungen haben solltest.";
$a->strings["The database you specify below should already exist. If it does not, please create it before continuing."] = "Die Datenbank, die du unten angibst, sollte bereits existieren. Ist dies noch nicht der Fall, erzeuge sie bitte bevor du mit der Installation fortfährst.";
$a->strings["In order to install Friendica we need to know how to connect to your database."] = "Um Friendica installieren zu können, müssen wir wissen, wie wir mit Deiner Datenbank Kontakt aufnehmen können.";
$a->strings["Please contact your hosting provider or site administrator if you have questions about these settings."] = "Bitte kontaktiere den Hosting Provider oder den Administrator der Seite, falls Du Fragen zu diesen Einstellungen haben solltest.";
$a->strings["The database you specify below should already exist. If it does not, please create it before continuing."] = "Die Datenbank, die Du unten angibst, sollte bereits existieren. Ist dies noch nicht der Fall, erzeuge sie bitte bevor Du mit der Installation fortfährst.";
$a->strings["Database Server Name"] = "Datenbank-Server";
$a->strings["Database Login Name"] = "Datenbank-Nutzer";
$a->strings["Database Login Password"] = "Datenbank-Passwort";
$a->strings["Database Name"] = "Datenbank-Name";
$a->strings["Site administrator email address"] = "E-Mail-Adresse des Administrators";
$a->strings["Your account email address must match this in order to use the web admin panel."] = "Die E-Mail-Adresse, die in deinem Friendica-Account eingetragen ist, muss mit dieser Adresse übereinstimmen, damit du das Admin-Panel benutzen kannst.";
$a->strings["Please select a default timezone for your website"] = "Bitte wähle die Standardzeitzone deiner Webseite";
$a->strings["Your account email address must match this in order to use the web admin panel."] = "Die E-Mail-Adresse, die in Deinem Friendica-Account eingetragen ist, muss mit dieser Adresse übereinstimmen, damit Du das Admin-Panel benutzen kannst.";
$a->strings["Please select a default timezone for your website"] = "Bitte wähle die Standardzeitzone Deiner Webseite";
$a->strings["Site settings"] = "Server-Einstellungen";
$a->strings["Could not find a command line version of PHP in the web server PATH."] = "Konnte keine Kommandozeilenversion von PHP im PATH des Servers finden.";
$a->strings["If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>"] = "Wenn du keine Kommandozeilen Version von PHP auf deinem Server installiert hast, kannst du keine Hintergrundprozesse via cron starten. Siehe <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>";
$a->strings["If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>"] = "Wenn Du keine Kommandozeilen Version von PHP auf Deinem Server installiert hast, kannst Du keine Hintergrundprozesse via cron starten. Siehe <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>";
$a->strings["PHP executable path"] = "Pfad zu PHP";
$a->strings["Enter full path to php executable. You can leave this blank to continue the installation."] = "Gib den kompletten Pfad zur ausführbaren Datei von PHP an. Du kannst dieses Feld auch frei lassen und mit der Installation fortfahren.";
$a->strings["Command line PHP"] = "Kommandozeilen-PHP";
$a->strings["PHP executable is not the php cli binary (could be cgi-fgci version)"] = "Die ausführbare Datei von PHP stimmt nicht mit der PHP cli Version überein (es könnte sich um die cgi-fgci Version handeln)";
$a->strings["Found PHP version: "] = "Gefundene PHP Version:";
$a->strings["PHP cli binary"] = "PHP CLI Binary";
$a->strings["The command line version of PHP on your system does not have \"register_argc_argv\" enabled."] = "Die Kommandozeilenversion von PHP auf deinem System hat \"register_argc_argv\" nicht aktiviert.";
$a->strings["The command line version of PHP on your system does not have \"register_argc_argv\" enabled."] = "Die Kommandozeilenversion von PHP auf Deinem System hat \"register_argc_argv\" nicht aktiviert.";
$a->strings["This is required for message delivery to work."] = "Dies wird für die Auslieferung von Nachrichten benötigt.";
$a->strings["PHP register_argc_argv"] = "PHP register_argc_argv";
$a->strings["Error: the \"openssl_pkey_new\" function on this system is not able to generate encryption keys"] = "Fehler: Die Funktion \"openssl_pkey_new\" auf diesem System ist nicht in der Lage, Verschlüsselungsschlüssel zu erzeugen";
$a->strings["If running under Windows, please see \"http://www.php.net/manual/en/openssl.installation.php\"."] = "Wenn der Server unter Windows läuft, schau dir bitte \"http://www.php.net/manual/en/openssl.installation.php\" an.";
$a->strings["If running under Windows, please see \"http://www.php.net/manual/en/openssl.installation.php\"."] = "Wenn der Server unter Windows läuft, schau Dir bitte \"http://www.php.net/manual/en/openssl.installation.php\" an.";
$a->strings["Generate encryption keys"] = "Schlüssel erzeugen";
$a->strings["libCurl PHP module"] = "PHP: libCurl-Modul";
$a->strings["GD graphics PHP module"] = "PHP: GD-Grafikmodul";
@ -743,25 +760,25 @@ $a->strings["Error: GD graphics PHP module with JPEG support required but not in
$a->strings["Error: openssl PHP module required but not installed."] = "Fehler: Das openssl-Modul von PHP ist nicht installiert.";
$a->strings["Error: mysqli PHP module required but not installed."] = "Fehler: Das mysqli-Modul von PHP ist nicht installiert.";
$a->strings["Error: mb_string PHP module required but not installed."] = "Fehler: mb_string PHP Module wird benötigt ist aber nicht installiert.";
$a->strings["The web installer needs to be able to create a file called \".htconfig.php\" in the top folder of your web server and it is unable to do so."] = "Der Installationswizard muss in der Lage sein, eine Datei im Stammverzeichnis deines Webservers anzulegen, ist allerdings derzeit nicht in der Lage, dies zu tun.";
$a->strings["This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can."] = "In den meisten Fällen ist dies ein Problem mit den Schreibrechten. Der Webserver könnte keine Schreiberlaubnis haben, selbst wenn du sie hast.";
$a->strings["At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Friendica top folder."] = "Nachdem du alles ausgefüllt hast, erhältst du einen Text, den du in eine Datei namens .htconfig.php in deinem Friendica-Wurzelverzeichnis kopieren musst.";
$a->strings["You can alternatively skip this procedure and perform a manual installation. Please see the file \"INSTALL.txt\" for instructions."] = "Alternativ kannst du diesen Schritt aber auch überspringen und die Installation manuell durchführen. Eine Anleitung dazu (Englisch) findest du in der Datei INSTALL.txt.";
$a->strings["The web installer needs to be able to create a file called \".htconfig.php\" in the top folder of your web server and it is unable to do so."] = "Der Installationswizard muss in der Lage sein, eine Datei im Stammverzeichnis Deines Webservers anzulegen, ist allerdings derzeit nicht in der Lage, dies zu tun.";
$a->strings["This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can."] = "In den meisten Fällen ist dies ein Problem mit den Schreibrechten. Der Webserver könnte keine Schreiberlaubnis haben, selbst wenn Du sie hast.";
$a->strings["At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Friendica top folder."] = "Nachdem Du alles ausgefüllt hast, erhältst Du einen Text, den Du in eine Datei namens .htconfig.php in Deinem Friendica-Wurzelverzeichnis kopieren musst.";
$a->strings["You can alternatively skip this procedure and perform a manual installation. Please see the file \"INSTALL.txt\" for instructions."] = "Alternativ kannst Du diesen Schritt aber auch überspringen und die Installation manuell durchführen. Eine Anleitung dazu (Englisch) findest Du in der Datei INSTALL.txt.";
$a->strings[".htconfig.php is writable"] = "Schreibrechte auf .htconfig.php";
$a->strings["Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering."] = "Friendica nutzt die Smarty3 Template Engine um die Webansichten zu rendern. Smarty3 kompiliert Templates zu PHP um das Rendern zu beschleunigen.";
$a->strings["In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder."] = "Um diese kompilierten Templates zu speichern benötigt der Webserver Schreibrechte zum Verzeichnis view/smarty3/ im obersten Ordner von Friendica.";
$a->strings["Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder."] = "Bitte stelle sicher, dass der Nutzer unter dem der Webserver läuft (z.B. www-data) Schreibrechte zu diesem Verzeichnis hat.";
$a->strings["Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files (.tpl) that it contains."] = "Hinweis: aus Sicherheitsgründen solltest du dem Webserver nur Schreibrechte für view/smarty3/ geben -- Nicht den Templatedateien (.tpl) die sie enthalten.";
$a->strings["Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files (.tpl) that it contains."] = "Hinweis: aus Sicherheitsgründen solltest Du dem Webserver nur Schreibrechte für view/smarty3/ geben -- Nicht den Templatedateien (.tpl) die sie enthalten.";
$a->strings["view/smarty3 is writable"] = "view/smarty3 ist schreibbar";
$a->strings["Url rewrite in .htaccess is not working. Check your server configuration."] = "Umschreiben der URLs in der .htaccess funktioniert nicht. Überprüfe die Konfiguration des Servers.";
$a->strings["Url rewrite is working"] = "URL rewrite funktioniert";
$a->strings["The database configuration file \".htconfig.php\" could not be written. Please use the enclosed text to create a configuration file in your web server root."] = "Die Konfigurationsdatei \".htconfig.php\" konnte nicht angelegt werden. Bitte verwende den angefügten Text, um die Datei im Stammverzeichnis deiner Friendica-Installation zu erzeugen.";
$a->strings["The database configuration file \".htconfig.php\" could not be written. Please use the enclosed text to create a configuration file in your web server root."] = "Die Konfigurationsdatei \".htconfig.php\" konnte nicht angelegt werden. Bitte verwende den angefügten Text, um die Datei im Stammverzeichnis Deiner Friendica-Installation zu erzeugen.";
$a->strings["<h1>What next</h1>"] = "<h1>Wie geht es weiter?</h1>";
$a->strings["IMPORTANT: You will need to [manually] setup a scheduled task for the poller."] = "WICHTIG: Du musst [manuell] einen Cronjob (o.ä.) für den Poller einrichten.";
$a->strings["Number of daily wall messages for %s exceeded. Message failed."] = "Maximale Anzahl der täglichen Pinnwand Nachrichten für %s ist überschritten. Zustellung fehlgeschlagen.";
$a->strings["Unable to check your home location."] = "Konnte deinen Heimatort nicht bestimmen.";
$a->strings["Unable to check your home location."] = "Konnte Deinen Heimatort nicht bestimmen.";
$a->strings["No recipient."] = "Kein Empfänger.";
$a->strings["If you wish for %s to respond, please check that the privacy settings on your site allow private mail from unknown senders."] = "Wenn du möchtest, dass %s dir antworten kann, überprüfe deine Privatsphären-Einstellungen und erlaube private Nachrichten von unbekannten Absendern.";
$a->strings["If you wish for %s to respond, please check that the privacy settings on your site allow private mail from unknown senders."] = "Wenn Du möchtest, dass %s Dir antworten kann, überprüfe Deine Privatsphären-Einstellungen und erlaube private Nachrichten von unbekannten Absendern.";
$a->strings["Help:"] = "Hilfe:";
$a->strings["Help"] = "Hilfe";
$a->strings["Not Found"] = "Nicht gefunden";
@ -773,7 +790,7 @@ $a->strings["Or - did you try to upload an empty file?"] = "Oder - hast Du versu
$a->strings["File exceeds size limit of %d"] = "Die Datei ist größer als das erlaubte Limit von %d";
$a->strings["File upload failed."] = "Hochladen der Datei fehlgeschlagen.";
$a->strings["Profile Match"] = "Profilübereinstimmungen";
$a->strings["No keywords to match. Please add keywords to your default profile."] = "Keine Schlüsselwörter zum Abgleichen gefunden. Bitte füge einige Schlüsselwörter zu deinem Standardprofil hinzu.";
$a->strings["No keywords to match. Please add keywords to your default profile."] = "Keine Schlüsselwörter zum Abgleichen gefunden. Bitte füge einige Schlüsselwörter zu Deinem Standardprofil hinzu.";
$a->strings["is interested in:"] = "ist interessiert an:";
$a->strings["Connect"] = "Verbinden";
$a->strings["link"] = "Link";
@ -792,7 +809,7 @@ $a->strings["Missing some important data!"] = "Wichtige Daten fehlen!";
$a->strings["Failed to connect with email account using the settings provided."] = "Verbindung zum E-Mail-Konto mit den angegebenen Einstellungen nicht möglich.";
$a->strings["Email settings updated."] = "E-Mail Einstellungen bearbeitet.";
$a->strings["Features updated"] = "Features aktualisiert";
$a->strings["Relocate message has been send to your contacts"] = "Die Umzugsbenachrichtigung wurde an deine Kontakte versendet.";
$a->strings["Relocate message has been send to your contacts"] = "Die Umzugsbenachrichtigung wurde an Deine Kontakte versendet.";
$a->strings["Passwords do not match. Password unchanged."] = "Die Passwörter stimmen nicht überein. Das Passwort bleibt unverändert.";
$a->strings["Empty passwords are not allowed. Password unchanged."] = "Leere Passwörter sind nicht erlaubt. Passwort bleibt unverändert.";
$a->strings["Wrong password."] = "Falsches Passwort.";
@ -828,7 +845,7 @@ $a->strings["disabled"] = "ausgeschaltet";
$a->strings["StatusNet"] = "StatusNet";
$a->strings["Email access is disabled on this site."] = "Zugriff auf E-Mails für diese Seite deaktiviert.";
$a->strings["Email/Mailbox Setup"] = "E-Mail/Postfach-Einstellungen";
$a->strings["If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox."] = "Wenn du mit E-Mail-Kontakten über diesen Service kommunizieren möchtest (optional), gib bitte die Einstellungen für dein Postfach an.";
$a->strings["If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox."] = "Wenn Du mit E-Mail-Kontakten über diesen Service kommunizieren möchtest (optional), gib bitte die Einstellungen für Dein Postfach an.";
$a->strings["Last successful email check:"] = "Letzter erfolgreicher E-Mail Check";
$a->strings["IMAP server name:"] = "IMAP-Server-Name:";
$a->strings["IMAP port:"] = "IMAP-Port:";
@ -853,7 +870,7 @@ $a->strings["Number of items to display per page when viewed from mobile device:
$a->strings["Don't show emoticons"] = "Keine Smilies anzeigen";
$a->strings["Don't show notices"] = "Info-Popups nicht anzeigen";
$a->strings["Infinite scroll"] = "Endloses Scrollen";
$a->strings["Automatic updates only at the top of the network page"] = "Automatische Updates nur, wenn du oben auf der Netzwerkseite bist.";
$a->strings["Automatic updates only at the top of the network page"] = "Automatische Updates nur, wenn Du oben auf der Netzwerkseite bist.";
$a->strings["User Types"] = "Nutzer Art";
$a->strings["Community Types"] = "Gemeinschafts Art";
$a->strings["Normal Account Page"] = "Normales Konto";
@ -868,18 +885,18 @@ $a->strings["Private Forum [Experimental]"] = "Privates Forum [Versuchsstadium]"
$a->strings["Private forum - approved members only"] = "Privates Forum, nur für Mitglieder";
$a->strings["OpenID:"] = "OpenID:";
$a->strings["(Optional) Allow this OpenID to login to this account."] = "(Optional) Erlaube die Anmeldung für dieses Konto mit dieser OpenID.";
$a->strings["Publish your default profile in your local site directory?"] = "Darf dein Standardprofil im Verzeichnis dieses Servers veröffentlicht werden?";
$a->strings["Publish your default profile in your local site directory?"] = "Darf Dein Standardprofil im Verzeichnis dieses Servers veröffentlicht werden?";
$a->strings["No"] = "Nein";
$a->strings["Publish your default profile in the global social directory?"] = "Darf dein Standardprofil im weltweiten Verzeichnis veröffentlicht werden?";
$a->strings["Publish your default profile in the global social directory?"] = "Darf Dein Standardprofil im weltweiten Verzeichnis veröffentlicht werden?";
$a->strings["Hide your contact/friend list from viewers of your default profile?"] = "Liste der Kontakte vor Betrachtern des Standardprofils verbergen?";
$a->strings["Hide your profile details from unknown viewers?"] = "Profil-Details vor unbekannten Betrachtern verbergen?";
$a->strings["If enabled, posting public messages to Diaspora and other networks isn't possible."] = "Wenn aktiviert, ist das senden öffentliche Nachrichten zu Diaspora und anderen Netzwerken nicht möglich";
$a->strings["Allow friends to post to your profile page?"] = "Dürfen deine Kontakte auf deine Pinnwand schreiben?";
$a->strings["Allow friends to tag your posts?"] = "Dürfen deine Kontakte deine Beiträge mit Schlagwörtern versehen?";
$a->strings["Allow us to suggest you as a potential friend to new members?"] = "Dürfen wir dich neuen Mitgliedern als potentiellen Kontakt vorschlagen?";
$a->strings["Permit unknown people to send you private mail?"] = "Dürfen dir Unbekannte private Nachrichten schicken?";
$a->strings["Allow friends to post to your profile page?"] = "Dürfen Deine Kontakte auf Deine Pinnwand schreiben?";
$a->strings["Allow friends to tag your posts?"] = "Dürfen Deine Kontakte Deine Beiträge mit Schlagwörtern versehen?";
$a->strings["Allow us to suggest you as a potential friend to new members?"] = "Dürfen wir Dich neuen Mitgliedern als potentiellen Kontakt vorschlagen?";
$a->strings["Permit unknown people to send you private mail?"] = "Dürfen Dir Unbekannte private Nachrichten schicken?";
$a->strings["Profile is <strong>not published</strong>."] = "Profil ist <strong>nicht veröffentlicht</strong>.";
$a->strings["Your Identity Address is"] = "Die Adresse deines Profils lautet:";
$a->strings["Your Identity Address is"] = "Die Adresse Deines Profils lautet:";
$a->strings["Automatically expire posts after this many days:"] = "Beiträge verfallen automatisch nach dieser Anzahl von Tagen:";
$a->strings["If empty, posts will not expire. Expired posts will be deleted"] = "Wenn leer verfallen Beiträge nie automatisch. Verfallene Beiträge werden gelöscht.";
$a->strings["Advanced expiration settings"] = "Erweiterte Verfallseinstellungen";
@ -893,7 +910,7 @@ $a->strings["Account Settings"] = "Kontoeinstellungen";
$a->strings["Password Settings"] = "Passwort-Einstellungen";
$a->strings["New Password:"] = "Neues Passwort:";
$a->strings["Confirm:"] = "Bestätigen:";
$a->strings["Leave password fields blank unless changing"] = "Lass die Passwort-Felder leer, außer du willst das Passwort ändern";
$a->strings["Leave password fields blank unless changing"] = "Lass die Passwort-Felder leer, außer Du willst das Passwort ändern";
$a->strings["Current Password:"] = "Aktuelles Passwort:";
$a->strings["Your current password to confirm the changes"] = "Dein aktuelles Passwort um die Änderungen zu bestätigen";
$a->strings["Password:"] = "Passwort:";
@ -916,24 +933,24 @@ $a->strings["Default Permissions for New Posts"] = "Standardberechtigungen für
$a->strings["Maximum private messages per day from unknown people:"] = "Maximale Anzahl privater Nachrichten von Unbekannten pro Tag:";
$a->strings["Notification Settings"] = "Benachrichtigungseinstellungen";
$a->strings["By default post a status message when:"] = "Standardmäßig eine Statusnachricht posten, wenn:";
$a->strings["accepting a friend request"] = " du eine Kontaktanfrage akzeptierst";
$a->strings["joining a forum/community"] = " du einem Forum/einer Gemeinschaftsseite beitrittst";
$a->strings["making an <em>interesting</em> profile change"] = " du eine <em>interessante</em> Änderung an deinem Profil durchführst";
$a->strings["accepting a friend request"] = " Du eine Kontaktanfrage akzeptierst";
$a->strings["joining a forum/community"] = " Du einem Forum/einer Gemeinschaftsseite beitrittst";
$a->strings["making an <em>interesting</em> profile change"] = " Du eine <em>interessante</em> Änderung an Deinem Profil durchführst";
$a->strings["Send a notification email when:"] = "Benachrichtigungs-E-Mail senden wenn:";
$a->strings["You receive an introduction"] = " du eine Kontaktanfrage erhältst";
$a->strings["Your introductions are confirmed"] = " eine deiner Kontaktanfragen akzeptiert wurde";
$a->strings["Someone writes on your profile wall"] = " jemand etwas auf deine Pinnwand schreibt";
$a->strings["You receive an introduction"] = " Du eine Kontaktanfrage erhältst";
$a->strings["Your introductions are confirmed"] = " eine Deiner Kontaktanfragen akzeptiert wurde";
$a->strings["Someone writes on your profile wall"] = " jemand etwas auf Deine Pinnwand schreibt";
$a->strings["Someone writes a followup comment"] = " jemand auch einen Kommentar verfasst";
$a->strings["You receive a private message"] = " du eine private Nachricht erhältst";
$a->strings["You receive a friend suggestion"] = " du eine Empfehlung erhältst";
$a->strings["You are tagged in a post"] = " du in einem Beitrag erwähnt wirst";
$a->strings["You are poked/prodded/etc. in a post"] = " du von jemandem angestupst oder sonstwie behandelt wirst";
$a->strings["You receive a private message"] = " Du eine private Nachricht erhältst";
$a->strings["You receive a friend suggestion"] = " Du eine Empfehlung erhältst";
$a->strings["You are tagged in a post"] = " Du in einem Beitrag erwähnt wirst";
$a->strings["You are poked/prodded/etc. in a post"] = " Du von jemandem angestupst oder sonstwie behandelt wirst";
$a->strings["Text-only notification emails"] = "Benachrichtigungs E-Mail als Rein-Text.";
$a->strings["Send text only notification emails, without the html part"] = "Sende Benachrichtigungs E-Mail als Rein-Text - ohne HTML-Teil";
$a->strings["Advanced Account/Page Type Settings"] = "Erweiterte Konto-/Seitentyp-Einstellungen";
$a->strings["Change the behaviour of this account for special situations"] = "Verhalten dieses Kontos in bestimmten Situationen:";
$a->strings["Relocate"] = "Umziehen";
$a->strings["If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."] = "Wenn du dein Profil von einem anderen Server umgezogen hast und einige deiner Kontakte deine Beiträge nicht erhalten, verwende diesen Button.";
$a->strings["If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."] = "Wenn Du Dein Profil von einem anderen Server umgezogen hast und einige Deiner Kontakte Deine Beiträge nicht erhalten, verwende diesen Button.";
$a->strings["Resend relocate message to contacts"] = "Umzugsbenachrichtigung erneut an Kontakte senden";
$a->strings["This introduction has already been accepted."] = "Diese Kontaktanfrage wurde bereits akzeptiert.";
$a->strings["Profile location is not valid or does not contain profile information."] = "Profiladresse ist ungültig oder stellt keine Profildaten zur Verfügung.";
@ -952,48 +969,48 @@ $a->strings["Friends are advised to please try again in 24 hours."] = "Freunde s
$a->strings["Invalid locator"] = "Ungültiger Locator";
$a->strings["Invalid email address."] = "Ungültige E-Mail-Adresse.";
$a->strings["This account has not been configured for email. Request failed."] = "Dieses Konto ist nicht für E-Mail konfiguriert. Anfrage fehlgeschlagen.";
$a->strings["Unable to resolve your name at the provided location."] = "Konnte deinen Namen an der angegebenen Stelle nicht finden.";
$a->strings["You have already introduced yourself here."] = "Du hast dich hier bereits vorgestellt.";
$a->strings["Apparently you are already friends with %s."] = "Es scheint so, als ob du bereits mit %s befreundet bist.";
$a->strings["Unable to resolve your name at the provided location."] = "Konnte Deinen Namen an der angegebenen Stelle nicht finden.";
$a->strings["You have already introduced yourself here."] = "Du hast Dich hier bereits vorgestellt.";
$a->strings["Apparently you are already friends with %s."] = "Es scheint so, als ob Du bereits mit %s befreundet bist.";
$a->strings["Invalid profile URL."] = "Ungültige Profil-URL.";
$a->strings["Disallowed profile URL."] = "Nicht erlaubte Profil-URL.";
$a->strings["Your introduction has been sent."] = "Deine Kontaktanfrage wurde gesendet.";
$a->strings["Please login to confirm introduction."] = "Bitte melde dich an, um die Kontaktanfrage zu bestätigen.";
$a->strings["Incorrect identity currently logged in. Please login to <strong>this</strong> profile."] = "Momentan bist du mit einer anderen Identität angemeldet. Bitte melde Dich mit <strong>diesem</strong> Profil an.";
$a->strings["Please login to confirm introduction."] = "Bitte melde Dich an, um die Kontaktanfrage zu bestätigen.";
$a->strings["Incorrect identity currently logged in. Please login to <strong>this</strong> profile."] = "Momentan bist Du mit einer anderen Identität angemeldet. Bitte melde Dich mit <strong>diesem</strong> Profil an.";
$a->strings["Hide this contact"] = "Verberge diesen Kontakt";
$a->strings["Welcome home %s."] = "Willkommen zurück %s.";
$a->strings["Please confirm your introduction/connection request to %s."] = "Bitte bestätige deine Kontaktanfrage bei %s.";
$a->strings["Please confirm your introduction/connection request to %s."] = "Bitte bestätige Deine Kontaktanfrage bei %s.";
$a->strings["Confirm"] = "Bestätigen";
$a->strings["Please enter your 'Identity Address' from one of the following supported communications networks:"] = "Bitte gib die Adresse deines Profils in einem der unterstützten sozialen Netzwerke an:";
$a->strings["If you are not yet a member of the free social web, <a href=\"http://dir.friendica.com/siteinfo\">follow this link to find a public Friendica site and join us today</a>."] = "Wenn du noch kein Mitglied dieses freien sozialen Netzwerks bist, <a href=\"http://dir.friendica.com/siteinfo\">folge diesem Link</a> um einen öffentlichen Friendica-Server zu finden und beizutreten.";
$a->strings["Please enter your 'Identity Address' from one of the following supported communications networks:"] = "Bitte gib die Adresse Deines Profils in einem der unterstützten sozialen Netzwerke an:";
$a->strings["If you are not yet a member of the free social web, <a href=\"http://dir.friendica.com/siteinfo\">follow this link to find a public Friendica site and join us today</a>."] = "Wenn Du noch kein Mitglied dieses freien sozialen Netzwerks bist, <a href=\"http://Dir.friendica.com/siteinfo\">folge diesem Link</a> um einen öffentlichen Friendica-Server zu finden und beizutreten.";
$a->strings["Friend/Connection Request"] = "Freundschafts-/Kontaktanfrage";
$a->strings["Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca"] = "Beispiele: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca";
$a->strings["Please answer the following:"] = "Bitte beantworte folgendes:";
$a->strings["Does %s know you?"] = "Kennt %s dich?";
$a->strings["Does %s know you?"] = "Kennt %s Dich?";
$a->strings["Add a personal note:"] = "Eine persönliche Notiz beifügen:";
$a->strings["Friendica"] = "Friendica";
$a->strings["StatusNet/Federated Social Web"] = "StatusNet/Federated Social Web";
$a->strings[" - please do not use this form. Instead, enter %s into your Diaspora search bar."] = " - bitte verwende dieses Formular nicht. Stattdessen suche nach %s in deiner Diaspora Suchleiste.";
$a->strings["Your Identity Address:"] = "Adresse deines Profils:";
$a->strings[" - please do not use this form. Instead, enter %s into your Diaspora search bar."] = " - bitte verwende dieses Formular nicht. Stattdessen suche nach %s in Deiner Diaspora Suchleiste.";
$a->strings["Your Identity Address:"] = "Adresse Deines Profils:";
$a->strings["Submit Request"] = "Anfrage abschicken";
$a->strings["Registration successful. Please check your email for further instructions."] = "Registrierung erfolgreich. Eine E-Mail mit weiteren Anweisungen wurde an dich gesendet.";
$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "Versenden der E-Mail fehlgeschlagen. Hier sind deine Account Details:\n\nLogin: %s\nPasswort: %s\n\nDu kannst das Passwort nach dem Anmelden ändern.";
$a->strings["Registration successful. Please check your email for further instructions."] = "Registrierung erfolgreich. Eine E-Mail mit weiteren Anweisungen wurde an Dich gesendet.";
$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "Versenden der E-Mail fehlgeschlagen. Hier sind Deine Account Details:\n\nLogin: %s\nPasswort: %s\n\nDu kannst das Passwort nach dem Anmelden ändern.";
$a->strings["Your registration can not be processed."] = "Deine Registrierung konnte nicht verarbeitet werden.";
$a->strings["Your registration is pending approval by the site owner."] = "Deine Registrierung muss noch vom Betreiber der Seite freigegeben werden.";
$a->strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Die maximale Anzahl täglicher Registrierungen auf dieser Seite wurde überschritten. Bitte versuche es morgen noch einmal.";
$a->strings["You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "Du kannst dieses Formular auch (optional) mit deiner OpenID ausfüllen, indem du deine OpenID angibst und 'Registrieren' klickst.";
$a->strings["If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items."] = "Wenn du nicht mit OpenID vertraut bist, lass dieses Feld bitte leer und fülle die restlichen Felder aus.";
$a->strings["You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "Du kannst dieses Formular auch (optional) mit Deiner OpenID ausfüllen, indem Du Deine OpenID angibst und 'Registrieren' klickst.";
$a->strings["If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items."] = "Wenn Du nicht mit OpenID vertraut bist, lass dieses Feld bitte leer und fülle die restlichen Felder aus.";
$a->strings["Your OpenID (optional): "] = "Deine OpenID (optional): ";
$a->strings["Include your profile in member directory?"] = "Soll dein Profil im Nutzerverzeichnis angezeigt werden?";
$a->strings["Include your profile in member directory?"] = "Soll Dein Profil im Nutzerverzeichnis angezeigt werden?";
$a->strings["Membership on this site is by invitation only."] = "Mitgliedschaft auf dieser Seite ist nur nach vorheriger Einladung möglich.";
$a->strings["Your invitation ID: "] = "ID deiner Einladung: ";
$a->strings["Your invitation ID: "] = "ID Deiner Einladung: ";
$a->strings["Your Full Name (e.g. Joe Smith): "] = "Vollständiger Name (z.B. Max Mustermann): ";
$a->strings["Your Email Address: "] = "Deine E-Mail-Adresse: ";
$a->strings["Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be '<strong>nickname@\$sitename</strong>'."] = "Wähle einen Spitznamen für dein Profil. Dieser muss mit einem Buchstaben beginnen. Die Adresse deines Profils auf dieser Seite wird '<strong>spitzname@\$sitename</strong>' sein.";
$a->strings["Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be '<strong>nickname@\$sitename</strong>'."] = "Wähle einen Spitznamen für Dein Profil. Dieser muss mit einem Buchstaben beginnen. Die Adresse Deines Profils auf dieser Seite wird '<strong>spitzname@\$sitename</strong>' sein.";
$a->strings["Choose a nickname: "] = "Spitznamen wählen: ";
$a->strings["Register"] = "Registrieren";
$a->strings["Import"] = "Import";
$a->strings["Import your profile to this friendica instance"] = "Importiere dein Profil auf diese Friendica Instanz";
$a->strings["Import your profile to this friendica instance"] = "Importiere Dein Profil auf diese Friendica Instanz";
$a->strings["System down for maintenance"] = "System zur Wartung abgeschaltet";
$a->strings["Search"] = "Suche";
$a->strings["Global Directory"] = "Weltweites Verzeichnis";
@ -1008,7 +1025,7 @@ $a->strings["About:"] = "Über:";
$a->strings["No entries (some entries may be hidden)."] = "Keine Einträge (einige Einträge könnten versteckt sein).";
$a->strings["No potential page delegates located."] = "Keine potentiellen Bevollmächtigten für die Seite gefunden.";
$a->strings["Delegate Page Management"] = "Delegiere das Management für die Seite";
$a->strings["Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely."] = "Bevollmächtigte sind in der Lage, alle Aspekte dieses Kontos/dieser Seite zu verwalten, abgesehen von den Grundeinstellungen des Kontos. Bitte gib niemandem eine Bevollmächtigung für deinen privaten Account, dem du nicht absolut vertraust!";
$a->strings["Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely."] = "Bevollmächtigte sind in der Lage, alle Aspekte dieses Kontos/dieser Seite zu verwalten, abgesehen von den Grundeinstellungen des Kontos. Bitte gib niemandem eine Bevollmächtigung für Deinen privaten Account, dem Du nicht absolut vertraust!";
$a->strings["Existing Page Managers"] = "Vorhandene Seitenmanager";
$a->strings["Existing Page Delegates"] = "Vorhandene Bevollmächtigte für die Seite";
$a->strings["Potential Delegates"] = "Potentielle Bevollmächtigte";
@ -1017,13 +1034,13 @@ $a->strings["No entries."] = "Keine Einträge.";
$a->strings["Common Friends"] = "Gemeinsame Freunde";
$a->strings["No contacts in common."] = "Keine gemeinsamen Kontakte.";
$a->strings["Export account"] = "Account exportieren";
$a->strings["Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server."] = "Exportiere deine Accountinformationen und Kontakte. Verwende dies um ein Backup deines Accounts anzulegen und/oder damit auf einen anderen Server umzuziehen.";
$a->strings["Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server."] = "Exportiere Deine Accountinformationen und Kontakte. Verwende dies um ein Backup Deines Accounts anzulegen und/oder damit auf einen anderen Server umzuziehen.";
$a->strings["Export all"] = "Alles exportieren";
$a->strings["Export your accout info, contacts and all your items as json. Could be a very big file, and could take a lot of time. Use this to make a full backup of your account (photos are not exported)"] = "Exportiere deine Account Informationen, Kontakte und alle Einträge als JSON Datei. Dies könnte eine sehr große Datei werden und dementsprechend viel Zeit benötigen. Verwende dies um ein komplettes Backup deines Accounts anzulegen (Fotos werden nicht exportiert).";
$a->strings["Export your accout info, contacts and all your items as json. Could be a very big file, and could take a lot of time. Use this to make a full backup of your account (photos are not exported)"] = "Exportiere Deine Account Informationen, Kontakte und alle Einträge als JSON Datei. Dies könnte eine sehr große Datei werden und dementsprechend viel Zeit benötigen. Verwende dies um ein komplettes Backup Deines Accounts anzulegen (Fotos werden nicht exportiert).";
$a->strings["%1\$s is currently %2\$s"] = "%1\$s ist momentan %2\$s";
$a->strings["Mood"] = "Stimmung";
$a->strings["Set your current mood and tell your friends"] = "Wähle deine aktuelle Stimmung und erzähle sie deinen Freunden";
$a->strings["Do you really want to delete this suggestion?"] = "Möchtest du wirklich diese Empfehlung löschen?";
$a->strings["Set your current mood and tell your friends"] = "Wähle Deine aktuelle Stimmung und erzähle sie Deinen Freunden";
$a->strings["Do you really want to delete this suggestion?"] = "Möchtest Du wirklich diese Empfehlung löschen?";
$a->strings["Friend Suggestions"] = "Kontaktvorschläge";
$a->strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "Keine Vorschläge verfügbar. Falls der Server frisch aufgesetzt wurde, versuche es bitte in 24 Stunden noch einmal.";
$a->strings["Ignore/Hide"] = "Ignorieren/Verbergen";
@ -1090,7 +1107,7 @@ $a->strings["Dislikes:"] = "Dislikes:";
$a->strings["Example: fishing photography software"] = "Beispiel: Fischen Fotografie Software";
$a->strings["(Used for suggesting potential friends, can be seen by others)"] = "(Wird verwendet, um potentielle Freunde zu finden, kann von Fremden eingesehen werden)";
$a->strings["(Used for searching profiles, never shown to others)"] = "(Wird für die Suche nach Profilen verwendet und niemals veröffentlicht)";
$a->strings["Tell us about yourself..."] = "Erzähle uns ein bisschen von dir …";
$a->strings["Tell us about yourself..."] = "Erzähle uns ein bisschen von Dir …";
$a->strings["Hobbies/Interests"] = "Hobbies/Interessen";
$a->strings["Contact information and Social Networks"] = "Kontaktinformationen und Soziale Netzwerke";
$a->strings["Musical interests"] = "Musikalische Interessen";
@ -1100,7 +1117,7 @@ $a->strings["Film/dance/culture/entertainment"] = "Filme/Tänze/Kultur/Unterhalt
$a->strings["Love/romance"] = "Liebe/Romantik";
$a->strings["Work/employment"] = "Arbeit/Anstellung";
$a->strings["School/education"] = "Schule/Ausbildung";
$a->strings["This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet."] = "Dies ist dein <strong>öffentliches</strong> Profil.<br />Es <strong>könnte</strong> für jeden Nutzer des Internets sichtbar sein.";
$a->strings["This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet."] = "Dies ist Dein <strong>öffentliches</strong> Profil.<br />Es <strong>könnte</strong> für jeden Nutzer des Internets sichtbar sein.";
$a->strings["Edit/Manage Profiles"] = "Bearbeite/Verwalte Profile";
$a->strings["Change profile photo"] = "Profilbild ändern";
$a->strings["Create New Profile"] = "Neues Profil anlegen";
@ -1135,9 +1152,9 @@ $a->strings["Suggestions, praise, donations, etc. - please email \"Info\" at Fri
$a->strings["Installed plugins/addons/apps:"] = "Installierte Plugins/Erweiterungen/Apps";
$a->strings["No installed plugins/addons/apps"] = "Keine Plugins/Erweiterungen/Apps installiert";
$a->strings["Authorize application connection"] = "Verbindung der Applikation autorisieren";
$a->strings["Return to your app and insert this Securty Code:"] = "Gehe zu deiner Anwendung zurück und trage dort folgenden Sicherheitscode ein:";
$a->strings["Please login to continue."] = "Bitte melde dich an um fortzufahren.";
$a->strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "Möchtest du dieser Anwendung den Zugriff auf deine Beiträge und Kontakte, sowie das Erstellen neuer Beiträge in deinem Namen gestatten?";
$a->strings["Return to your app and insert this Securty Code:"] = "Gehe zu Deiner Anwendung zurück und trage dort folgenden Sicherheitscode ein:";
$a->strings["Please login to continue."] = "Bitte melde Dich an um fortzufahren.";
$a->strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "Möchtest Du dieser Anwendung den Zugriff auf Deine Beiträge und Kontakte, sowie das Erstellen neuer Beiträge in Deinem Namen gestatten?";
$a->strings["Remote privacy information not available."] = "Entfernte Privatsphäreneinstellungen nicht verfügbar.";
$a->strings["Visible to:"] = "Sichtbar für:";
$a->strings["Personal Notes"] = "Persönliche Notizen";
@ -1147,11 +1164,11 @@ $a->strings["Friendica provides this service for sharing events with other netwo
$a->strings["UTC time: %s"] = "UTC Zeit: %s";
$a->strings["Current timezone: %s"] = "Aktuelle Zeitzone: %s";
$a->strings["Converted localtime: %s"] = "Umgerechnete lokale Zeit: %s";
$a->strings["Please select your timezone:"] = "Bitte wähle deine Zeitzone:";
$a->strings["Please select your timezone:"] = "Bitte wähle Deine Zeitzone:";
$a->strings["Poke/Prod"] = "Anstupsen";
$a->strings["poke, prod or do other things to somebody"] = "Stupse Leute an oder mache anderes mit ihnen";
$a->strings["Recipient"] = "Empfänger";
$a->strings["Choose what you wish to do to recipient"] = "Was willst du mit dem Empfänger machen:";
$a->strings["Choose what you wish to do to recipient"] = "Was willst Du mit dem Empfänger machen:";
$a->strings["Make this post private"] = "Diesen Beitrag privat machen";
$a->strings["Total invitation limit exceeded."] = "Limit für Einladungen erreicht.";
$a->strings["%s : Not a valid email address."] = "%s: Keine gültige Email Adresse.";
@ -1163,15 +1180,15 @@ $a->strings["%d message sent."] = array(
1 => "%d Nachrichten gesendet.",
);
$a->strings["You have no more invitations available"] = "Du hast keine weiteren Einladungen";
$a->strings["Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks."] = "Besuche %s für eine Liste der öffentlichen Server, denen du beitreten kannst. Friendica Mitglieder unterschiedlicher Server können sich sowohl alle miteinander verbinden, als auch mit Mitgliedern anderer Sozialer Netzwerke.";
$a->strings["To accept this invitation, please visit and register at %s or any other public Friendica website."] = "Um diese Kontaktanfrage zu akzeptieren, besuche und registriere dich bitte bei %s oder einer anderen öffentlichen Friendica Website.";
$a->strings["Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join."] = "Friendica Server verbinden sich alle untereinander, um ein großes datenschutzorientiertes Soziales Netzwerk zu bilden, das von seinen Mitgliedern betrieben und kontrolliert wird. Sie können sich auch mit vielen üblichen Sozialen Netzwerken verbinden. Besuche %s für eine Liste alternativer Friendica Server, denen du beitreten kannst.";
$a->strings["Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks."] = "Besuche %s für eine Liste der öffentlichen Server, denen Du beitreten kannst. Friendica Mitglieder unterschiedlicher Server können sich sowohl alle miteinander verbinden, als auch mit Mitgliedern anderer Sozialer Netzwerke.";
$a->strings["To accept this invitation, please visit and register at %s or any other public Friendica website."] = "Um diese Kontaktanfrage zu akzeptieren, besuche und registriere Dich bitte bei %s oder einer anderen öffentlichen Friendica Website.";
$a->strings["Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join."] = "Friendica Server verbinden sich alle untereinander, um ein großes datenschutzorientiertes Soziales Netzwerk zu bilden, das von seinen Mitgliedern betrieben und kontrolliert wird. Sie können sich auch mit vielen üblichen Sozialen Netzwerken verbinden. Besuche %s für eine Liste alternativer Friendica Server, denen Du beitreten kannst.";
$a->strings["Our apologies. This system is not currently configured to connect with other public sites or invite members."] = "Es tut uns leid. Dieses System ist zurzeit nicht dafür konfiguriert, sich mit anderen öffentlichen Seiten zu verbinden oder Mitglieder einzuladen.";
$a->strings["Send invitations"] = "Einladungen senden";
$a->strings["Enter email addresses, one per line:"] = "E-Mail-Adressen eingeben, eine pro Zeile:";
$a->strings["You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web."] = "Du bist herzlich dazu eingeladen, dich mir und anderen guten Freunden auf Friendica anzuschließen - und ein besseres Soziales Netz aufzubauen.";
$a->strings["You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web."] = "Du bist herzlich dazu eingeladen, Dich mir und anderen guten Freunden auf Friendica anzuschließen - und ein besseres Soziales Netz aufzubauen.";
$a->strings["You will need to supply this invitation code: \$invite_code"] = "Du benötigst den folgenden Einladungscode: \$invite_code";
$a->strings["Once you have registered, please connect with me via my profile page at:"] = "Sobald du registriert bist, kontaktiere mich bitte auf meiner Profilseite:";
$a->strings["Once you have registered, please connect with me via my profile page at:"] = "Sobald Du registriert bist, kontaktiere mich bitte auf meiner Profilseite:";
$a->strings["For more information about the Friendica project and why we feel it is important, please visit http://friendica.com"] = "Für weitere Informationen über das Friendica Projekt und warum wir es für ein wichtiges Projekt halten, besuche bitte http://friendica.com";
$a->strings["Photo Albums"] = "Fotoalben";
$a->strings["Contact Photos"] = "Kontaktbilder";
@ -1179,9 +1196,9 @@ $a->strings["Upload New Photos"] = "Neue Fotos hochladen";
$a->strings["Contact information unavailable"] = "Kontaktinformationen nicht verfügbar";
$a->strings["Album not found."] = "Album nicht gefunden.";
$a->strings["Delete Album"] = "Album löschen";
$a->strings["Do you really want to delete this photo album and all its photos?"] = "Möchtest du wirklich dieses Foto-Album und all seine Foto löschen?";
$a->strings["Do you really want to delete this photo album and all its photos?"] = "Möchtest Du wirklich dieses Foto-Album und all seine Foto löschen?";
$a->strings["Delete Photo"] = "Foto löschen";
$a->strings["Do you really want to delete this photo?"] = "Möchtest du wirklich dieses Foto löschen?";
$a->strings["Do you really want to delete this photo?"] = "Möchtest Du wirklich dieses Foto löschen?";
$a->strings["%1\$s was tagged in %2\$s by %3\$s"] = "%1\$s wurde von %3\$s in %2\$s getaggt";
$a->strings["a photo"] = "einem Foto";
$a->strings["Image exceeds size limit of "] = "Die Bildgröße übersteigt das Limit von ";
@ -1219,13 +1236,13 @@ $a->strings["Share"] = "Teilen";
$a->strings["Recent Photos"] = "Neueste Fotos";
$a->strings["Account approved."] = "Konto freigegeben.";
$a->strings["Registration revoked for %s"] = "Registrierung für %s wurde zurückgezogen";
$a->strings["Please login."] = "Bitte melde dich an.";
$a->strings["Please login."] = "Bitte melde Dich an.";
$a->strings["Move account"] = "Account umziehen";
$a->strings["You can import an account from another Friendica server."] = "Du kannst einen Account von einem anderen Friendica Server importieren.";
$a->strings["You need to export your account from the old server and upload it here. We will recreate your old account here with all your contacts. We will try also to inform your friends that you moved here."] = "Du musst deinen Account vom alten Server exportieren und hier hochladen. Wir stellen deinen alten Account mit all deinen Kontakten wieder her. Wir werden auch versuchen all deine Freunde darüber zu informieren, dass du hierher umgezogen bist.";
$a->strings["You need to export your account from the old server and upload it here. We will recreate your old account here with all your contacts. We will try also to inform your friends that you moved here."] = "Du musst Deinen Account vom alten Server exportieren und hier hochladen. Wir stellen Deinen alten Account mit all Deinen Kontakten wieder her. Wir werden auch versuchen all Deine Freunde darüber zu informieren, dass Du hierher umgezogen bist.";
$a->strings["This feature is experimental. We can't import contacts from the OStatus network (statusnet/identi.ca) or from Diaspora"] = "Dieses Feature ist experimentell. Wir können keine Kontakte vom OStatus Netzwerk (statusnet/identi.ca) oder von Diaspora importieren";
$a->strings["Account file"] = "Account Datei";
$a->strings["To export your account, go to \"Settings->Export your personal data\" and select \"Export account\""] = "Um deinen Account zu exportieren, rufe \"Einstellungen -> Persönliche Daten exportieren\" auf und wähle \"Account exportieren\"";
$a->strings["To export your account, go to \"Settings->Export your personal data\" and select \"Export account\""] = "Um Deinen Account zu exportieren, rufe \"Einstellungen -> Persönliche Daten exportieren\" auf und wähle \"Account exportieren\"";
$a->strings["Item not available."] = "Beitrag nicht verfügbar.";
$a->strings["Item was not found."] = "Beitrag konnte nicht gefunden werden.";
$a->strings["Delete this item?"] = "Diesen Beitrag löschen?";
@ -1233,11 +1250,10 @@ $a->strings["show fewer"] = "weniger anzeigen";
$a->strings["Update %s failed. See error logs."] = "Update %s fehlgeschlagen. Bitte Fehlerprotokoll überprüfen.";
$a->strings["Create a New Account"] = "Neues Konto erstellen";
$a->strings["Logout"] = "Abmelden";
$a->strings["Login"] = "Anmeldung";
$a->strings["Nickname or Email address: "] = "Spitzname oder E-Mail-Adresse: ";
$a->strings["Password: "] = "Passwort: ";
$a->strings["Remember me"] = "Anmeldedaten merken";
$a->strings["Or login using OpenID: "] = "Oder melde dich mit deiner OpenID an: ";
$a->strings["Or login using OpenID: "] = "Oder melde Dich mit Deiner OpenID an: ";
$a->strings["Forgot your password?"] = "Passwort vergessen?";
$a->strings["Website Terms of Service"] = "Website Nutzungsbedingungen";
$a->strings["terms of service"] = "Nutzungsbedingungen";
@ -1262,7 +1278,7 @@ $a->strings["Status Messages and Posts"] = "Statusnachrichten und Beiträge";
$a->strings["Profile Details"] = "Profildetails";
$a->strings["Videos"] = "Videos";
$a->strings["Events and Calendar"] = "Ereignisse und Kalender";
$a->strings["Only You Can See This"] = "Nur du kannst das sehen";
$a->strings["Only You Can See This"] = "Nur Du kannst das sehen";
$a->strings["This entry was edited"] = "Dieser Beitrag wurde bearbeitet.";
$a->strings["ignore thread"] = "Thread ignorieren";
$a->strings["unignore thread"] = "Thread nicht mehr ignorieren";
@ -1271,12 +1287,12 @@ $a->strings["ignored"] = "Ignoriert";
$a->strings["Categories:"] = "Kategorien:";
$a->strings["Filed under:"] = "Abgelegt unter:";
$a->strings["via"] = "via";
$a->strings["\n\t\t\tThe friendica developers released update %s recently,\n\t\t\tbut when I tried to install it, something went terribly wrong.\n\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."] = "\nDie Friendica-Entwickler haben vor kurzem das Update %s veröffentlicht, aber bei der Installation ging etwas schrecklich schief.\n\nDas Problem sollte so schnell wie möglich gelöst werden, aber ich schaffe es nicht alleine. Bitte kontaktiere einen Friendica-Entwickler falls du mir nicht alleine helfen kannst. Meine Datenbank könnte ungültig sein.";
$a->strings["\n\t\t\tThe friendica developers released update %s recently,\n\t\t\tbut when I tried to install it, something went terribly wrong.\n\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."] = "\nDie Friendica-Entwickler haben vor kurzem das Update %s veröffentlicht, aber bei der Installation ging etwas schrecklich schief.\n\nDas Problem sollte so schnell wie möglich gelöst werden, aber ich schaffe es nicht alleine. Bitte kontaktiere einen Friendica-Entwickler falls Du mir nicht alleine helfen kannst. Meine Datenbank könnte ungültig sein.";
$a->strings["The error message is\n[pre]%s[/pre]"] = "Die Fehlermeldung lautet\n[pre]%s[/pre]";
$a->strings["Errors encountered creating database tables."] = "Fehler aufgetreten während der Erzeugung der Datenbanktabellen.";
$a->strings["Errors encountered performing database changes."] = "Es sind Fehler beim Bearbeiten der Datenbank aufgetreten.";
$a->strings["Logged out."] = "Abgemeldet.";
$a->strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Beim Versuch dich mit der von dir angegebenen OpenID anzumelden trat ein Problem auf. Bitte überprüfe, dass du die OpenID richtig geschrieben hast.";
$a->strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Beim Versuch Dich mit der von Dir angegebenen OpenID anzumelden trat ein Problem auf. Bitte überprüfe, dass Du die OpenID richtig geschrieben hast.";
$a->strings["The error message was:"] = "Die Fehlermeldung lautete:";
$a->strings["Add New Contact"] = "Neuen Kontakt hinzufügen";
$a->strings["Enter address or web location"] = "Adresse oder Web-Link eingeben";
@ -1317,7 +1333,7 @@ $a->strings["Enable widget to display Network posts only from selected network"]
$a->strings["Save search terms for re-use"] = "Speichere Suchanfragen für spätere Wiederholung.";
$a->strings["Network Tabs"] = "Netzwerk Reiter";
$a->strings["Network Personal Tab"] = "Netzwerk-Reiter: Persönlich";
$a->strings["Enable tab to display only Network posts that you've interacted on"] = "Aktiviert einen Netzwerk-Reiter in dem Nachrichten angezeigt werden mit denen du interagiert hast";
$a->strings["Enable tab to display only Network posts that you've interacted on"] = "Aktiviert einen Netzwerk-Reiter in dem Nachrichten angezeigt werden mit denen Du interagiert hast";
$a->strings["Network New Tab"] = "Netzwerk-Reiter: Neue";
$a->strings["Enable tab to display only new Network posts (from the last 12 hours)"] = "Aktiviert einen Netzwerk-Reiter in dem ausschließlich neue Beiträge (der letzten 12 Stunden) angezeigt werden";
$a->strings["Network Shared Links Tab"] = "Netzwerk-Reiter: Geteilte Links";
@ -1347,10 +1363,10 @@ $a->strings["No browser URL could be matched to this address."] = "Zu dieser Adr
$a->strings["Unable to match @-style Identity Address with a known protocol or email contact."] = "Konnte die @-Adresse mit keinem der bekannten Protokolle oder Email-Kontakte abgleichen.";
$a->strings["Use mailto: in front of address to force email check."] = "Verwende mailto: vor der Email Adresse, um eine Überprüfung der E-Mail-Adresse zu erzwingen.";
$a->strings["The profile address specified belongs to a network which has been disabled on this site."] = "Die Adresse dieses Profils gehört zu einem Netzwerk, mit dem die Kommunikation auf dieser Seite ausgeschaltet wurde.";
$a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können.";
$a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von Dir erhalten können.";
$a->strings["Unable to retrieve contact information."] = "Konnte die Kontaktinformationen nicht empfangen.";
$a->strings["following"] = "folgen";
$a->strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Eine gelöschte Gruppe mit diesem Namen wurde wiederbelebt. Bestehende Berechtigungseinstellungen <strong>könnten</strong> auf diese Gruppe oder zukünftige Mitglieder angewandt werden. Falls du dies nicht möchtest, erstelle bitte eine andere Gruppe mit einem anderen Namen.";
$a->strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Eine gelöschte Gruppe mit diesem Namen wurde wiederbelebt. Bestehende Berechtigungseinstellungen <strong>könnten</strong> auf diese Gruppe oder zukünftige Mitglieder angewandt werden. Falls Du dies nicht möchtest, erstelle bitte eine andere Gruppe mit einem anderen Namen.";
$a->strings["Default privacy group for new contacts"] = "Voreingestellte Gruppe für neue Kontakte";
$a->strings["Everybody"] = "Alle Kontakte";
$a->strings["edit"] = "bearbeiten";
@ -1414,7 +1430,7 @@ $a->strings["Visible to <strong>everybody</strong>"] = "Für <strong>jedermann</
$a->strings["Please enter a video link/URL:"] = "Bitte Link/URL zum Video einfügen:";
$a->strings["Please enter an audio link/URL:"] = "Bitte Link/URL zum Audio einfügen:";
$a->strings["Tag term:"] = "Tag:";
$a->strings["Where are you right now?"] = "Wo hältst du dich jetzt gerade auf?";
$a->strings["Where are you right now?"] = "Wo hältst Du Dich jetzt gerade auf?";
$a->strings["Delete item(s)?"] = "Einträge löschen?";
$a->strings["Post to Email"] = "An E-Mail senden";
$a->strings["Connectors disabled, since \"%s\" is enabled."] = "Konnektoren sind nicht verfügbar, da \"%s\" aktiv ist.";
@ -1539,8 +1555,8 @@ $a->strings["Love/Romance:"] = "Liebesleben:";
$a->strings["Work/employment:"] = "Arbeit/Beschäftigung:";
$a->strings["School/education:"] = "Schule/Ausbildung:";
$a->strings["Click here to upgrade."] = "Zum Upgraden hier klicken.";
$a->strings["This action exceeds the limits set by your subscription plan."] = "Diese Aktion überschreitet die Obergrenze deines Abonnements.";
$a->strings["This action is not available under your subscription plan."] = "Diese Aktion ist in deinem Abonnement nicht verfügbar.";
$a->strings["This action exceeds the limits set by your subscription plan."] = "Diese Aktion überschreitet die Obergrenze Deines Abonnements.";
$a->strings["This action is not available under your subscription plan."] = "Diese Aktion ist in Deinem Abonnement nicht verfügbar.";
$a->strings["End this session"] = "Diese Sitzung beenden";
$a->strings["Your posts and conversations"] = "Deine Beiträge und Unterhaltungen";
$a->strings["Your profile page"] = "Deine Profilseite";
@ -1557,11 +1573,12 @@ $a->strings["Apps"] = "Apps";
$a->strings["Addon applications, utilities, games"] = "Addon Anwendungen, Dienstprogramme, Spiele";
$a->strings["Search site content"] = "Inhalt der Seite durchsuchen";
$a->strings["Conversations on this site"] = "Unterhaltungen auf dieser Seite";
$a->strings["Conversations on the network"] = "Unterhaltungen im Netzwerk";
$a->strings["Directory"] = "Verzeichnis";
$a->strings["People directory"] = "Nutzerverzeichnis";
$a->strings["Information"] = "Information";
$a->strings["Information about this friendica instance"] = "Informationen zu dieser Friendica Instanz";
$a->strings["Conversations from your friends"] = "Unterhaltungen deiner Kontakte";
$a->strings["Conversations from your friends"] = "Unterhaltungen Deiner Kontakte";
$a->strings["Network Reset"] = "Netzwerk zurücksetzen";
$a->strings["Load Network page with no filters"] = "Netzwerk-Seite ohne Filter laden";
$a->strings["Friend Requests"] = "Kontaktanfragen";
@ -1594,8 +1611,8 @@ $a->strings["Invalid OpenID url"] = "Ungültige OpenID URL";
$a->strings["Please enter the required information."] = "Bitte trage die erforderlichen Informationen ein.";
$a->strings["Please use a shorter name."] = "Bitte verwende einen kürzeren Namen.";
$a->strings["Name too short."] = "Der Name ist zu kurz.";
$a->strings["That doesn't appear to be your full (First Last) name."] = "Das scheint nicht dein kompletter Name (Vor- und Nachname) zu sein.";
$a->strings["Your email domain is not among those allowed on this site."] = "Die Domain deiner E-Mail Adresse ist auf dieser Seite nicht erlaubt.";
$a->strings["That doesn't appear to be your full (First Last) name."] = "Das scheint nicht Dein kompletter Name (Vor- und Nachname) zu sein.";
$a->strings["Your email domain is not among those allowed on this site."] = "Die Domain Deiner E-Mail Adresse ist auf dieser Seite nicht erlaubt.";
$a->strings["Not a valid email address."] = "Keine gültige E-Mail-Adresse.";
$a->strings["Cannot use that email."] = "Konnte diese E-Mail-Adresse nicht verwenden.";
$a->strings["Your \"nickname\" can only contain \"a-z\", \"0-9\", \"-\", and \"_\", and must also begin with a letter."] = "Dein Spitzname darf nur aus Buchstaben und Zahlen (\"a-z\",\"0-9\", \"_\" und \"-\") bestehen, außerdem muss er mit einem Buchstaben beginnen.";
@ -1605,11 +1622,11 @@ $a->strings["SERIOUS ERROR: Generation of security keys failed."] = "FATALER FEH
$a->strings["An error occurred during registration. Please try again."] = "Während der Anmeldung ist ein Fehler aufgetreten. Bitte versuche es noch einmal.";
$a->strings["An error occurred creating your default profile. Please try again."] = "Bei der Erstellung des Standardprofils ist ein Fehler aufgetreten. Bitte versuche es noch einmal.";
$a->strings["Friends"] = "Freunde";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tThank you for registering at %2\$s. Your account has been created.\n\t"] = "\nHallo %1\$s,\n\ndanke für deine Registrierung auf %2\$s. Dein Account wurde eingerichtet.";
$a->strings["\n\t\tThe login details are as follows:\n\t\t\tSite Location:\t%3\$s\n\t\t\tLogin Name:\t%1\$s\n\t\t\tPassword:\t%5\$s\n\n\t\tYou may change your password from your account \"Settings\" page after logging\n\t\tin.\n\n\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\tYou may also wish to add some basic information to your default profile\n\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\tWe recommend setting your full name, adding a profile photo,\n\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\tthan that.\n\n\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\tIf you are new and do not know anybody here, they may help\n\t\tyou to make some new and interesting friends.\n\n\n\t\tThank you and welcome to %2\$s."] = "\nDie Anmelde-Details sind die folgenden:\n\tAdresse der Seite:\t%3\$s\n\tBenutzernamename:\t%1\$s\n\tPasswort:\t%5\$s\n\nDu kannst dein Passwort unter \"Einstellungen\" ändern, sobald du dich\nangemeldet hast.\n\nBitte nimm dir ein paar Minuten um die anderen Einstellungen auf dieser\nSeite zu kontrollieren.\n\nEventuell magst du ja auch einige Informationen über dich in deinem\nProfil veröffentlichen, damit andere Leute dich einfacher finden können.\nBearbeite hierfür einfach dein Standard-Profil (über die Profil-Seite).\n\nWir empfehlen dir, deinen kompletten Namen anzugeben und ein zu dir\npassendes Profilbild zu wählen, damit dich alte Bekannte wieder finden.\nAußerdem ist es nützlich, wenn du auf deinem Profil Schlüsselwörter\nangibst. Das erleichtert es, Leute zu finden, die deine Interessen teilen.\n\nWir respektieren deine Privatsphäre - keine dieser Angaben ist nötig.\nWenn du neu im Netzwerk bist und noch niemanden kennst, dann können sie\nallerdings dabei helfen, neue und interessante Kontakte zu knüpfen.\n\nDanke für deine Aufmerksamkeit und willkommen auf %2\$s.";
$a->strings["\n\t\tDear %1\$s,\n\t\t\tThank you for registering at %2\$s. Your account has been created.\n\t"] = "\nHallo %1\$s,\n\ndanke für Deine Registrierung auf %2\$s. Dein Account wurde eingerichtet.";
$a->strings["\n\t\tThe login details are as follows:\n\t\t\tSite Location:\t%3\$s\n\t\t\tLogin Name:\t%1\$s\n\t\t\tPassword:\t%5\$s\n\n\t\tYou may change your password from your account \"Settings\" page after logging\n\t\tin.\n\n\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\tYou may also wish to add some basic information to your default profile\n\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\tWe recommend setting your full name, adding a profile photo,\n\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\tthan that.\n\n\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\tIf you are new and do not know anybody here, they may help\n\t\tyou to make some new and interesting friends.\n\n\n\t\tThank you and welcome to %2\$s."] = "\nDie Anmelde-Details sind die folgenden:\n\tAdresse der Seite:\t%3\$s\n\tBenutzernamename:\t%1\$s\n\tPasswort:\t%5\$s\n\nDu kannst Dein Passwort unter \"Einstellungen\" ändern, sobald Du Dich\nangemeldet hast.\n\nBitte nimm Dir ein paar Minuten um die anderen Einstellungen auf dieser\nSeite zu kontrollieren.\n\nEventuell magst Du ja auch einige Informationen über Dich in Deinem\nProfil veröffentlichen, damit andere Leute Dich einfacher finden können.\nBearbeite hierfür einfach Dein Standard-Profil (über die Profil-Seite).\n\nWir empfehlen Dir, Deinen kompletten Namen anzugeben und ein zu Dir\npassendes Profilbild zu wählen, damit Dich alte Bekannte wieder finden.\nAußerdem ist es nützlich, wenn Du auf Deinem Profil Schlüsselwörter\nangibst. Das erleichtert es, Leute zu finden, die Deine Interessen teilen.\n\nWir respektieren Deine Privatsphäre - keine dieser Angaben ist nötig.\nWenn Du neu im Netzwerk bist und noch niemanden kennst, dann können sie\nallerdings dabei helfen, neue und interessante Kontakte zu knüpfen.\n\nDanke für Deine Aufmerksamkeit und willkommen auf %2\$s.";
$a->strings["Sharing notification from Diaspora network"] = "Freigabe-Benachrichtigung von Diaspora";
$a->strings["Attachments:"] = "Anhänge:";
$a->strings["Do you really want to delete this item?"] = "Möchtest du wirklich dieses Item löschen?";
$a->strings["Do you really want to delete this item?"] = "Möchtest Du wirklich dieses Item löschen?";
$a->strings["Archives"] = "Archiv";
$a->strings["Male"] = "Männlich";
$a->strings["Female"] = "Weiblich";
@ -1673,38 +1690,38 @@ $a->strings["Thank You,"] = "Danke,";
$a->strings["%s Administrator"] = "der Administrator von %s";
$a->strings["%s <!item_type!>"] = "%s <!item_type!>";
$a->strings["[Friendica:Notify] New mail received at %s"] = "[Friendica-Meldung] Neue Nachricht erhalten von %s";
$a->strings["%1\$s sent you a new private message at %2\$s."] = "%1\$s hat dir eine neue private Nachricht auf %2\$s geschickt.";
$a->strings["%1\$s sent you %2\$s."] = "%1\$s schickte dir %2\$s.";
$a->strings["%1\$s sent you a new private message at %2\$s."] = "%1\$s hat Dir eine neue private Nachricht auf %2\$s geschickt.";
$a->strings["%1\$s sent you %2\$s."] = "%1\$s schickte Dir %2\$s.";
$a->strings["a private message"] = "eine private Nachricht";
$a->strings["Please visit %s to view and/or reply to your private messages."] = "Bitte besuche %s, um deine privaten Nachrichten anzusehen und/oder zu beantworten.";
$a->strings["Please visit %s to view and/or reply to your private messages."] = "Bitte besuche %s, um Deine privaten Nachrichten anzusehen und/oder zu beantworten.";
$a->strings["%1\$s commented on [url=%2\$s]a %3\$s[/url]"] = "%1\$s kommentierte [url=%2\$s]a %3\$s[/url]";
$a->strings["%1\$s commented on [url=%2\$s]%3\$s's %4\$s[/url]"] = "%1\$s kommentierte [url=%2\$s]%3\$ss %4\$s[/url]";
$a->strings["%1\$s commented on [url=%2\$s]your %3\$s[/url]"] = "%1\$s kommentierte [url=%2\$s]deinen %3\$s[/url]";
$a->strings["%1\$s commented on [url=%2\$s]your %3\$s[/url]"] = "%1\$s kommentierte [url=%2\$s]Deinen %3\$s[/url]";
$a->strings["[Friendica:Notify] Comment to conversation #%1\$d by %2\$s"] = "[Friendica-Meldung] Kommentar zum Beitrag #%1\$d von %2\$s";
$a->strings["%s commented on an item/conversation you have been following."] = "%s hat einen Beitrag kommentiert, dem du folgst.";
$a->strings["%s commented on an item/conversation you have been following."] = "%s hat einen Beitrag kommentiert, dem Du folgst.";
$a->strings["Please visit %s to view and/or reply to the conversation."] = "Bitte besuche %s, um die Konversation anzusehen und/oder zu kommentieren.";
$a->strings["[Friendica:Notify] %s posted to your profile wall"] = "[Friendica-Meldung] %s hat auf deine Pinnwand geschrieben";
$a->strings["%1\$s posted to your profile wall at %2\$s"] = "%1\$s schrieb auf %2\$s auf deine Pinnwand";
$a->strings["%1\$s posted to [url=%2\$s]your wall[/url]"] = "%1\$s hat etwas auf [url=%2\$s]deiner Pinnwand[/url] gepostet";
$a->strings["[Friendica:Notify] %s tagged you"] = "[Friendica-Meldung] %s hat dich erwähnt";
$a->strings["%1\$s tagged you at %2\$s"] = "%1\$s erwähnte dich auf %2\$s";
$a->strings["%1\$s [url=%2\$s]tagged you[/url]."] = "%1\$s [url=%2\$s]erwähnte dich[/url].";
$a->strings["[Friendica:Notify] %s posted to your profile wall"] = "[Friendica-Meldung] %s hat auf Deine Pinnwand geschrieben";
$a->strings["%1\$s posted to your profile wall at %2\$s"] = "%1\$s schrieb auf %2\$s auf Deine Pinnwand";
$a->strings["%1\$s posted to [url=%2\$s]your wall[/url]"] = "%1\$s hat etwas auf [url=%2\$s]Deiner Pinnwand[/url] gepostet";
$a->strings["[Friendica:Notify] %s tagged you"] = "[Friendica-Meldung] %s hat Dich erwähnt";
$a->strings["%1\$s tagged you at %2\$s"] = "%1\$s erwähnte Dich auf %2\$s";
$a->strings["%1\$s [url=%2\$s]tagged you[/url]."] = "%1\$s [url=%2\$s]erwähnte Dich[/url].";
$a->strings["[Friendica:Notify] %s shared a new post"] = "[Friendica Benachrichtigung] %s hat einen Beitrag geteilt";
$a->strings["%1\$s shared a new post at %2\$s"] = "%1\$s hat einen neuen Beitrag auf %2\$s geteilt";
$a->strings["%1\$s [url=%2\$s]shared a post[/url]."] = "%1\$s [url=%2\$s]hat einen Beitrag geteilt[/url].";
$a->strings["[Friendica:Notify] %1\$s poked you"] = "[Friendica-Meldung] %1\$s hat dich angestupst";
$a->strings["%1\$s poked you at %2\$s"] = "%1\$s hat dich auf %2\$s angestupst";
$a->strings["%1\$s [url=%2\$s]poked you[/url]."] = "%1\$s [url=%2\$s]hat dich angestupst[/url].";
$a->strings["[Friendica:Notify] %s tagged your post"] = "[Friendica-Meldung] %s hat deinen Beitrag getaggt";
$a->strings["%1\$s tagged your post at %2\$s"] = "%1\$s erwähnte deinen Beitrag auf %2\$s";
$a->strings["[Friendica:Notify] %1\$s poked you"] = "[Friendica-Meldung] %1\$s hat Dich angestupst";
$a->strings["%1\$s poked you at %2\$s"] = "%1\$s hat Dich auf %2\$s angestupst";
$a->strings["%1\$s [url=%2\$s]poked you[/url]."] = "%1\$s [url=%2\$s]hat Dich angestupst[/url].";
$a->strings["[Friendica:Notify] %s tagged your post"] = "[Friendica-Meldung] %s hat Deinen Beitrag getaggt";
$a->strings["%1\$s tagged your post at %2\$s"] = "%1\$s erwähnte Deinen Beitrag auf %2\$s";
$a->strings["%1\$s tagged [url=%2\$s]your post[/url]"] = "%1\$s erwähnte [url=%2\$s]Deinen Beitrag[/url]";
$a->strings["[Friendica:Notify] Introduction received"] = "[Friendica-Meldung] Kontaktanfrage erhalten";
$a->strings["You've received an introduction from '%1\$s' at %2\$s"] = "Du hast eine Kontaktanfrage von '%1\$s' auf %2\$s erhalten";
$a->strings["You've received [url=%1\$s]an introduction[/url] from %2\$s."] = "Du hast eine [url=%1\$s]Kontaktanfrage[/url] von %2\$s erhalten.";
$a->strings["You may visit their profile at %s"] = "Hier kannst du das Profil betrachten: %s";
$a->strings["You may visit their profile at %s"] = "Hier kannst Du das Profil betrachten: %s";
$a->strings["Please visit %s to approve or reject the introduction."] = "Bitte besuche %s, um die Kontaktanfrage anzunehmen oder abzulehnen.";
$a->strings["[Friendica:Notify] A new person is sharing with you"] = "[Friendica Benachrichtigung] Eine neue Person teilt mit dir";
$a->strings["%1\$s is sharing with you at %2\$s"] = "%1\$s teilt mit dir auf %2\$s";
$a->strings["[Friendica:Notify] A new person is sharing with you"] = "[Friendica Benachrichtigung] Eine neue Person teilt mit Dir";
$a->strings["%1\$s is sharing with you at %2\$s"] = "%1\$s teilt mit Dir auf %2\$s";
$a->strings["[Friendica:Notify] You have a new follower"] = "[Friendica Benachrichtigung] Du hast einen neuen Kontakt auf ";
$a->strings["You have a new follower at %2\$s : %1\$s"] = "Du hast einen neuen Kontakt auf %2\$s: %1\$s";
$a->strings["[Friendica:Notify] Friend suggestion received"] = "[Friendica-Meldung] Kontaktvorschlag erhalten";
@ -1714,11 +1731,11 @@ $a->strings["Name:"] = "Name:";
$a->strings["Photo:"] = "Foto:";
$a->strings["Please visit %s to approve or reject the suggestion."] = "Bitte besuche %s, um den Vorschlag zu akzeptieren oder abzulehnen.";
$a->strings["[Friendica:Notify] Connection accepted"] = "[Friendica-Benachrichtigung] Kontaktanfrage bestätigt";
$a->strings["'%1\$s' has acepted your connection request at %2\$s"] = "'%1\$s' hat deine Kontaktanfrage auf %2\$s bestätigt";
$a->strings["%2\$s has accepted your [url=%1\$s]connection request[/url]."] = "%2\$s hat deine [url=%1\$s]Kontaktanfrage[/url] akzeptiert.";
$a->strings["'%1\$s' has acepted your connection request at %2\$s"] = "'%1\$s' hat Deine Kontaktanfrage auf %2\$s bestätigt";
$a->strings["%2\$s has accepted your [url=%1\$s]connection request[/url]."] = "%2\$s hat Deine [url=%1\$s]Kontaktanfrage[/url] akzeptiert.";
$a->strings["You are now mutual friends and may exchange status updates, photos, and email\n\twithout restriction."] = "Ihr seit nun beidseitige Freunde und könnt Statusmitteilungen, Bilder und Emails ohne Einschränkungen austauschen.";
$a->strings["Please visit %s if you wish to make any changes to this relationship."] = "Bitte besuche %s, wenn du Änderungen an eurer Beziehung vornehmen willst.";
$a->strings["'%1\$s' has chosen to accept you a \"fan\", which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically."] = "'%1\$s' hat sich entschieden dich als \"Fan\" zu akzeptieren, dies schränkt einige Kommunikationswege - wie private Nachrichten und einige Interaktionsmöglichkeiten auf der Profilseite - ein. Wenn dies eine Berühmtheiten- oder Gemeinschaftsseite ist, werden diese Einstellungen automatisch vorgenommen.";
$a->strings["Please visit %s if you wish to make any changes to this relationship."] = "Bitte besuche %s, wenn Du Änderungen an eurer Beziehung vornehmen willst.";
$a->strings["'%1\$s' has chosen to accept you a \"fan\", which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically."] = "'%1\$s' hat sich entschieden Dich als \"Fan\" zu akzeptieren, dies schränkt einige Kommunikationswege - wie private Nachrichten und einige Interaktionsmöglichkeiten auf der Profilseite - ein. Wenn dies eine Berühmtheiten- oder Gemeinschaftsseite ist, werden diese Einstellungen automatisch vorgenommen.";
$a->strings["'%1\$s' may choose to extend this into a two-way or more permissive relationship in the future. "] = "'%1\$s' kann den Kontaktstatus zu einem späteren Zeitpunkt erweitern und diese Einschränkungen aufheben. ";
$a->strings["[Friendica System:Notify] registration request"] = "[Friendica System:Benachrichtigung] Registrationsanfrage";
$a->strings["You've received a registration request from '%1\$s' at %2\$s"] = "Du hast eine Registrierungsanfrage von %2\$s auf '%1\$s' erhalten";
@ -1737,7 +1754,7 @@ $a->strings["%d contact not imported"] = array(
0 => "%d Kontakt nicht importiert",
1 => "%d Kontakte nicht importiert",
);
$a->strings["Done. You can now login with your username and password"] = "Erledigt. Du kannst dich jetzt mit deinem Nutzernamen und Passwort anmelden";
$a->strings["Done. You can now login with your username and password"] = "Erledigt. Du kannst Dich jetzt mit Deinem Nutzernamen und Passwort anmelden";
$a->strings["toggle mobile"] = "auf/von Mobile Ansicht wechseln";
$a->strings["Theme settings"] = "Themeneinstellungen";
$a->strings["Set resize level for images in posts and comments (width and height)"] = "Wähle das Vergrößerungsmaß für Bilder in Beiträgen und Kommentaren (Höhe und Breite)";

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more