Merge remote-tracking branch 'upstream/master'

This commit is contained in:
zottel 2015-09-09 09:53:51 +02:00
commit 2417396a93
17 changed files with 362 additions and 62 deletions

View File

@ -1,6 +1,6 @@
Hubzilla
========
Hubzilla - Community Server
===========================
Websites. Redefined.
--------------------

View File

@ -45,7 +45,7 @@ We need much more than this, but here are areas where developers can help. Pleas
[li]Create mobile clients for the top platforms - which involves extending the API so that we can do stuff far beyond the current crop of Twitter/Statusnet clients. Ditto for mobile themes. We can probably use something like the Friendica Android app as a base to start from.[/li]
[li](in progress Habeas Codice) Implement owned and exchangeable "things".[/li]
[li]Family Account creation - using service classes (an account holder can create a certain number of sub-accounts which are all tied to their subscription - if the subscription lapses they all go away).[/li]
[li]Put mod_admin under Comanche[/li]
In many cases some of the work has already been started and code exists so that you needn't start from scratch. Please contact one of the developer channels like Channel One (one@zothub.com) before embarking and we can tell you what we already have and provide some insights on how we envision these features fitting together.

View File

@ -57,6 +57,10 @@ function import_diaspora($data) {
$channel_id = $c['channel']['channel_id'];
// Hubzilla only: Turn on the Diaspora protocol so that follow requests will be sent.
set_pconfig($channel_id,'system','diaspora_allowed','1');
// todo - add auto follow settings, (and strip exif in hubzilla)
$location = escape_tags($data['user']['profile']['location']);
@ -70,7 +74,6 @@ function import_diaspora($data) {
);
if($data['user']['profile']['nsfw']) {
// fixme for hubzilla which doesn't use pageflags any more
q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d",
intval(PAGE_ADULT),
intval($channel_id)

View File

@ -896,6 +896,55 @@ require_once('include/items.php');
api_register_func('api/red/item/new','red_item_new', true);
function red_item(&$a, $type) {
if (api_user() === false) {
logger('api_red_item_new: no user');
return false;
}
if($_REQUEST['mid']) {
$arr = array('mid' => $_REQUEST['mid']);
}
elseif($_REQUEST['item_id']) {
$arr = array('item_id' => $_REQUEST['item_id']);
}
else
json_return_and_die(array());
$arr['start'] = 0;
$arr['records'] = 999999;
$arr['item_type'] = '*';
$i = items_fetch($arr,$a->get_channel(),get_observer_hash());
if(! $i)
json_return_and_die(array());
$ret = array();
$tmp = array();
$str = '';
foreach($i as $ii) {
$tmp[] = encode_item($ii,true);
if($str)
$str .= ',';
$str .= $ii['id'];
}
$ret['item'] = $tmp;
if($str) {
$r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item.id in ( $str ) ");
if($r)
$ret['item_id'] = $r;
}
json_return_and_die($ret);
}
api_register_func('api/red/item/full','red_item', true);
function api_get_status($xchan_hash) {
require_once('include/security.php');

View File

@ -5,7 +5,7 @@
require_once('include/zot.php');
require_once('include/crypto.php');
require_once('include/menu.php');
/**
* @brief Called when creating a new channel.
@ -595,6 +595,26 @@ function identity_basic_export($channel_id, $items = false) {
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
for($y = 0; $y < count($x); $y ++) {
$m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']);
if($m)
$ret['menu'][] = menu_element($m);
}
}
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
for($y = 0; $y < count($x); $y ++) {
$m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']);
if($m)
$ret['menu'][] = menu_element($m);
}
}
if(! $items)

View File

@ -1,5 +1,6 @@
<?php
require_once('include/menu.php');
function import_channel($channel) {
@ -49,6 +50,11 @@ function import_channel($channel) {
unset($channel['channel_id']);
$channel['channel_account_id'] = get_account_id();
$channel['channel_primary'] = (($seize) ? 1 : 0);
if($channel['channel_pageflags'] & PAGE_ALLOWCODE) {
if(! is_site_admin())
$channel['channel_pageflags'] = $channel['channel_pageflags'] ^ PAGE_ALLOWCODE;
}
dbesc_array($channel);
@ -479,8 +485,19 @@ function sync_chatrooms($channel,$chatrooms) {
function import_items($channel,$items) {
if($channel && $items) {
$allow_code = false;
$r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
where channel_id = %d limit 1",
intval($channel['channel_id'])
);
if($r) {
if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
$allow_code = true;
}
}
foreach($items as $i) {
$item = get_item_elements($i);
$item = get_item_elements($i,$allow_code);
if(! $item)
continue;
@ -616,7 +633,132 @@ function sync_events($channel,$events) {
}
function import_menus($channel,$menus) {
if($channel && $menus) {
foreach($menus as $menu) {
$m = array();
$m['menu_channel_id'] = $channel['channel_id'];
$m['menu_name'] = $menu['pagetitle'];
$m['menu_desc'] = $menu['desc'];
if($menu['created'])
$m['menu_created'] = datetime_convert($menu['created']);
if($menu['edited'])
$m['menu_edited'] = datetime_convert($menu['edited']);
$m['menu_flags'] = 0;
if($menu['flags']) {
if(in_array('bookmark',$menu['flags']))
$m['menu_flags'] |= MENU_BOOKMARK;
if(in_array('system',$menu['flags']))
$m['menu_flags'] |= MENU_SYSTEM;
}
$menu_id = menu_create($m);
if($menu_id) {
if(is_array($menu['items'])) {
foreach($menu['items'] as $it) {
$mitem = array();
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
$mitem['mitem_desc'] = escape_tags($it['desc']);
$mitem['mitem_order'] = intval($it['order']);
if(is_array($it['flags'])) {
$mitem['mitem_flags'] = 0;
if(in_array('zid',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_ZID;
if(in_array('new-window',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_NEWWIN;
if(in_array('chatroom',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_CHATROOM;
}
menu_add_item($menu_id,$channel['channel_id'],$mitem);
}
}
}
}
}
}
function sync_menus($channel,$menus) {
if($channel && $menus) {
foreach($menus as $menu) {
$m = array();
$m['menu_channel_id'] = $channel['channel_id'];
$m['menu_name'] = $menu['pagetitle'];
$m['menu_desc'] = $menu['desc'];
if($menu['created'])
$m['menu_created'] = datetime_convert($menu['created']);
if($menu['edited'])
$m['menu_edited'] = datetime_convert($menu['edited']);
$m['menu_flags'] = 0;
if($menu['flags']) {
if(in_array('bookmark',$menu['flags']))
$m['menu_flags'] |= MENU_BOOKMARK;
if(in_array('system',$menu['flags']))
$m['menu_flags'] |= MENU_SYSTEM;
}
$editing = false;
$r = q("select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1",
dbesc($m['menu_name']),
intval($channel['channel_id'])
);
if($r) {
if($r[0]['menu_edited'] >= $m['menu_edited'])
continue;
if($menu['menu_deleted']) {
menu_delete_id($r[0]['menu_id'],$channel['channel_id']);
continue;
}
$menu_id = $r[0]['menu_id'];
$m['menu_id'] = $r[0]['menu_id'];
$x = menu_edit($m);
if(! $x)
continue;
$editing = true;
}
if(! $editing) {
$menu_id = menu_create($m);
}
if($menu_id) {
if($editing) {
// don't try syncing - just delete all the entries and start over
q("delete from menu_item where mitem_menu_id = %d",
intval($menu_id)
);
}
if(is_array($menu['items'])) {
foreach($menu['items'] as $it) {
$mitem = array();
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
$mitem['mitem_desc'] = escape_tags($it['desc']);
$mitem['mitem_order'] = intval($it['order']);
if(is_array($it['flags'])) {
$mitem['mitem_flags'] = 0;
if(in_array('zid',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_ZID;
if(in_array('new-window',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_NEWWIN;
if(in_array('chatroom',$it['flags']))
$mitem['mitem_flags'] |= MENU_ITEM_CHATROOM;
}
menu_add_item($menu_id,$channel['channel_id'],$mitem);
}
}
}
}
}
}

View File

@ -833,10 +833,13 @@ function title_is_body($title, $body) {
}
function get_item_elements($x) {
function get_item_elements($x,$allow_code = false) {
$arr = array();
$arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
if($allow_code)
$arr['body'] = $x['body'];
else
$arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
$key = get_config('system','pubkey');
@ -1309,7 +1312,7 @@ function encode_item($item,$mirror = false) {
$x['comment_scope'] = $c_scope;
if($item['term'])
$x['tags'] = encode_item_terms($item['term']);
$x['tags'] = encode_item_terms($item['term'],$mirror);
if($item['diaspora_meta']) {
$z = json_decode($item['diaspora_meta'],true);
@ -1401,11 +1404,16 @@ function encode_item_xchan($xchan) {
return $ret;
}
function encode_item_terms($terms) {
function encode_item_terms($terms,$mirror = false) {
$ret = array();
$allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK );
if($mirror) {
$allowed_export_terms[] = TERM_PCATEGORY;
$allowed_export_terms[] = TERM_FILE;
}
if($terms) {
foreach($terms as $term) {
if(in_array($term['type'],$allowed_export_terms))
@ -4726,6 +4734,12 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if($arr['wall'])
$sql_options .= " and item_wall = 1 ";
if($arr['item_id'])
$sql_options .= " and parent = " . intval($arr['item_id']) . " ";
if($arr['mid'])
$sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' ";
$sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options ) ";
@ -4852,11 +4866,15 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
require_once('include/security.php');
$sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash);
if($arr['pages'])
$item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " ";
else
$item_restrict = " AND item_type = 0 ";
if($arr['item_type'] === '*')
$item_restrict = '';
if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) {
// "New Item View" - show all items unthreaded in reverse created date order

View File

@ -6,7 +6,7 @@ require_once('include/bbcode.php');
function menu_fetch($name,$uid,$observer_xchan) {
$sql_options = permissions_sql($uid);
$sql_options = permissions_sql($uid,$observer_xchan);
$r = q("select * from menu where menu_channel_id = %d and menu_name = '%s' limit 1",
intval($uid),
@ -238,7 +238,6 @@ function menu_edit($arr) {
return false;
}
$r = q("select * from menu where menu_id = %d and menu_channel_id = %d limit 1",
intval($menu_id),
intval($menu_channel_id)
@ -388,3 +387,14 @@ function menu_del_item($menu_id,$uid,$item_id) {
return $r;
}
function menu_sync_packet($uid,$observer_hash,$menu_id,$delete = false) {
$r = menu_fetch_id($menu_id,$uid);
if($r) {
$m = menu_fetch($r['menu_name'],$uid,$observer_hash);
if($m) {
if($delete)
$m['menu_delete'] = 1;
build_sync_packet($uid,array('menu' => array(menu_element($m))));
}
}
}

View File

@ -1074,4 +1074,63 @@ function widget_helpindex($arr) {
$o .= '</ul></div>';
return $o;
}
function widget_admin($arr) {
/*
* Side bar links
*/
if(! is_site_admin()) {
return login(false);
}
$a = get_app();
$o = '';
// array( url, name, extra css classes )
$aside = array(
'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
'users' => array(z_root() . '/admin/users/', t('Accounts'), 'users'),
'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
'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'),
'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
);
/* get plugins admin page */
$r = q("SELECT * FROM addon WHERE plugin_admin = 1");
$aside['plugins_admin'] = array();
if($r) {
foreach ($r as $h){
$plugin = $h['name'];
$aside['plugins_admin'][] = array(z_root() . '/admin/plugins/' . $plugin, $plugin, 'plugin');
// temp plugins with admin
$a->plugins_admin[] = $plugin;
}
}
$aside['logs'] = array(z_root() . '/admin/logs/', t('Logs'), 'logs');
$o .= replace_macros(get_markup_template('admin_aside.tpl'), array(
'$admin' => $aside,
'$admtxt' => t('Admin'),
'$plugadmtxt' => t('Plugin Features'),
'$logtxt' => t('Logs'),
'$h_pending' => t('User registrations waiting for confirmation'),
'$admurl'=> z_root() . '/admin/'
));
return $o;
}

View File

@ -2896,6 +2896,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('item_id',$arr) && $arr['item_id'])
sync_items($channel,$arr['item_id']);
if(array_key_exists('menu',$arr) && $arr['menu'])
sync_menus($channel,$arr['menu']);
if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) {
if(array_key_exists('channel_page_flags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) {
$arr['channel']['channel_removed'] = (($arr['channel']['channel_pageflags'] & 0x8000) ? 1 : 0);

View File

@ -84,48 +84,6 @@ function admin_content(&$a) {
return login(false);
}
/*
* Side bar links
*/
// array( url, name, extra css classes )
$aside = array(
'site' => array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
'users' => array($a->get_baseurl(true)."/admin/users/", t("Accounts") , "users"),
'channels' => array($a->get_baseurl(true)."/admin/channels/", t("Channels") , "channels"),
'plugins' => array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
'themes' => array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
// 'hubloc' => array($a->get_baseurl(true)."/admin/hubloc/", t("Server") , "server"),
'profs' => array(z_root() . '/admin/profs', t('Profile Config'), 'profs'),
'dbsync' => array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync")
);
/* get plugins admin page */
$r = q("SELECT * FROM addon WHERE plugin_admin = 1");
$aside['plugins_admin'] = array();
foreach ($r as $h){
$plugin = $h['name'];
$aside['plugins_admin'][] = array($a->get_baseurl(true) . '/admin/plugins/' . $plugin, $plugin, 'plugin');
// temp plugins with admin
$a->plugins_admin[] = $plugin;
}
$aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
$t = get_markup_template("admin_aside.tpl");
$a->page['aside'] .= replace_macros( $t, array(
'$admin' => $aside,
'$admtxt' => t('Admin'),
'$plugadmtxt' => t('Plugin Features'),
'$logtxt' => t('Logs'),
'$h_pending' => t('User registrations waiting for confirmation'),
'$admurl'=> $a->get_baseurl(true)."/admin/"
));
/*
* Page content

View File

@ -443,6 +443,9 @@ function import_post(&$a) {
if(is_array($data['event_item']))
import_items($channel,$data['event_item']);
if(is_array($data['menu']))
import_menus($channel,$data['menu']);
$saved_notification_flags = notifications_off($channel['channel_id']);

View File

@ -37,6 +37,7 @@ function menu_post(&$a) {
$_REQUEST['menu_id'] = intval(argv(1));
$r = menu_edit($_REQUEST);
if($r) {
menu_sync_packet($uid,get_observer_hash(),$menu_id);
//info( t('Menu updated.') . EOL);
goaway(z_root() . '/mitem/' . $menu_id . (($a->is_sys) ? '?f=&sys=1' : ''));
}
@ -45,7 +46,9 @@ function menu_post(&$a) {
}
else {
$r = menu_create($_REQUEST);
if($r) {
if($r) {
menu_sync_packet($uid,get_observer_hash(),$r);
//info( t('Menu created.') . EOL);
goaway(z_root() . '/mitem/' . $r . (($a->is_sys) ? '?f=&sys=1' : ''));
}
@ -56,6 +59,8 @@ function menu_post(&$a) {
}
function menu_content(&$a) {
$uid = local_channel();
@ -121,6 +126,7 @@ function menu_content(&$a) {
if(intval(argv(1))) {
if(argc() == 3 && argv(2) == 'drop') {
menu_sync_packet($uid,get_observer_hash(),intval(argv(1)),true);
$r = menu_delete_id(intval(argv(1)),$uid);
if(!$r)
notice( t('Menu could not be deleted.'). EOL);

View File

@ -64,6 +64,7 @@ function mitem_post(&$a) {
$_REQUEST['mitem_id'] = $mitem_id;
$r = menu_edit_item($_REQUEST['menu_id'],$uid,$_REQUEST);
if($r) {
menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']);
//info( t('Menu element updated.') . EOL);
goaway(z_root() . '/mitem/' . $_REQUEST['menu_id'] . (($a->is_sys) ? '?f=&sys=1' : ''));
}
@ -74,6 +75,7 @@ function mitem_post(&$a) {
else {
$r = menu_add_item($_REQUEST['menu_id'],$uid,$_REQUEST);
if($r) {
menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']);
//info( t('Menu element added.') . EOL);
if($_REQUEST['submit']) {
goaway(z_root() . '/menu' . (($a->is_sys) ? '?f=&sys=1' : ''));
@ -202,7 +204,9 @@ function mitem_content(&$a) {
$lockstate = (($mitem['allow_cid'] || $mitem['allow_gid'] || $mitem['deny_cid'] || $mitem['deny_gid']) ? 'lock' : 'unlock');
if(argc() == 4 && argv(3) == 'drop') {
menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']);
$r = menu_del_item($mitem['mitem_menu_id'], $uid, intval(argv(2)));
menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']);
if($r)
info( t('Menu item deleted.') . EOL);
else

View File

@ -130,7 +130,7 @@ function profile_photo_post(&$a) {
if($r) {
$base_image = $r[0];
$base_image['data'] = dbunescbin($base_image['data']);
$base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']));
$im = photo_factory($base_image['data'], $base_image['type']);
if($im->is_valid()) {
@ -332,7 +332,7 @@ function profile_photo_content(&$a) {
goaway($a->get_baseurl() . '/profiles');
}
$r = q("SELECT `data`, `type` FROM photo WHERE id = %d and uid = %d limit 1",
$r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval(local_channel())
@ -342,9 +342,31 @@ function profile_photo_content(&$a) {
return;
}
$ph = photo_factory(dbunescbin($r[0]['data']), $r[0]['type']);
// go ahead as if we have just uploaded a new photo to crop
profile_photo_crop_ui_head($a, $ph);
if(intval($r[0]['os_storage']))
$data = @file_get_contents($r[0]['data']);
else
$data = dbunescbin($r[0]['data']);
$ph = photo_factory($data, $r[0]['type']);
$smallest = 0;
if($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
$i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale",
dbesc($r[0]['resource_id']),
intval(local_channel())
);
if($i) {
$hash = $i[0]['resource_id'];
foreach($i as $ii) {
if(intval($ii['scale']) < 2) {
$smallest = intval($ii['scale']);
}
}
}
}
profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
}
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d",

View File

@ -1 +1 @@
2015-09-07.1148
2015-09-08.1149

3
view/pdl/mod_admin.pdl Normal file
View File

@ -0,0 +1,3 @@
[region=aside]
[widget=admin][/widget]
[/region]