Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Haakon Meland Eriksen 2016-03-04 06:05:47 +01:00
commit 059da4d017
21 changed files with 334 additions and 64 deletions

View File

@ -1,3 +1,46 @@
Hubzilla 1.3
Admin Security configuration page created which consolidates several previously hidden settings:
Communication white/black lists
Channel white/black lists
OEmbed white/black lists
Admin Profile Fields page created which manages the availability and order of standard profile fields and allows new fields to be created/managed
"Poke" module reworked - page UI updated and "poke basic" setting introduced which limits the available poke "verbs".
"Mood" module UI reworked
"profile_photo" module UI reworked
"cover_photo" module UI reworked
"new_channel" module UI reworked
"register" module UI reworked
"pubsites" module UI reworked
item-meta ("iconfig") created which implements arbitrary storage for item metadata for plugins
abook-meta ("abconfig") created which implements arbitrary storage for connection metadata for plugins
"Strict transport security header" made optional as it conflicts with some existing Apache/nginx configurations
"Hubzilla UNO" (Hubzilla with radically simplified and locked site settings) implemented as an install configuration.
.well-known directory conflict worked out to support LetsEncrypt cert ownership checks without disrupting webfinger and other internal uses of .well-known
Lots of work on 'zcards' which are self-contained HTML representations of a channel including cover photos, profile photos, and some text information
Long standing bug uncovered which failed to properly restrict the lower time limit for public feed requests
A number of fixes to "readmore" to fix page jumping
Bugfix: persons other than the channel owner who have permission to upload photos to a channel could not do so if the js_upload plugin/addon was enabled
Siteinfo incorrectly identifying secondary directory servers
Allow admin to set and lock features when UNO is configured
Atom feeds: alter how events are formatted to be compatible with GNU-social
Allow guest/visitor access to view personal calendar
Moved several more classes to "composer format" and provided an autoloader.
Bugfix: require existing password to change password
Bugfix: allow relative_date() to be translated to Polish which has more than two plural forms.
Plugin API: add "requires" keyword to module header to indicate dependent addons
ActivityStreams improvements and cleanup: photo and file activities
UI cleanup for editing profile when multiple profiles enabled
Removed the "markdown" feature as there are numerous issues and no maintainer.
Provide "footer" bbcode to ease theming of post footer content
Bugfix: install issues caused by composer code refactor and typo in postgres load file
Plugins:
keepout - "block public on steroids"
pubsubhubbub - provides PuSH support to Atom feeds, required for GNU-social federation
GNUsocial protocol - under development
Diaspora protocol - some work to ease migration to the new signing format
Diaspost - disabled; numerous issues and no maintainer
smileybutton - theme work and fixed compatibility with other jot-tools plugins
Hubzilla 1.2
Provide extra HTTP security headers (several of them).

View File

@ -32,8 +32,6 @@ We need much more than this, but here are areas where developers can help. Pleas
[li]API extensions, for Twitter API - search, friending, threading. For Red API, lots of stuff[/li]
[li]Import channel from Diaspora/Friendica (Diaspora partially done)[/li]
[li]MediaGoblin photo "crosspost" connector[/li]
[li]Create management page/UI for extensible profile fields[/li]
[li]Create interface to include/exclude and re-order standard profile fields[/li]
[li]App taxonomy[/li]
[li]Customisable App collection pages[/li]
[li]replace the tinymce visual editor and/or make the visual editor pluggable and responsive to different output formats. We probably want library/bbedit for bbcode. This needs a fair bit of work to catch up with our "enhanced bbcode", but start with images, links, bold and highlight and work from there.[/li]

View File

