Merge remote-tracking branch 'upstream/develop'

This commit is contained in:
Michael Vogel 2015-01-02 00:02:45 +01:00
commit f9a6cbd89e
36 changed files with 23740 additions and 23146 deletions

50
doc/Developers-Intro.md Normal file
View file

@ -0,0 +1,50 @@
Where to get started to help improve Friendica?
===============================================
* [Home](help)
Do you want to help us improve Friendica? Here we have compiled some hints on how to get started and some tasks to help you choose. A project like Friendica is the sum of many different contributions. **Very different skills are required to make good software. Some of them involve coding, others do not.** We are looking for helpers in all areas, whether you write text or code, whether you spread the word to convince people or design new icons. Whether you feel like an expert or like a newbie - join us with your ideas!
**Contact us**
The discussion of Friendica development takes place in the following Friendica forums:
* The main [forum for Friendica development](https://friendika.openmindspace.org/profile/friendicadevelopers)
* The [forum for Friendica theme development](https://friendica.eu/profile/ftdevs)
**Help other users**
Remember the questions you had when you first tried Friendica? A good place to start can be to help new people find their way around Friendica in the [general support forum](https://helpers.pyxis.uberspace.de/profile/helpers). Welcome them, answer their questions, point them to documentation or ping other helpers directly if you can't help but think you know who can.
**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.
**Design**
Are you good at designing things? If you have seen Friendica you probably have ideas to improve it, haven't you?
* 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!
* 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.
* **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.
* Talk to design people if you know any.
* Let us know about your plans [in the dev forum](https://friendika.openmindspace.org/profile/friendicadevelopers) and the [theme developer forum](https://friendica.eu/profile/ftdevs). Do not worry about cross-posting.
* **Client software:** There are free software clients that do somehow work with Friendica but most of them need love and maintenance. Also, they were mostly made for other platforms using the StatusNet API. This means they lack:w
the features that are really specific to Friendica. Popular clients you might want to have a look at are:
* [Hotot (Linux)](http://hotot.org/) - abandoned
* [Friendica for Android](https://github.com/max-weller/friendica-for-android) - abandoned
* You can find more working client software in [Wikipedia](https://en.wikipedia.org/wiki/Friendica).

View file

@ -1,23 +0,0 @@
Friendica Developer Guide
===================
**Here is how you can join us.**
First, get yourself a working git package on the system where you will be
doing development.
Create your own github account.
You may fork/clone the Friendica repository from [https://github.com/friendica/friendica.git](https://github.com/friendica/friendica.git).
Follow the instructions provided here: [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/)
to create and use your own tracking fork on github
Then go to your github page and create a "Pull request" when you are ready
to notify us to merge your work.
**Important**
Please pull in any changes from the project repository and merge them with your work **before** issuing a pull request. We reserve the right to reject any patch which results in a large number of merge conflicts. This is especially true in the case of language translations - where we may not be able to understand the subtle differences between conflicting versions.
Also - **test your changes**. Don't assume that a simple fix won't break something else. If possible get an experienced Friendica developer to review the code.

36
doc/Github.md Normal file
View file

@ -0,0 +1,36 @@
Friendica on Github
===================
* [Home](help)
**Here is how you can work on the code with us**
1. Install git on the system you will be developing on.
2. Create your own [github](https://github.com) account.
3. Fork the Friendica repository from [https://github.com/friendica/friendica.git](https://github.com/friendica/friendica.git).
4. Clone your fork from your Github account to your machine. Follow the instructions provided here: [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/) to create and use your own tracking fork on github
5. Commit your changes to your fork. Then go to your github page and create a "Pull request" to notify us to merge your work.
**Branches**
There are two branches in the main repo on Github:
1. master: This branch contains stable releases only.
2. develop: This branch contains the latest code. This is what you want to work with.
**Important**
Please pull in any changes from the project repository and merge them with your work **before** issuing a pull request. We reserve the right to reject any patch which results in a large number of merge conflicts. This is especially true in the case of language translations - where we may not be able to understand the subtle differences between conflicting versions.
Also - **test your changes**. Don't assume that a simple fix won't break something else. If possible get an experienced Friendica developer to review the code.
**Vagrant**
[Vagrant](https://www.vagrantup.com/) is a virtualization solution for developers. No need to setup up a webserver 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.
2. git clone Friendica (note the Vagrantfile inside).
3. Run vagrant up, have some patience.
4. Run vagrant ssh to log into the virtual machine.
5. It depends on the network setup of your host and virtual box guest how you reach the friendica web interface of the VM.

View file

@ -1,7 +1,7 @@
Friendica Documentation and Resources
=====================================
**Contents**
**User Manual**
* General functions - first steps
* [Account Basics](help/Account-Basics)
@ -10,7 +10,7 @@ Friendica Documentation and Resources
* [BBCode tag reference](help/BBCode)
* [Comment, sort and delete posts](help/Text_comment)
* [Profiles](help/Profiles)
* You and other user
* You and other users
* [Connectors](help/Connectors)
* [Making Friends](help/Making-Friends)
* [Groups and Privacy](help/Groups-and-Privacy)
@ -19,12 +19,11 @@ Friendica Documentation and Resources
* [Chats](help/Chats)
* Further information
* [Improve Performance](help/Improve-Performance)
* [Move Account](help/Move-Account)
* [Remove Account](help/Remove-Account)
* [Bugs and Issues](help/Bugs-and-Issues)
* [Move your account](help/Move-Account)
* [Delete your account](help/Remove-Account)
* [Frequently asked questions (FAQ)](help/FAQ)
**Technical Documentation**
**Admin Manual**
* [Install](help/Install)
* [Settings](help/Settings)
@ -32,10 +31,14 @@ Friendica Documentation and Resources
* [Installing Connectors (Facebook/Twitter/StatusNet)](help/Installing-Connectors)
* [Message Flow](help/Message-Flow)
* [Using SSL with Friendica](help/SSL)
* [Developers](help/Developers)
* [Twitter/StatusNet API Functions](help/api)
* [Translation of Friendica](help/translations)
**Developer Manual**
* [Where to get started?](help/Developers-Intro)
* [Help on Github](help/Github)
* [How to translate Friendica](help/translations)
* [Bugs and Issues](help/Bugs-and-Issues)
**External Resources**

View file

@ -196,6 +196,24 @@ Current hooks:
'email' => email to look up the avatar for
'url' => the (string) generated URL of the avatar
**'emailer_send_prepare'** - called from Emailer::send() before building the mime message
$b is (array) , params to Emailer::send()
'fromName' => name of the sender
'fromEmail' => email fo the sender
'replyTo' => replyTo address to direct responses
'toEmail' => destination email address
'messageSubject' => subject of the message
'htmlVersion' => html version of the message
'textVersion' => text only version of the message
'additionalMailHeader' => additions to the smtp mail header
**'emailer_send'** - called before calling PHP's mail()
$b is (array) , params to mail()
'to'
'subject'
'body'
'headers'
A complete list of all hook callbacks with file locations (generated 14-Feb-2012): Please see the source for details of any hooks not documented above.

View file

@ -14,9 +14,12 @@ class Emailer {
* @param htmlVersion html version of the message
* @param textVersion text only version of the message
* @param additionalMailHeader additions to the smtp mail header
* @param optional uid user id of the destination user
*/
static public function send($params) {
call_hooks('emailer_send_prepare', $params);
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
@ -49,11 +52,18 @@ class Emailer {
"--" . $mimeBoundary . "--\n"; // message ending
// send the message
$hookdata = array(
'to' => $params['toEmail'],
'subject' => $messageSubject,
'body' => $multipartMessageBody,
'headers' => $messageHeader
);
call_hooks("emailer_send", $hookdata);
$res = mail(
$params['toEmail'], // send to address
$messageSubject, // subject
$multipartMessageBody, // message body
$messageHeader // message headers
$hookdata['to'], // send to address
$hookdata['subject'], // subject
$hookdata['body'], // message body
$hookdata['headers'] // message headers
);
logger("header " . 'To: ' . $params['toEmail'] . "\n" . $messageHeader, LOGGER_DEBUG);
logger("return value " . (($res)?"true":"false"), LOGGER_DEBUG);

View file

@ -764,11 +764,16 @@ function get_photo_info($url) {
if (is_null($data)) {
$img_str = fetch_url($url, true, $redirects, 4);
$filesize = strlen($img_str);
$tempfile = tempnam(get_temppath(), "cache");
file_put_contents($tempfile, $img_str);
$data = getimagesize($tempfile);
unlink($tempfile);
if ($data)
$data["size"] = $filesize;
Cache::set($url, serialize($data));
} else
$data = unserialize($data);

View file

@ -197,6 +197,7 @@
}
function api_error(&$a, $type, $error) {
# TODO: https://dev.twitter.com/overview/api/response-codes
$r = "<status><error>".$error."</error><request>".$a->query_string."</request></status>";
switch($type){
case "xml":
@ -871,8 +872,10 @@
$in_reply_to_screen_name = NULL;
}
$converted = api_convert_item($item);
$status_info = array(
'text' => trim(html2plain(bbcode(api_clean_plain_items($lastwall['body']), false, false, 2, true), 0)),
'text' => $converted["text"],
'truncated' => false,
'created_at' => api_date($lastwall['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
@ -884,19 +887,17 @@
'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => NULL,
'favorited' => false,
// attachments
'favorited' => $lastwall['starred'] ? true : false,
'user' => $user_info,
'statusnet_html' => trim(bbcode($lastwall['body'], false, false)),
'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $lastwall['parent'],
);
if ($lastwall['title'] != "")
$status_info['statusnet_html'] = "<h4>".bbcode($lastwall['title'])."</h4>\n".$status_info['statusnet_html'];
if (count($converted["attachments"]) > 0)
$status_info["attachments"] = $converted["attachments"];
$entities = api_get_entitities($status_info['text'], $lastwall['body']);
if (count($entities) > 0)
$status_info['entities'] = $entities;
if (count($converted["entities"]) > 0)
$status_info["entities"] = $converted["entities"];
if (($lastwall['item_network'] != "") AND ($status["source"] == 'web'))
$status_info["source"] = network_to_name($lastwall['item_network']);
@ -970,8 +971,11 @@
}
}
}
$converted = api_convert_item($item);
$user_info['status'] = array(
'text' => trim(html2plain(bbcode(api_clean_plain_items($lastwall['body']), false, false, 2, true), 0)),
'text' => $converted["text"],
'truncated' => false,
'created_at' => api_date($lastwall['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
@ -983,17 +987,16 @@
'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => NULL,
'favorited' => false,
'statusnet_html' => trim(bbcode($lastwall['body'], false, false)),
'favorited' => $lastwall['starred'] ? true : false,
'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $lastwall['parent'],
);
if ($lastwall['title'] != "")
$user_info['statusnet_html'] = "<h4>".bbcode($lastwall['title'])."</h4>\n".$user_info['statusnet_html'];
if (count($converted["attachments"]) > 0)
$user_info["status"]["attachments"] = $converted["attachments"];
$entities = api_get_entitities($user_info['text'], $lastwall['body']);
if (count($entities) > 0)
$user_info['entities'] = $entities;
if (count($converted["entities"]) > 0)
$user_info["status"]["entities"] = $converted["entities"];
if (($lastwall['item_network'] != "") AND ($user_info["status"]["source"] == 'web'))
$user_info["status"]["source"] = network_to_name($lastwall['item_network']);
@ -1102,9 +1105,9 @@
// 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.
// at the network timeline just mark everything seen.
$r = q("UPDATE `item` SET `unseen` = 0
$r = q("UPDATE `item` SET `unseen` = 0
WHERE `unseen` = 1 AND `uid` = %d",
//intval($user_info['uid'])
intval(api_user())
@ -1198,7 +1201,7 @@
api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
/**
*
*
*/
function api_statuses_show(&$a, $type){
if (api_user()===false) return false;
@ -1419,9 +1422,9 @@
api_register_func('api/statuses/destroy','api_statuses_destroy', true);
/**
*
*
* http://developer.twitter.com/doc/get/statuses/mentions
*
*
*/
function api_statuses_mentions(&$a, $type){
if (api_user()===false) return false;
@ -1568,6 +1571,68 @@
api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
/**
* Star/unstar an item
* param: id : id of the item
*
* api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid
*/
function api_favorites_create_destroy(&$a, $type){
if (api_user()===false) return false;
# for versioned api.
# TODO: we need a better global soluton
$action_argv_id=2;
if ($a->argv[1]=="1.1") $action_argv_id=3;
if ($a->argc<=$action_argv_id) die(api_error($a, $type, t("Invalid request.")));
$action = str_replace(".".$type,"",$a->argv[$action_argv_id]);
if ($a->argc==$action_argv_id+2) {
$itemid = intval($a->argv[$action_argv_id+1]);
} else {
$itemid = intval($_REQUEST['id']);
}
$item = q("SELECT * FROM item WHERE id=%d AND uid=%d",
$itemid, api_user());
if ($item===false || count($item)==0) die(api_error($a, $type, t("Invalid item.")));
switch($action){
case "create":
$item[0]['starred']=1;
break;
case "destroy":
$item[0]['starred']=0;
break;
default:
die(api_error($a, $type, t("Invalid action. ".$action)));
}
$r = q("UPDATE item SET starred=%d WHERE id=%d AND uid=%d",
$item[0]['starred'], $itemid, api_user());
q("UPDATE thread SET starred=%d WHERE iid=%d AND uid=%d",
$item[0]['starred'], $itemid, api_user());
if ($r===false) die(api_error($a, $type, t("DB error")));
$user_info = api_get_user($a);
$ret = api_format_items($item,$user_info)[0];
$data = array('$status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("status", $type, $data);
}
api_register_func('api/favorites/create', 'api_favorites_create_destroy', true);
api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true);
function api_favorites(&$a, $type){
global $called_api;
@ -1603,7 +1668,7 @@
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d AND `verb` = '%s'
WHERE `item`.`uid` = %d
AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `item`.`starred` = 1
AND `contact`.`id` = `item`.`contact-id`
@ -1612,7 +1677,6 @@
AND `item`.`id`>%d
ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
intval(api_user()),
dbesc(ACTIVITY_POST),
intval($since_id),
intval($start), intval($count)
);
@ -1633,6 +1697,9 @@
api_register_func('api/favorites','api_favorites', true);
function api_format_as($a, $ret, $user_info) {
$as = array();
@ -1740,6 +1807,67 @@
return $ret;
}
function api_convert_item($item) {
$body = $item['body'];
$attachments = api_get_attachments($body);
// Workaround for ostatus messages where the title is identically to the body
$html = bbcode(api_clean_plain_items($body), false, false, 2, true);
$statusbody = trim(html2plain($html, 0));
// handle data: images
$statusbody = api_format_items_embeded_images($item,$statusbody);
$statustitle = trim($item['title']);
if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
$statustext = trim($statusbody);
else
$statustext = trim($statustitle."\n\n".$statusbody);
if (($item["network"] == NETWORK_FEED) and (strlen($statustext)> 1000))
$statustext = substr($statustext, 0, 1000)."... \n".$item["plink"];
$statushtml = trim(bbcode($body, false, false));
if ($item['title'] != "")
$statushtml = "<h4>".bbcode($item['title'])."</h4>\n".$statushtml;
$entities = api_get_entitities($statustext, $body);
return(array("text" => $statustext, "html" => $statushtml, "attachments" => $attachments, "entities" => $entities));
}
function api_get_attachments(&$body) {
$text = $body;
$text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $text);
$URLSearchString = "^\[\]";
$ret = preg_match_all("/\[img\]([$URLSearchString]*)\[\/img\]/ism", $text, $images);
if (!$ret)
return false;
require_once("include/Photo.php");
$attachments = array();
foreach ($images[1] AS $image) {
$imagedata = get_photo_info($image);
if ($imagedata)
$attachments[] = array("url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]);
}
if (strstr($_SERVER['HTTP_USER_AGENT'], "AndStatus"))
foreach ($images[0] AS $orig)
$body = str_replace($orig, "", $body);
return $attachments;
}
function api_get_entitities(&$text, $bbcode) {
/*
To-Do:
@ -1907,7 +2035,7 @@
$text);
return $text;
}
function api_format_items($r,$user_info, $filter_user = false) {
$a = get_app();
@ -1961,29 +2089,10 @@
$in_reply_to_status_id_str = NULL;
}
// Workaround for ostatus messages where the title is identically to the body
//$statusbody = trim(html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 5, true), 0));
$html = bbcode(api_clean_plain_items($item['body']), false, false, 2, true);
$statusbody = trim(html2plain($html, 0));
// handle data: images
$statusbody = api_format_items_embeded_images($item,$statusbody);
$statustitle = trim($item['title']);
$converted = api_convert_item($item);
if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
$statustext = trim($statusbody);
else
$statustext = trim($statustitle."\n\n".$statusbody);
if (($item["network"] == NETWORK_FEED) and (strlen($statustext)> 1000))
$statustext = substr($statustext, 0, 1000)."... \n".$item["plink"];
$statushtml = trim(bbcode($item['body'], false, false));
$status = array(
'text' => $statustext,
'text' => $converted["text"],
'truncated' => False,
'created_at'=> api_date($item['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
@ -1996,19 +2105,17 @@
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => NULL,
'favorited' => $item['starred'] ? true : false,
//'attachments' => array(),
'user' => $status_user ,
//'entities' => NULL,
'statusnet_html' => $statushtml,
'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $item['parent'],
);
if ($item['title'] != "")
$status['statusnet_html'] = "<h4>".bbcode($item['title'])."</h4>\n".$status['statusnet_html'];
if (count($converted["attachments"]) > 0)
$status["attachments"] = $converted["attachments"];
$entities = api_get_entitities($status['text'], $item['body']);
if (count($entities) > 0)
$status['entities'] = $entities;
if (count($converted["entities"]) > 0)
$status["entities"] = $converted["entities"];
if (($item['item_network'] != "") AND ($status["source"] == 'web'))
$status["source"] = network_to_name($item['item_network']);
@ -2367,7 +2474,7 @@
if ($user_id !="") {
$sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id);
}
}
elseif($screen_name !=""){
$sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'";
}
@ -2377,7 +2484,7 @@
intval($since_id),
intval($start), intval($count)
);
$ret = Array();
foreach($r as $item) {
@ -2479,7 +2586,7 @@
echo json_encode($r[0]);
}
killme();
killme();
}
api_register_func('api/friendica/photos/list', 'api_fr_photos_list', true);
@ -2697,9 +2804,6 @@ function api_best_nickname(&$contacts) {
/*
Not implemented by now:
favorites
favorites/create
favorites/destroy
statuses/retweets_of_me
friendships/create
friendships/destroy

View file

@ -90,8 +90,9 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
} else {
$Text = bbcode($Text, $preserve_nl, false, 4);
// Libertree doesn't convert a harizontal rule if there isn't a linefeed
$Text = str_replace("<hr />", "<br /><hr />", $Text);
$Text = str_replace(array("<hr />", "<hr>"), array("<br /><hr />", "<br><hr>"), $Text);
}
// Now convert HTML to Markdown

View file

@ -2028,6 +2028,7 @@ function diaspora_retraction($importer,$xml) {
dbesc(datetime_convert()),
intval($r[0]['id'])
);
delete_thread($r[0]['id']);
}
}
}
@ -2100,6 +2101,7 @@ function diaspora_signed_retraction($importer,$xml,$msg) {
dbesc(datetime_convert()),
intval($r[0]['id'])
);
delete_thread($r[0]['id']);
// Now check if the retraction needs to be relayed by us
//

View file

@ -21,6 +21,7 @@ function notification($params) {
$thanks = t('Thank You,');
$sitename = $a->config['sitename'];
$site_admin = sprintf( t('%s Administrator'), $sitename);
$nickname = "";
$sender_name = $product;
$hostname = $a->get_hostname();
@ -29,6 +30,10 @@ function notification($params) {
$sender_email = t('noreply') . '@' . $hostname;
$user = q("SELECT `nickname` FROM `user` WHERE `uid` = %d", intval($params['uid']));
if ($user)
$nickname = $user[0]["nickname"];
// with $params['show_in_notification_page'] == false, the notification isn't inserted into
// the database, and an email is sent if applicable.
// default, if not specified: true
@ -37,6 +42,7 @@ function notification($params) {
$additional_mail_header = "";
$additional_mail_header .= "Precedence: list\n";
$additional_mail_header .= "X-Friendica-Host: ".$hostname."\n";
$additional_mail_header .= "X-Friendica-Account: <".$nickname."@".$hostname.">\n";
$additional_mail_header .= "X-Friendica-Platform: ".FRIENDICA_PLATFORM."\n";
$additional_mail_header .= "X-Friendica-Version: ".FRIENDICA_VERSION."\n";
$additional_mail_header .= "List-ID: <notification.".$hostname.">\n";
@ -344,7 +350,7 @@ function notification($params) {
$show_in_notification_page = false;
}
$subject .= " (".$nickname."@".$hostname.")";
$h = array(
'params' => $params,
@ -592,6 +598,7 @@ function notification($params) {
// use the Emailer class to send the message
return Emailer::send(array(
'uid' => $params['uid'],
'fromName' => $sender_name,
'fromEmail' => $sender_email,
'replyTo' => $sender_email,

View file

@ -16,7 +16,7 @@ function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb)
function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
{
$savestart = str_replace('$', '%', $startbb);
$savestart = str_replace('$', '\x01', $startbb);
$replace = false;
$xpath = new DomXPath($doc);
@ -37,7 +37,7 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
foreach ($attributes as $attribute => $value) {
$startbb = str_replace('%'.++$i, '$1', $startbb);
$startbb = str_replace('\x01'.++$i, '$1', $startbb);
if (strpos('*'.$startbb, '$1') > 0) {

View file

@ -872,9 +872,18 @@ function get_atom_elements($feed, $item, $contact = array()) {
}
if (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND $contact['fetch_further_information']) {
$res["body"] = $res["title"].add_page_info($res['plink'], false, "", ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_blacklist']);
$preview = "";
// Handle enclosures and treat them as preview picture
if (isset($attach))
foreach ($attach AS $attachment)
if ($attachment->type == "image/jpeg")
$preview = $attachment->link;
$res["body"] = $res["title"].add_page_info($res['plink'], false, $preview, ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_blacklist']);
$res["title"] = "";
$res["object-type"] = ACTIVITY_OBJ_BOOKMARK;
unset($res["attach"]);
} elseif (isset($contact["network"]) AND ($contact["network"] == NETWORK_OSTATUS))
$res["body"] = add_page_info_to_body($res["body"]);
elseif (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND strstr($res['plink'], ".app.net/")) {
@ -939,7 +948,15 @@ function add_page_info_data($data) {
function add_page_info($url, $no_photos = false, $photo = "", $keywords = false, $keyword_blacklist = "") {
require_once("mod/parse_url.php");
$data = parseurl_getsiteinfo($url, true);
$data = Cache::get("parse_url:".$url);
if (is_null($data)){
$data = parseurl_getsiteinfo($url, true);
Cache::set("parse_url:".$url,serialize($data));
} else
$data = unserialize($data);
if ($photo != "")
$data["images"][0]["src"] = $photo;
logger('add_page_info: fetch page info for '.$url.' '.print_r($data, true), LOGGER_DEBUG);
@ -1027,7 +1044,7 @@ function encode_rel_links($links) {
function item_store($arr,$force_parent = false, $notify = false) {
function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) {
// If it is a posting where users should get notifications, then define it as wall posting
if ($notify) {
@ -1452,7 +1469,7 @@ function item_store($arr,$force_parent = false, $notify = false) {
// current post can be deleted if is for a communuty page and no mention are
// in it.
if (!$deleted) {
if (!$deleted AND !$dontcache) {
// Store the fresh generated item into the cache
$cachefile = get_cachefile(urlencode($arr["guid"])."-".hash("md5", $arr['body']));
@ -1474,7 +1491,7 @@ function item_store($arr,$force_parent = false, $notify = false) {
}
}
create_tags_from_item($current_post);
create_tags_from_item($current_post, $dontcache);
create_files_from_item($current_post);
if ($notify)

View file

@ -78,6 +78,11 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
if (!is_object($j))
return false;
// Always embed the SSL version
if (isset($j->html))
$j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html);
$j->embedurl = $embedurl;
// If fetching information doesn't work, then improve via internal functions

View file

@ -15,7 +15,7 @@ function onepoll_run(&$argv, &$argc){
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
@ -57,28 +57,30 @@ function onepoll_run(&$argv, &$argc){
return;
}
// Test
$lockpath = get_lockpath();
if ($lockpath != '') {
$pidfile = new pidfile($lockpath, 'onepoll'.$contact_id);
if($pidfile->is_already_running()) {
if ($pidfile->is_already_running()) {
logger("onepoll: Already running for contact ".$contact_id);
if ($pidfile->running_time() > 9*60) {
$pidfile->kill();
logger("killed stale process");
}
exit;
}
}
$d = datetime_convert();
// 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.
$contacts = q("SELECT `contact`.* FROM `contact`
$contacts = q("SELECT `contact`.* FROM `contact`
WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
AND NOT `network` IN ( '%s', '%s', '%s' )
AND `contact`.`id` = %d
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0 LIMIT 1",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),

View file

@ -240,14 +240,14 @@ function poller_run(&$argv, &$argc){
// 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'.
// changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'.
if($contact['subhub']) {
$poll_interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
$hub_update = false;
if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force)
$hub_update = true;
}
@ -256,13 +256,13 @@ function poller_run(&$argv, &$argc){
/**
* Based on $contact['priority'], should we poll this site now? Or later?
*/
*/
switch ($contact['priority']) {
case 5:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
$update = true;
break;
break;
case 4:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
$update = true;
@ -285,7 +285,13 @@ function poller_run(&$argv, &$argc){
continue;
}
proc_run('php','include/onepoll.php',$contact['id']);
// 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']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}

22
include/shadowupdate.php Normal file
View file

@ -0,0 +1,22 @@
<?php
require_once("boot.php");
require_once("include/threads.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_shadow_copy();
killme();
?>

View file

@ -1,5 +1,5 @@
<?php
function create_tags_from_item($itemid) {
function create_tags_from_item($itemid, $dontcache = false) {
global $a;
$profile_base = $a->get_baseurl();
@ -26,14 +26,16 @@ function create_tags_from_item($itemid) {
if ($message["deleted"])
return;
$cachefile = get_cachefile(urlencode($message["guid"])."-".hash("md5", $message['body']));
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);
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"]);

View file

@ -1,5 +1,5 @@
<?php
function add_thread($itemid) {
function add_thread($itemid, $onlyshadow = false) {
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`,
`deleted`, `origin`, `forum_mode`, `mention`, `network` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
@ -9,13 +9,71 @@ function add_thread($itemid) {
$item = $items[0];
$item['iid'] = $itemid;
$result = dbq("INSERT INTO `thread` (`"
.implode("`, `", array_keys($item))
."`) VALUES ('"
.implode("', '", array_values($item))
."')" );
if (!$onlyshadow) {
$result = dbq("INSERT INTO `thread` (`"
.implode("`, `", array_keys($item))
."`) VALUES ('"
.implode("', '", array_values($item))
."')");
logger("add_thread: Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
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;
// Is it a visible public post?
if (!$item["visible"] OR $item["deleted"] OR $item["moderated"] OR $item["private"])
return;
// is it an entry from a connector? Only add an entry for natively connected networks
if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
return;
// Only do these checks if the post isn't a wall post
if (!$item["wall"]) {
// Check, if hide-friends is activated - then don't do a shadow entry
$r = q("SELECT `hide-friends` FROM `profile` WHERE `is-default` AND `uid` = %d AND NOT `hide-friends`",
$item['uid']);
if (!count($r))
return;
// Check if the contact is hidden or blocked
$r = q("SELECT `id` FROM `contact` WHERE NOT `hidden` AND NOT `blocked` AND `id` = %d",
$item['contact-id']);
if (!count($r))
return;
}
// Only add a shadow, if the profile isn't hidden
$r = q("SELECT `uid` FROM `user` where `uid` = %d AND NOT `hidewall`", $item['uid']);
if (!count($r))
return;
$item = q("SELECT * FROM `item` WHERE `id` = %d",
intval($itemid));
if (count($item) AND ($item[0]["allow_cid"] == '') AND ($item[0]["allow_gid"] == '') AND
($item[0]["deny_cid"] == '') AND ($item[0]["deny_gid"] == '')) {
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1",
dbesc($item['uri']));
if (!$r) {
// Preparing public shadow (removing user specific data)
require_once("include/items.php");
unset($item[0]['id']);
$item[0]['uid'] = 0;
$item[0]['contact-id'] = 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);
}
}
}
function update_thread_uri($itemuri, $uid) {
@ -27,7 +85,7 @@ function update_thread_uri($itemuri, $uid) {
}
function update_thread($itemid, $setmention = false) {
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`,
$items = q("SELECT `uid`, `uri`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`,
`deleted`, `origin`, `forum_mode`, `network` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
if (!$items)
@ -40,16 +98,50 @@ function update_thread($itemid, $setmention = false) {
$sql = "";
foreach ($item AS $field => $data) {
if ($sql != "")
$sql .= ", ";
foreach ($item AS $field => $data)
if ($field != "uri") {
if ($sql != "")
$sql .= ", ";
$sql .= "`".$field."` = '".$data."'";
}
$sql .= "`".$field."` = '".dbesc($data)."'";
}
$result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", $itemid);
$result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
logger("update_thread: Update thread for item ".$itemid." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
// Updating a shadow item entry
$items = q("SELECT `id`, `title`, `body`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
`moderated`, `visible`, `spam`, `starred`, `bookmark`, `deleted`, `origin`, `forum_mode`, `network`
FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item["uri"]));
if (!$items)
return;
$item = $items[0];
$result = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `network` = '%s' WHERE `id` = %d",
dbesc($item["title"]),
dbesc($item["body"]),
dbesc($item["network"]),
intval($item["id"])
);
logger("update_thread: Updating public shadow for post ".$item["id"]." Result: ".print_r($result, true), LOGGER_DEBUG);
/*
$sql = "";
foreach ($item AS $field => $data)
if ($field != "id") {
if ($sql != "")
$sql .= ", ";
$sql .= "`".$field."` = '".dbesc($data)."'";
}
//logger("update_thread: Updating public shadow for post ".$item["id"]." SQL: ".$sql, LOGGER_DEBUG);
$result = q("UPDATE `item` SET ".$sql." WHERE `id` = %d", intval($item["id"]));
logger("update_thread: Updating public shadow for post ".$item["id"]." Result: ".print_r($result, true), LOGGER_DEBUG);
*/
}
function delete_thread_uri($itemuri, $uid) {
@ -61,13 +153,28 @@ function delete_thread_uri($itemuri, $uid) {
}
function delete_thread($itemid) {
$item = q("SELECT `uri`, `uid` FROM `thread` WHERE `iid` = %d", intval($itemid));
$result = q("DELETE FROM `thread` WHERE `iid` = %d", intval($itemid));
logger("delete_thread: Deleted thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
if (count($item)) {
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND NOT (`uid` IN (%d, 0))",
dbesc($item["uri"]),
intval($item["uid"])
);
if (!count($r)) {
$r = q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = 0)",
dbesc($item["uri"])
);
logger("delete_thread: Deleted shadow for item ".$item["uri"]." - ".print_r($result, true), LOGGER_DEBUG);
}
}
}
function update_threads() {
global $db;
global $db;
logger("update_threads: start");
@ -96,4 +203,21 @@ function update_threads_mention() {
q("UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d", $parent["parent"]);
}
}
function update_shadow_copy() {
global $db;
logger("start");
$messages = $db->q(sprintf("SELECT `iid` FROM `thread` WHERE `uid` != 0 AND `network` IN ('', '%s', '%s', '%s')
AND `visible` AND NOT `deleted` AND NOT `moderated` AND NOT `private` ORDER BY `created`",
NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS), true);
logger("fetched messages: ".count($messages));
while ($message = $db->qfetch())
add_thread($message["iid"], true);
$db->qclose();
}
?>

View file

@ -114,6 +114,10 @@ function community_content(&$a, $update = 0) {
}
function community_getitems($start, $itemspage) {
// Work in progress
if (get_config('system', 'global_community'))
return(community_getpublicitems($start, $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`,
@ -136,3 +140,19 @@ function community_getitems($start, $itemspage) {
return($r);
}
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
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
ORDER BY `item`.`received` DESC LIMIT %d, %d",
intval($start),
intval($itemspage)
);
return($r);
}

View file

@ -9,17 +9,18 @@ function oembed_content(&$a){
echo oembed_replacecb($url);
killme();
}
if ($a->argv[1]=='h2b'){
$text = trim(hex2bin($_REQUEST['text']));
echo oembed_html2bbcode($text);
killme();
}
if ($a->argc == 2){
echo "<html><body>";
$url = base64url_decode($a->argv[1]);
$j = oembed_fetch_url($url);
echo $j->html;
// logger('mod-oembed ' . $j->html, LOGGER_ALL);
echo "</body></html>";

View file

@ -1183,8 +1183,6 @@ function photos_content(&$a) {
intval($a->pager['itemspage'])
);
$o .= '<h3 id="photo-album-title">' . $album . '</h3>';
if($cmd === 'edit') {
if(($album !== t('Profile Photos')) && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
if($can_post) {
@ -1211,25 +1209,18 @@ function photos_content(&$a) {
else {
if(($album !== t('Profile Photos')) && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
if($can_post) {
$o .= '<div id="album-edit-link"><a href="'. $a->get_baseurl() . '/photos/'
. $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">'
. t('Edit Album') . '</a></div>';
$edit = array(t('Edit Album'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit');
}
}
}
if($_GET['order'] === 'posted')
$o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '" >' . t('Show Newest First') . '</a></div>';
$order = array(t('Show Newest First'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album));
else
$o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '?f=&order=posted" >' . t('Show Oldest First') . '</a></div>';
$order = array(t('Show Oldest First'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '?f=&order=posted');
$photos = array();
if($can_post) {
$o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>';
}
$tpl = get_markup_template('photo_album.tpl');
if(count($r))
$twist = 'rotright';
foreach($r as $rr) {
@ -1248,20 +1239,31 @@ function photos_content(&$a) {
$imgalt_e = $rr['filename'];
$desc_e = $rr['desc'];
}
$o .= replace_macros($tpl,array(
'$id' => $rr['id'],
'$twist' => ' ' . $twist . rand(2,4),
'$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id']
$photos[] = array(
'id' => $rr['id'],
'twist' => ' ' . $twist . rand(2,4),
'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id']
. (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''),
'$phototitle' => t('View Photo'),
'$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' .$ext,
'$imgalt' => $imgalt_e,
'$desc'=> $desc_e
));
'title' => t('View Photo'),
'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' .$ext,
'alt' => $imgalt_e,
'desc'=> $desc_e,
'ext' => $ext,
'hash'=> $rr['resource_id'],
);
}
$o .= '<div id="photo-album-end"></div>';
$tpl = get_markup_template('photo_album.tpl');
$o .= replace_macros($tpl, array(
'$photos' => $photos,
'$album' => $album,
'$can_post' => $can_post,
'$upload' => array(t('Upload New Photos'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album)),
'$order' => $order,
'$edit' => $edit
));
$o .= paginate($a);
return $o;

View file

@ -1022,7 +1022,7 @@ function settings_content(&$a) {
));
$hide_wall = replace_macros($opt_tpl,array(
'$field' => array('hidewall', t('Hide your profile details from unknown viewers?'), $a->user['hidewall'], '', array(t('No'),t('Yes'))),
'$field' => array('hidewall', t('Hide your profile details from unknown viewers?'), $a->user['hidewall'], t("If enabled, posting public messages to Diaspora and other networks isn't possible."), array(t('No'),t('Yes'))),
));

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

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,19 @@
<h3 id="photo-album-title">{{$album}}</h3>
{{if $edit}}
<div id="album-edit-link"><a href="{{$edit.1}}" title="{{$edit.0}}">{{$edit.0}}</a></div>
{{/if}}
<div class="photos-upload-link" ><a href="{{$order.1}}" title="{{$order.0}}">{{$order.0}}</a></div>
{{if $can_post}}
<div class="photos-upload-link" ><a href="{{$upload.1}}">{{$upload.0}}</a></div>
{{/if}}
{{foreach $photos as $photo}}
<div class="photo-album-image-wrapper" id="photo-album-image-wrapper-{{$id}}">
<a href="{{$photolink}}" class="photo-album-photo-link" id="photo-album-photo-link-{{$id}}" title="{{$phototitle}}">
<img src="{{$imgsrc}}" alt="{{$imgalt}}" title="{{$phototitle}}" class="photo-album-photo lframe resize{{$twist}}" id="photo-album-photo-{{$id}}" />
<p class='caption'>{{$desc}}</p>
<a href="{{$photo.link}}" class="photo-album-photo-link" id="photo-album-photo-link-{{$id}}" title="{{$photo.title}}">
<img src="{{$photo.src}}" alt="{{if $photo.album.name}}{{$photo.album.name}}{{elseif $photo.desc}}{{$photo.desc}}{{elseif $photo.alt}}{{$photo.alt}}{{else}}{{$photo.unknown}}{{/if}}" title="{{$photo.title}}" class="photo-album-photo lframe resize{{$twist}}" id="photo-album-photo-{{$id}}" />
<p class='caption'>{{$photo.desc}}</p>
</a>
</div>
<div class="photo-album-image-wrapper-end"></div>
{{/foreach}}

View file

@ -1,39 +1,39 @@
<div class="vcard">
<div class="vcard h-card">
<div class="fn label">{{$profile.name}}</div>
<div class="fn label p-name">{{$profile.name}}</div>
{{if $pdesc}}<div class="title">{{$profile.pdesc}}</div>{{/if}}
{{if $profile.picdate}}
<div id="profile-photo-wrapper"><img class="photo" width="175" height="175" src="{{$profile.photo}}?rev={{$profile.picdate}}" alt="{{$profile.name}}"></div>
<div id="profile-photo-wrapper"><img class="photo u-photo" width="175" height="175" src="{{$profile.photo}}?rev={{$profile.picdate}}" alt="{{$profile.name}}"></div>
{{else}}
<div id="profile-photo-wrapper"><img class="photo" width="175" height="175" src="{{$profile.photo}}" alt="{{$profile.name}}"></div>
<div id="profile-photo-wrapper"><img class="photo u-photo" width="175" height="175" src="{{$profile.photo}}" alt="{{$profile.name}}"></div>
{{/if}}
{{if $profile.network_name}}<dl class="network"><dt class="network-label">{{$network}}</dt><dd class="x-network">{{$profile.network_name}}</dd></dl>{{/if}}
{{if $location}}
<dl class="location"><dt class="location-label">{{$location}}</dt>
<dd class="adr">
{{if $profile.address}}<div class="street-address">{{$profile.address}}</div>{{/if}}
{{if $profile.address}}<div class="street-address p-street-address">{{$profile.address}}</div>{{/if}}
<span class="city-state-zip">
<span class="locality">{{$profile.locality}}</span>{{if $profile.locality}}, {{/if}}
<span class="region">{{$profile.region}}</span>
<span class="postal-code">{{$profile.postal_code}}</span>
<span class="locality p-locality">{{$profile.locality}}</span>{{if $profile.locality}}, {{/if}}
<span class="region p-region">{{$profile.region}}</span>
<span class="postal-code p-postal-code">{{$profile.postal_code}}</span>
</span>
{{if $profile.country_name}}<span class="country-name">{{$profile.country_name}}</span>{{/if}}
{{if $profile.country_name}}<span class="country-name p-country-name">{{$profile.country_name}}</span>{{/if}}
</dd>
</dl>
{{/if}}
{{if $gender}}<dl class="mf"><dt class="gender-label">{{$gender}}</dt> <dd class="x-gender">{{$profile.gender}}</dd></dl>{{/if}}
{{if $gender}}<dl class="mf"><dt class="gender-label">{{$gender}}</dt> <dd class="x-gender p-gender-identity">{{$profile.gender}}</dd></dl>{{/if}}
{{if $profile.pubkey}}<div class="key" style="display:none;">{{$profile.pubkey}}</div>{{/if}}
{{if $profile.pubkey}}<div class="key u-key" style="display:none;">{{$profile.pubkey}}</div>{{/if}}
{{if $marital}}<dl class="marital"><dt class="marital-label"><span class="heart">&hearts;</span>{{$marital}}</dt><dd class="marital-text">{{$profile.marital}}</dd></dl>{{/if}}
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url"><a href="{{$profile.homepage}}" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url u-url"><a href="{{$profile.homepage}}" rel="me" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
{{include file="diaspora_vcard.tpl"}}

View file

@ -45,7 +45,8 @@ function vier_form(&$a, $style){
"flat"=>"Flat",
"netcolour"=>"Coloured Networks",
"breathe"=>"Breathe",
"plus"=>"Plus"
"plus"=>"Plus",
"dark"=>"Dark"
);
$t = get_markup_template("theme_settings.tpl" );
$o .= replace_macros($t, array(

61
view/theme/vier/dark.css Normal file
View file

@ -0,0 +1,61 @@
*{
box-shadow: 0 0 0 0 !important;
border-color: #343434 !important;
}
hr { background-color: #343434 !important; }
a, .wall-item-name, .fakelink {
color: #989898 !important;
}
nav {
color: #989898 !important;
background-color: #1C2126 !important;
}
nav .nav-notify {
background-color: #2C77AE !important
}
a.on {
color: #FFFFFF !important;
background-color: #2C77AE !important
}
aside, .menu-popup, .fc-state-highlight, a.off, .autocomplete {
color: #989898 !important;
background-color: #252C33 !important;
border-right: 1px solid #D2D2D2;
}
body, section, blockquote, blockquote.shared_content, #profile-jot-form,
.dspr, .twit, .pump, .dfrn, .tread-wrapper, code, .mail-list-wrapper, div.pager, ul.tabs {
color: #989898 !important;
background-color: #171B1F !important;
}
div.rte, .mceContentBody {
background:none repeat scroll 0 0 #333333!important;
color:#FFF!important;
text-align:left;
}
div.pager, ul.tabs {
box-shadow: unset;
border-bottom: unset;
}
input, option, textarea, select {
color: #989898 !important;
border: 2px solid #0C1116 !important;
background-color: #0C1116 !important;
}
input#side-peoplefind-submit, input#side-follow-submit {
margin-top: 2px !important;
}
li :hover {
color: #767676 !important;
}

View file

@ -1,4 +1,11 @@
*{ box-shadow: 0 0 0 0 !important;}
*{
box-shadow: 0 0 0 0 !important;
border-color: #EAEAEA !important;
}
nav { background-color: #27333F !important; }
aside { background-color: #EAEEF4 !important }
body, section { background-color: #ffffff !important;}
#profile-jot-form { background-color: #ffffff !important;}
.dspr, .twit, .pump, .dfrn { background-color: #ffffff !important;}
@ -11,4 +18,4 @@ div.pager, ul.tabs {
aside {
border-right: 1px solid #D2D2D2;
}
}

View file

@ -1,15 +1,15 @@
<div class="vcard">
<div class="vcard h-card">
<div class="tool">
<div class="fn label">{{$profile.name}}</div>
<div class="fn label p-name">{{$profile.name}}</div>
{{if $profile.edit}}
<div class="action">
<a class="icon s16 edit ttright" href="#" rel="#profiles-menu" title="{{$profile.edit.3}}"><span>{{$profile.edit.1}}</span></a>
<ul id="profiles-menu" class="menu-popup">
{{foreach $profile.menu.entries as $e}}
<li>
<a href="profiles/{{$e.id}}"><img src='{{$e.photo}}'>{{$e.profile_name}}</a>
<a href="profiles/{{$e.id}}"><img class="u-photo" src='{{$e.photo}}'>{{$e.profile_name}}</a>
</li>
{{/foreach}}
<li><a href="profile_photo" >{{$profile.menu.chg_photo}}</a></li>
@ -36,11 +36,11 @@
{{if $location}}
<dl class="location"><dt class="location-label">{{$location}}</dt><br>
<dd class="adr">
{{if $profile.address}}<div class="street-address">{{$profile.address}}</div>{{/if}}
{{if $profile.address}}<div class="street-address p-street-address">{{$profile.address}}</div>{{/if}}
<span class="city-state-zip">
<span class="locality">{{$profile.locality}}</span>{{if $profile.locality}}, {{/if}}
<span class="region">{{$profile.region}}</span>
<span class="postal-code">{{$profile.postal_code}}</span>
<span class="locality p-locality">{{$profile.locality}}</span>{{if $profile.locality}}, {{/if}}
<span class="region p-region">{{$profile.region}}</span>
<span class="postal-code p-postal-code">{{$profile.postal_code}}</span>
</span>
{{if $profile.country_name}}<span class="country-name">{{$profile.country_name}}</span>{{/if}}
</dd>
@ -53,7 +53,7 @@
{{if $marital}}<dl class="marital"><dt class="marital-label"><span class="heart">&hearts;</span>{{$marital}}</dt><dd class="marital-text">{{$profile.marital}}</dd></dl>{{/if}}
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url"><a href="{{$profile.homepage}}" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
{{if $homepage}}<dl class="homepage"><dt class="homepage-label">{{$homepage}}</dt><dd class="homepage-url"><a href="{{$profile.homepage}}" class="u-url" rel="me" target="_blank">{{$profile.homepage}}</a></dd></dl>{{/if}}
{{include file="diaspora_vcard.tpl"}}

View file

@ -22,6 +22,8 @@ if ($style == "")
if ($style == "flat")
$a->page['htmlhead'] .= '<link rel="stylesheet" href="view/theme/vier/flat.css" type="text/css" media="screen"/>'."\n";
if ($style == "dark")
$a->page['htmlhead'] .= '<link rel="stylesheet" href="view/theme/vier/dark.css" type="text/css" media="screen"/>'."\n";
else if ($style == "netcolour")
$a->page['htmlhead'] .= '<link rel="stylesheet" href="view/theme/vier/netcolour.css" type="text/css" media="screen"/>'."\n";
else if ($style == "breathe")