Merge branch 'dev'

This commit is contained in:
zotlabs 2018-09-20 18:36:14 -07:00
commit a4d987b45a
18 changed files with 258 additions and 56 deletions

View File

@ -388,9 +388,7 @@ class Apps {
// This will catch somebody clicking on a system "available" app that hasn't had the path macros replaced
// and they are allowed to see the app
if(strstr($papp['url'],'$baseurl') || strstr($papp['url'],'$nick') || strstr($papp['photo'],'$baseurl') || strstr($pap['photo'],'$nick')) {
if(strpos($papp['url'],'$baseurl') || strpos($papp['url'],'$nick') || strpos($papp['photo'],'$baseurl') || strpos($papp['photo'],'$nick')) {
$view_channel = local_channel();
if(! $view_channel) {
$sys = get_sys_channel();
@ -399,7 +397,13 @@ class Apps {
self::app_macros($view_channel,$papp);
}
if(! strstr($papp['url'],'://'))
if(strpos($papp['url'], ',')) {
$urls = explode(',', $papp['url']);
$papp['url'] = trim($urls[0]);
$papp['settings_url'] = trim($urls[1]);
}
if(! strpos($papp['url'],'://'))
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
@ -468,7 +472,9 @@ class Apps {
$hosturl = '';
if(local_channel()) {
$installed = self::app_installed(local_channel(),$papp);
if(self::app_installed(local_channel(),$papp) && !$papp['deleted'])
$installed = true;
$hosturl = z_root() . '/';
}
elseif(remote_channel()) {
@ -495,6 +501,7 @@ class Apps {
if($mode === 'install') {
$papp['embed'] = true;
}
return replace_macros(get_markup_template('app.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
@ -503,11 +510,12 @@ class Apps {
'$installed' => $installed,
'$action_label' => (($hosturl && in_array($mode, ['view','install'])) ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : ''),
'$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''),
'$delete' => ((local_channel() && $mode == 'edit') ? t('Delete') : ''),
'$undelete' => ((local_channel() && $mode == 'edit') ? t('Undelete') : ''),
'$settings_url' => ((local_channel() && $installed && $mode == 'list') ? $papp['settings_url'] : ''),
'$deleted' => $papp['deleted'],
'$feature' => (($papp['embed']) ? false : true),
'$pin' => (($papp['embed']) ? false : true),
'$feature' => (($papp['embed'] || $mode == 'edit') ? false : true),
'$pin' => (($papp['embed'] || $mode == 'edit') ? false : true),
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
@ -912,7 +920,7 @@ class Apps {
$arr['author'] = $sys['channel_hash'];
}
if($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (! strstr($arr['photo'],z_root()))) {
if($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (! strpos($arr['photo'],z_root()))) {
$x = import_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@ -998,7 +1006,7 @@ class Apps {
if((! $darray['app_url']) || (! $darray['app_id']))
return $ret;
if($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (! strstr($arr['photo'],z_root()))) {
if($arr['photo'] && (strpos($arr['photo'],'icon:') === false) && (! strpos($arr['photo'],z_root()))) {
$x = import_xchan_photo(str_replace('$baseurl',z_root(),$arr['photo']),get_observer_hash(),true);
$arr['photo'] = $x[1];
}

View File

@ -1,6 +1,7 @@
<?php
namespace Zotlabs\Module;
use App;
require_once('include/socgraph.php');
require_once('include/selectors.php');
@ -12,8 +13,10 @@ class Connections extends \Zotlabs\Web\Controller {
if(! local_channel())
return;
App::$profile_uid = local_channel();
$channel = \App::get_channel();
$channel = App::get_channel();
if($channel)
head_set_icon($channel['xchan_photo_s']);
@ -43,7 +46,7 @@ class Connections extends \Zotlabs\Web\Controller {
$all = false;
if(! $_REQUEST['aj'])
$_SESSION['return_url'] = \App::$query_string;
$_SESSION['return_url'] = App::$query_string;
$search_flags = "";
$head = '';
@ -88,14 +91,14 @@ class Connections extends \Zotlabs\Web\Controller {
$search_flags = " and abook_pending = 1 ";
$head = t('New');
$pending = true;
\App::$argv[1] = 'pending';
App::$argv[1] = 'pending';
}
else {
$head = t('All');
$search_flags = '';
$all = true;
\App::$argc = 1;
unset(\App::$argv[1]);
App::$argc = 1;
unset(App::$argv[1]);
}
break;
// case 'unconnected':
@ -225,15 +228,15 @@ class Connections extends \Zotlabs\Web\Controller {
intval(local_channel())
);
if($r) {
\App::set_pager_total($r[0]['total']);
App::set_pager_total($r[0]['total']);
$total = $r[0]['total'];
}
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ORDER BY xchan_name LIMIT %d OFFSET %d ",
intval(local_channel()),
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
intval(App::$pager['itemspage']),
intval(App::$pager['start'])
);
$contacts = array();
@ -337,7 +340,7 @@ class Connections extends \Zotlabs\Web\Controller {
'$finding' => (($searching) ? t('Connections search') . ": '" . $search . "'" : ""),
'$submit' => t('Find'),
'$edit' => t('Edit'),
'$cmd' => \App::$cmd,
'$cmd' => App::$cmd,
'$contacts' => $contacts,
'$paginate' => paginate($a),

View File

@ -0,0 +1,51 @@
<?php
namespace Zotlabs\Module\Settings;
class Connections {
function post() {
check_form_security_token_redirectOnErr('/settings/connections', 'settings_connections');
$features = self::get_features();
process_features_post(local_channel(), $features, $_POST);
build_sync_packet();
return;
}
function get() {
$features = self::get_features();
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
'$action_url' => 'settings/connections',
'$form_security_token' => get_form_security_token("settings_connections"),
'$title' => t('Connections Settings'),
'$features' => process_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
return $o;
}
function get_features() {
$arr = [
[
'connfilter',
t('Connection Filtering'),
t('Filter incoming posts from connections based on keywords/content'),
false,
get_config('feature_lock','connfilter')
]
];
return $arr;
}
}

View File

@ -10,13 +10,7 @@ class Network {
$features = self::get_features();
foreach($features as $f) {
$k = $f[0];
if(array_key_exists("feature_$k",$_POST))
set_pconfig(local_channel(),'feature',$k, (string) $_POST["feature_$k"]);
else
set_pconfig(local_channel(),'feature', $k, '');
}
process_features_post(local_channel(), $features, $_POST);
build_sync_packet();
return;
@ -26,19 +20,14 @@ class Network {
$features = self::get_features();
foreach($features as $f) {
$arr[] = array('feature_' . $f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On')));
}
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
'$action_url' => 'settings/network',
'$form_security_token' => get_form_security_token("settings_network"),
'$title' => t('Activity Settings'),
'$features' => $arr,
'$baseurl' => z_root(),
'$submit' => t('Submit'),
'$features' => process_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
return $o;
@ -109,14 +98,6 @@ class Network {
t('Show friend and connection suggestions'),
false,
get_config('feature_lock','suggest')
],
[
'connfilter',
t('Connection Filtering'),
t('Filter incoming posts from connections based on keywords/content'),
false,
get_config('feature_lock','connfilter')
]
];

View File

@ -1,5 +1,5 @@
version: 1
url: $baseurl/connections
version: 1.1
url: $baseurl/connections, $baseurl/settings/connections
requires: local_channel
name: Connections
photo: icon:users

View File

@ -1,5 +1,5 @@
version: 1
url: $baseurl/network
version: 1.1
url: $baseurl/network, $baseurl/settings/network
requires: local_channel
name: Grid
photo: icon:th

11
doc/hook/attach_delete.bb Normal file
View File

@ -0,0 +1,11 @@
[h2]attach_delete[/h2]
Invoked when an attachment is deleted using attach_delete().
[code]
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo];
call_hooks("attach_delete",$arr);
[/code]
See include/attach.php

View File

@ -0,0 +1,39 @@
[h2]content_security_policy[/h2]
Called to modify CSP settings prior to the output of the Content-Security-Policy header.
This hook permits addons to modify the content-security-policy if necessary to allow loading of foreign js libraries or css styles.
[code]
if(App::$config['system']['content_security_policy']) {
$cspsettings = Array (
'script-src' => Array ("'self'","'unsafe-inline'","'unsafe-eval'"),
'style-src' => Array ("'self'","'unsafe-inline'")
);
call_hooks('content_security_policy',$cspsettings);
// Legitimate CSP directives (cxref: https://content-security-policy.com/)
$validcspdirectives=Array(
"default-src", "script-src", "style-src",
"img-src", "connect-src", "font-src",
"object-src", "media-src", 'frame-src',
'sandbox', 'report-uri', 'child-src',
'form-action', 'frame-ancestors', 'plugin-types'
);
$cspheader = "Content-Security-Policy:";
foreach ($cspsettings as $cspdirective => $csp) {
if (!in_array($cspdirective,$validcspdirectives)) {
logger("INVALID CSP DIRECTIVE: ".$cspdirective,LOGGER_DEBUG);
continue;
}
$cspsettingsarray=array_unique($cspsettings[$cspdirective]);
$cspsetpolicy = implode(' ',$cspsettingsarray);
if ($cspsetpolicy) {
$cspheader .= " ".$cspdirective." ".$cspsetpolicy.";";
}
}
header($cspheader);
}
[/code]
see: boot.php

View File

@ -0,0 +1,7 @@
[h2]dreport_process[/h2]
Called for each delivery report received
Passed a delivery_report array.
see: include/zot.php

View File

@ -0,0 +1,17 @@
[h2]dropdown_extras[/h2]
Modify the dropdown menu available through the cog of items as displayed by conv_item.tpl
This hook allows plugins to add arbitrary html to the cog dropdown of thread items displayed with the conv_item.tpl template.
It is fed an array of ['item' => $item, 'dropdown_extras' => '']. Any additions to the cog menu should be prepended/appended to
the ['dropdown_extras'] element.
[code]
$dropdown_extras_arr = [ 'item' => $item , 'dropdown_extras' => '' ];
call_hooks('dropdown_extras',$dropdown_extras_arr);
$dropdown_extras = $dropdown_extras_arr['dropdown_extras'];
[/code]
see: Zotlabs/Lib/ThreadItem.php
see: view/tpl/conv_item.tpl

0
doc/hook/permit_hook.bb Normal file
View File

View File

@ -52,6 +52,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/app_menu]app_menu[/zrl]
Called when generating the app_menu dropdown (may be obsolete)
[zrl=[baseurl]/help/hook/attach_delete]attach_delete[/zrl]
Called when attachments are deleted from the attach table
[zrl=[baseurl]/help/hook/atom_author]atom_author[/zrl]
Called when generating an author or owner element for an Atom ActivityStream feed
@ -113,7 +116,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
Validate the email provided in an account registration
[zrl=[baseurl]/help/hook/check_account_invite]check_account_invite[/zrl]
Validate an invitation code when using site invitations
Validate an invitation code when using site invitations
[zrl=[baseurl]/help/hook/check_account_password]check_account_password[/zrl]
Used to provide policy control over account passwords (minimum length, character set inclusion, etc.)
@ -137,7 +140,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
Called when posting to the features/addon settings page
[zrl=[baseurl]/help/hook/construct_page]construct_page[/zrl]
General purpose hook to provide content to certain page regions. Called when constructing the Comanche page.
General purpose hook to provide content to certain page regions. Called when constructing the Comanche page.
[zrl=[baseurl]/help/hook/contact_block_end]contact_block_end[/zrl]
Called when generating the sidebar "Connections" widget
@ -151,8 +154,11 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/contact_select_options]contact_select_options[/zrl]
Deprecated/unused
[zrl=[baseurl]/help/hook/content_security_policy]content_security_policy[/zrl]
Called prior to output of the Content-Security-Policy header
[zrl=[baseurl]/help/hook/conversation_start]conversation_start[/zrl]
Called in the beginning of rendering a conversation (message or message collection or stream)
Called in the beginning of rendering a conversation (message or message collection or stream)
[zrl=[baseurl]/help/hook/cover_photo_content_end]cover_photo_content_end[/zrl]
Called after a cover photo has been uplaoded
@ -183,7 +189,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/display_item]display_item[/zrl]
Called for each item being displayed in a conversation thread
[zrl=[baseurl]/help/hook/display_settings]display_settings[/zrl]
Called from settings module when displaying the 'display settings' section
@ -202,6 +208,12 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/dreport_is_storable]dreport_is_storable[/zrl]
called before storing a dreport record to determine whether to store it
[zrl=[baseurl]/help/hook/dreport_process]dreport_process[/zrl]
called for each valid delivery report
[zrl=[baseurl]/help/hook/dropdown_extras]dropdown_extras[/zrl]
Add additional items to the dropdown cog when item/threads are displayed.
[zrl=[baseurl]/help/hook/drop_item]drop_item[/zrl]
called when an 'item' is removed
@ -260,7 +272,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
called to generate the HTML for displaying a map location by text location
[zrl=[baseurl]/help/hook/get_all_api_perms]get_all_api_perms[/zrl]
Called when retrieving the permissions for API uses
Called when retrieving the permissions for API uses
[zrl=[baseurl]/help/hook/get_all_perms]get_all_perms[/zrl]
called when get_all_perms() is used
@ -446,7 +458,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
Called when probing a URL to generate post content from it
[zrl=[baseurl]/help/hook/pdl_selector]pdl_selector[/zrl]
Called when creating a layout selection in a form
Called when creating a layout selection in a form
[zrl=[baseurl]/help/hook/perm_is_allowed]perm_is_allowed[/zrl]
Called during perm_is_allowed() to determine if a permission is allowed for this channel and observer
@ -457,6 +469,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/permissions_update]permissions_update[/zrl]
Called when a permissions refresh is transmitted
[zrl=[baseurl]/help/hook/permit_hook]permit_hook[/zrl]
Called before a registered hook is actually executed to determine if it should be allowed or blocked
[zrl=[baseurl]/help/hook/personal_xrd]personal_xrd[/zrl]
Called when generating the personal XRD for "old webfinger" (Diaspora)
@ -540,7 +555,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/queue_deliver]queue_deliver[/zrl]
Called when delivering a queued message
[zrl=[baseurl]/help/hook/register_account]register_account[/zrl]
Called when an account has been created

View File

@ -44,6 +44,23 @@ function feature_level($feature,$def) {
return $def;
}
function process_features_get($uid, $features) {
foreach($features as $f) {
$arr[] = array('feature_' . $f[0],$f[1],((intval(feature_enabled($uid, $f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On')));
}
return $arr;
}
function process_features_post($uid, $features, $post_arr) {
foreach($features as $f) {
$k = $f[0];
if(array_key_exists("feature_$k",$post_arr))
set_pconfig($uid,'feature',$k, (string) $post_arr["feature_$k"]);
else
set_pconfig($uid,'feature', $k, '');
}
}
function get_features($filtered = true, $level = (-1)) {
$account = \App::get_account();

View File

@ -199,14 +199,25 @@ function nav($template = 'default') {
// turned off until somebody discovers this and figures out a good location for it.
$powered_by = '';
$url = '';
$settings_url = '';
if(App::$profile_uid && App::$nav_sel['raw_name']) {
$active_app = q("SELECT app_url FROM app WHERE app_channel = %d AND app_name = '%s' LIMIT 1",
intval(App::$profile_uid),
dbesc(App::$nav_sel['raw_name'])
);
if($active_app) {
$url = $active_app[0]['app_url'];
if(strpos($active_app[0]['app_url'], ',')) {
$urls = explode(',', $active_app[0]['app_url']);
$url = trim($urls[0]);
if($is_owner)
$settings_url = trim($urls[1]);
}
else {
$url = $active_app[0]['app_url'];
}
}
}
@ -289,7 +300,8 @@ function nav($template = 'default') {
'$addapps' => t('Add Apps'),
'$orderapps' => t('Arrange Apps'),
'$sysapps_toggle' => t('Toggle System Apps'),
'$url' => (($url) ? $url : App::$cmd)
'$url' => (($url) ? $url : App::$cmd),
'$settings_url' => $settings_url
));
if(x($_SESSION, 'reload_avatar') && $observer) {

View File

@ -458,6 +458,25 @@ function call_hooks($name, &$data = null) {
if (isset(App::$hooks[$name])) {
foreach(App::$hooks[$name] as $hook) {
if ($name != 'permit_hook') { // avoid looping
$checkhook = [
'name'=>$name,
'hook'=>$hook,
'data'=>$data,
// Note: Since PHP uses COPY-ON-WRITE
// for variables, there is no cost to
// passing the $data structure (unless
// the permit_hook processors change the
// information it contains.
'permit'=>true
];
call_hooks('permit_hook',$checkhook);
if (!$checkhook['permit']) {
continue;
}
$data = $checkhook['data'];
}
$origfn = $hook[1];
if($hook[0])
@include_once($hook[0]);

View File

@ -20,6 +20,7 @@
{{if $delete}}<button type="submit" name="delete" value="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" class="btn btn-outline-secondary btn-sm" title="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" ><i class="fa fa-fw fa-trash-o drop-icons"></i></button>{{/if}}
{{if $feature}}<button type="submit" name="feature" value="nav_featured_app" class="btn btn-outline-secondary btn-sm" title="{{if $featured}}{{$remove}}{{else}}{{$add}}{{/if}}"><i class="fa fa-fw fa-star{{if $featured}} text-warning{{/if}}"></i></button>{{/if}}
{{if $pin}}<button type="submit" name="pin" value="nav_pinned_app" class="btn btn-outline-secondary btn-sm" title="{{if $pinned}}{{$remove_nav}}{{else}}{{$add_nav}}{{/if}}"><i class="fa fa-fw fa-thumb-tack{{if $pinned}} text-success{{/if}}"></i></button>{{/if}}
{{if $settings_url}}<a href="{{$settings_url}}" class="btn btn-outline-secondary btn-sm"><i class="fa fa-fw fa-cog"></i></a>{{/if}}
</form>
</div>
{{/if}}

View File

@ -70,7 +70,15 @@
<br><small>{{$sitelocation}}</small>
{{/if}}
</a>
</div>
{{if $settings_url}}
<div id="nav-app-settings-link-wrapper" class="navbar-nav mr-auto">
<a id="nav-app-settings-link" href="{{$settings_url}}" class="nav-link">
<i class="fa fa-fw fa-cog"></i>
</a>
</div>
{{/if}}
{{/if}}
{{/if}}
<div class="navbar-toggler-right">

View File

@ -0,0 +1,13 @@
<div class="generic-content-wrapper">
<div class="section-title-wrapper">
<h2>{{$title}}</h2>
</div>
<div class="section-content-wrapper">
<form action="{{$action_url}}" method="post" autocomplete="off">
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
{{$content}}
<div class="settings-submit-wrapper" >
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
</div>
</div>
</div>