@ -66,7 +66,7 @@ function get_features($filtered = true) {
'composition' => array(
t('Post Composition Features'),
// array('richtext', t('Richtext Editor'), t('Enable richtext editor'),falseget_config('feature_lock','richtext')),
array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false,get_config('feature_lock','markdown')),
// array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false,get_config('feature_lock','markdown')),
array('large_photos', t('Large Photos'), t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),false,get_config('feature_lock','large_photos')),
array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'),false,get_config('feature_lock','channel_sources')),
array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'),false,get_config('feature_lock','content_encrypt')),

View File

@ -68,7 +68,6 @@ require_once('include/html2plain.php');
require_once('include/cli_startup.php');
require_once('include/zot.php');
require_once('include/queue_fn.php');
require_once('include/session.php');
require_once('include/datetime.php');
require_once('include/items.php');
require_once('include/bbcode.php');

View File

@ -11,7 +11,6 @@ function ratenotif_run($argv, $argc){
$a = get_app();
require_once("session.php");
require_once("datetime.php");
require_once('include/items.php');
require_once('include/Contact.php');

View File

@ -982,28 +982,48 @@ function widget_cover_photo($arr) {
require_once('include/identity.php');
$o = '';
$a = get_app();
$channel_id = 0;
if(array_key_exists('channel_id', $arr) && intval($arr['channel_id']))
$channel_id = intval($arr['channel_id']);
if(! $channel_id)
$channel_id = get_app()->profile_uid;
$channel_id = $a->profile_uid;
if(! $channel_id)
return '';
$channel = channelx_by_n($channel_id);
if(array_key_exists('style', $arr) && isset($arr['style']))
$style = $arr['style'];
else
$style = 'width:100%; padding-right: 10px; height: auto;';
$style = 'width:100%; height: auto;';
// ensure they can't sneak in an eval(js) function
if(strpbrk($style,'(\'"<>') !== false)
$style = '';
if(array_key_exists('title', $arr) && isset($arr['title']))
$title = $arr['title'];
else
$title = $channel['channel_name'];
if(array_key_exists('subtitle', $arr) && isset($arr['subtitle']))
$subtitle = $arr['subtitle'];
else
$subtitle = $channel['xchan_addr'];
$c = get_cover_photo($channel_id,'html');
if($c) {
$o = '<div class="widget">' . (($style) ? str_replace('alt=',' style="' . $style . '" alt=',$c) : $c) . '</div>';
$photo_html = (($style) ? str_replace('alt=',' style="' . $style . '" alt=',$c) : $c);
$o = replace_macros(get_markup_template('cover_photo_widget.tpl'),array(
'$photo_html' => $photo_html,
'$title' => $title,
'$subtitle' => $subtitle,
));
}
return $o;
}
@ -1297,7 +1317,7 @@ function widget_admin($arr) {
'plugins' => array(z_root() . '/admin/plugins/', t('Plugins'), 'plugins'),
'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'),
'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
'profs' => array(z_root() . '/admin/profs', t('Profile Config'), 'profs'),
'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'),
'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
);

View File

@ -1620,26 +1620,47 @@ readable.");
function admin_page_profs_post(&$a) {
if($_REQUEST['id']) {
$r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs']),
intval($_REQUEST['id'])
);
if(array_key_exists('basic',$_REQUEST)) {
$arr = explode(',',$_REQUEST['basic']);
for($x = 0; $x < count($arr); $x ++)
if(trim($arr[$x]))
$arr[$x] = trim($arr[$x]);
set_config('system','profile_fields_basic',$arr);
if(array_key_exists('advanced',$_REQUEST)) {
$arr = explode(',',$_REQUEST['advanced']);
for($x = 0; $x < count($arr); $x ++)
if(trim($arr[$x]))
$arr[$x] = trim($arr[$x]);
set_config('system','profile_fields_advanced',$arr);
}
goaway(z_root() . '/admin/profs');
}
else {
$r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs'])
);
if(array_key_exists('field_name',$_REQUEST)) {
if($_REQUEST['id']) {
$r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs']),
intval($_REQUEST['id'])
);
}
else {
$r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs'])
);
}
}
// add to chosen array basic or advanced
goaway(z_root() . '/admin/profs');
@ -1686,4 +1707,70 @@ function admin_page_profs(&$a) {
'$submit' => t('Save')
));
}
$basic = '';
$barr = array();
$fields = get_profile_fields_basic();
if(! $fields)
$fields = get_profile_fields_basic(1);
if($fields) {
foreach($fields as $k => $v) {
if($basic)
$basic .= ', ';
$basic .= trim($k);
$barr[] = trim($k);
}
}
$advanced = '';
$fields = get_profile_fields_advanced();
if(! $fields)
$fields = get_profile_fields_advanced(1);
if($fields) {
foreach($fields as $k => $v) {
if(in_array(trim($k),$barr))
continue;
if($advanced)
$advanced .= ', ';
$advanced .= trim($k);
}
}
$all = '';
$fields = get_profile_fields_advanced(1);
if($fields) {
foreach($fields as $k => $v) {
if($all)
$all .= ', ';
$all .= trim($k);
}
}
$r = q("select * from profdef where true");
if($r) {
foreach($r as $rr) {
if($all)
$all .= ', ';
$all .= $rr['field_name'];
}
}
$o = replace_macros(get_markup_template('admin_profiles.tpl'),array(
'$title' => t('Profile Fields'),
'$basic' => array('basic',t('Basic Profile Fields'),$basic,''),
'$advanced' => array('advanced',t('Advanced Profile Fields'),$advanced,t('(In addition to basic fields)')),
'$all' => $all,
'$all_desc' => t('All available fields'),
'$cust_field_desc' => t('Custom Fields'),
'$cust_fields' => $r,
'$edit' => t('Edit'),
'$drop' => t('Delete'),
'$new' => t('Create Custom Field'),
'$submit' => t('Submit')
));
return $o;
}

View File

@ -477,15 +477,28 @@ function item_post(&$a) {
if($mimetype === 'text/bbcode') {
require_once('include/text.php');
if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
require_once('include/bb2diaspora.php');
$body = escape_tags(trim($body));
$body = str_replace("\n",'<br />', $body);
$body = preg_replace_callback('/\[share(.*?)\]/ism','share_shield',$body);
$body = diaspora2bb($body,true);
$body = preg_replace_callback('/\[share(.*?)\]/ism','share_unshield',$body);
}
// Markdown doesn't work correctly. Do not re-enable unless you're willing to fix it and support it.
// Sample that will probably give you grief - you must preserve the linebreaks
// and provide the correct markdown interpretation and you cannot allow unfiltered HTML
// Markdown
// ========
//
// **bold** abcde
// fghijkl
// *italic*
// <img src="javascript:alert('hacked');" />
// if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
// require_once('include/bb2diaspora.php');
// $body = escape_tags(trim($body));
// $body = str_replace("\n",'<br />', $body);
// $body = preg_replace_callback('/\[share(.*?)\]/ism','share_shield',$body);
// $body = diaspora2bb($body,true);
// $body = preg_replace_callback('/\[share(.*?)\]/ism','share_unshield',$body);
// }
// BBCODE alert: the following functions assume bbcode input
// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)

View File

@ -1 +1 @@
2016-03-01.1323H
2016-03-03.1325H

View File

@ -17,24 +17,12 @@ main {
aside {
display: table-cell;
vertical-align: top;
padding: 80px 7px 0px 7px;
padding: 71px 7px 0px 7px;
}
section {
width: 100%;
display: table-cell;
vertical-align: top;
padding: 80px 7px 200px 7px;
}
@media screen and (max-width: 767px) {
section {
padding: 65px 7px 200px 7px;
}
aside#region_1 {
padding: 65px 7px 0px 7px;
}
padding: 71px 7px 200px 7px;
}

View File

@ -122,3 +122,30 @@ li:hover .group-edit-icon {
#event-upload-choose {
width: 100%;
}
/* cover photo */
#cover-photo {
position: relative;
width: 100%;
height: auto;
}
#cover-photo-caption {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
padding: 15px;
color: #fff;
font-weight: bold;
text-shadow: 1px 1px 3px rgba(0,0,0,.7);
}
.cover-photo-title {
font-size: 30px;
}
.cover-photo-subtitle {
font-size: 20px;
}

View File

@ -1,4 +1,4 @@
s met dit e-mailadres een account aangemaakt op {{$sitename}}.
Er is met dit e-mailadres een account aangemaakt op {{$sitename}}.
De inloggegevens zijn als volgt:
Hub: {{$siteurl}}

View File

@ -1,3 +1,6 @@
[region=banner]
[widget=cover_photo][/widget]
[/region]
[region=aside]
[widget=fullprofile][/widget]
[widget=archive][var=wall]1[/var][/widget]

View File

@ -6,6 +6,7 @@
<?php if(x($page,'htmlhead')) echo $page['htmlhead'] ?>
</head>
<body>
<?php if(x($page,'banner')) echo $page['banner']; ?>
<header><?php if(x($page,'header')) echo $page['header']; ?></header>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"><?php if(x($page,'nav')) echo $page['nav']; ?></nav>
<main>

View File

@ -174,6 +174,7 @@ header #banner {
z-index: 1040;
margin-top: 14px;
text-align: center;
text-shadow: 1px 1px 2px rgba(0,0,0,.5);
font-size: 14px;
font-family: tahoma, "Lucida Sans", sans;
color: $banner_colour;

View File

@ -2,6 +2,7 @@
* redbasic theme specific JavaScript
*/
$(document).ready(function() {
// CSS3 calc() fallback (for unsupported browsers)
$('body').append('<div id="css3-calc" style="width: 10px; width: calc(10px + 10px); display: none;"></div>');
if( $('#css3-calc').width() == 10) {
@ -38,9 +39,7 @@ $(document).ready(function() {
$("input[data-role=cat-tagsinput]").tagsinput({
tagClass: 'label label-primary'
});
});
$(document).ready(function(){
var doctitle = document.title;
function checkNotify() {
var notifyUpdateElem = document.getElementById('notify-update');

View File

@ -21,6 +21,7 @@
<li><a href='{{$admin.plugins.0}}'>{{$admin.plugins.1}}</a></li>
<li><a href='{{$admin.themes.0}}'>{{$admin.themes.1}}</a></li>
<li><a href='{{$admin.features.0}}'>{{$admin.features.1}}</a></li>
<li><a href='{{$admin.profs.0}}'>{{$admin.profs.1}}</a></li>
<li><a href='{{$admin.dbsync.0}}'>{{$admin.dbsync.1}}</a></li>
</ul>
</div>

View File

@ -0,0 +1,38 @@
<div class="generic-content-wrapper">
<div class="section-title-wrapper"><a title="{{$new}}" class="btn btn-primary btn-xs pull-right" href="admin/profs/new"><i class="icon-plus-sign">&nbsp;{{$new}}</i></a><h2>{{$title}}</h2>
<div class="clear"></div>
</div>
<div class="section-content-tools-wrapper">
<div class="section-content-info-wrapper">{{$all_desc}}
<br /><br />
{{$all}}
</div>
<form action="admin/profs" method="post">
{{include file="field_textarea.tpl" field=$basic}}
{{include file="field_textarea.tpl" field=$advanced}}
<input type="submit" name="submit" value="{{$submit}}" />
</form>
{{if $cust_fields}}
<br /><br />
<div><strong>{{$cust_field_desc}}</strong></div>
<br />
<table width="100%">
{{foreach $cust_fields as $field}}
<tr><td>{{$field.field_name}}</td><td>{{$field.field_desc}}</td><td><a class="btn btn-danger btn-xs" href="admin/profs/drop/{{$field.id}}" title="{{$drop}}"><i class="icon-trash"></i>&nbsp;{{$drop}}</a> <a class="btn btn-xs" title="{{$edit}}" href="admin/profs/{{$field.id}}" ><i class="icon-pencil"></i></a></td></tr>
{{/foreach}}
</table>
{{/if}}
</div>
</div>

53
view/tpl/cover_photo_widget.tpl Executable file
View File

@ -0,0 +1,53 @@
<script>
$(document).ready(function() {
if($('#cover-photo').length && $(window).width() > 755) {
$('.navbar-fixed-top').css('position', 'relative');
$('aside, section').css('padding-top', 0 + 'px');
$('main').css('opacity', 0);
$('header').hide();
}
else {
$('#cover-photo').remove();
}
});
$(window).scroll(function () {
if($('#cover-photo').length && $(window).width() > 755 && $(window).scrollTop() >= $('#cover-photo').height()) {
$('header').fadeIn();
$('main').css('opacity', 1);
$('aside, section').css('padding-top', 71 + 'px');
$(window).scrollTop($(window).scrollTop() - $('#cover-photo').height())
$('.navbar-fixed-top').css('position', 'fixed');
$('#cover-photo').remove();
}
if($('#cover-photo').length) {
$('main').css('opacity', ($(window).scrollTop()/$('#cover-photo').height()).toFixed(1));
}
});
$(window).resize(function () {
if($('#cover-photo').length && $(window).width() < 755) {
$('main').css('opacity', 1);
$('aside, section').css('padding-top', 71 + 'px');
$('.navbar-fixed-top').css('position', 'fixed');
$('#cover-photo').remove();
}
});
function slideUpCover() {
$('html, body').animate({scrollTop: $('#cover-photo').height() + 'px'});
}
</script>
<div id="cover-photo" onclick="slideUpCover();">
{{$photo_html}}
<div id="cover-photo-caption">
<div class="cover-photo-title">
{{$title}}
</div>
<div class="cover-photo-subtitle">
{{$subtitle}}
</div>
</div>
</div>

View File

@ -1,12 +1,12 @@
{{$mimeselect}}
{{$layoutselect}}
{{if $id_select}}
<div class="channel-id-select-div">
<span class="channel-id-select-desc">{{$id_seltext}}</span> {{$id_select}}
</div>
{{/if}}
<div id="profile-jot-wrapper">
<form id="profile-jot-form" action="{{$action}}" method="post">
<form id="profile-jot-form" action="{{$action}}" method="post">
{{$mimeselect}}
{{$layoutselect}}
{{if $id_select}}
<div class="channel-id-select-div">
<span class="channel-id-select-desc">{{$id_seltext}}</span> {{$id_select}}
</div>
{{/if}}
<div id="profile-jot-wrapper">
{{if $parent}}
<input type="hidden" name="parent" value="{{$parent}}" />
{{/if}}
@ -160,8 +160,8 @@
</div>
<div id="profile-jot-text-loading"></div>
<div id="profile-jot-end" class="clear"></div>
</form>
</div>
</div>
</form>
<div id="jot-preview-content" style="display:none;"></div>

View File

@ -72,7 +72,7 @@
{{if $profile.marital}}
<dl id="aprofile-marital" class="aprofile">
<dt><span class="heart">&hearts;</span> {{$profile.marital.0}}</dt>
<dd>{{$profile.marital.1}}{{if $profile.marital.with}} ({{$profile.marital.with}}){{/if}}{{if $profile.howlong}} {{$profile.howlong}}{{/if}}</dd>
<dd>{{$profile.marital.1}}{{if in_array('with',$fields)}}{{if $profile.marital.with}} ({{$profile.marital.with}}){{/if}}{{/if}}{{if in_array('howlong',$fields)}}{{if $profile.howlong}} {{$profile.howlong}}{{/if}}{{/if}}</dd>
</dl>
{{/if}}
{{/if}}