Merge remote-tracking branch 'upstream/dev' into wiki
This commit is contained in:
commit
e0d9d30bcf
41
CHANGELOG
41
CHANGELOG
@ -1,3 +1,44 @@
|
||||
Hubzilla 1.10
|
||||
Wiki:
|
||||
Lots of enhanced functionality, usability improvements, and bugfixes from v1.8
|
||||
Turned into an optional feature (default on) but disabled in UNO
|
||||
Sync:
|
||||
Items are now relocated (links patched) when syncing to clones
|
||||
Access Tokens:
|
||||
New feature - allows members to create access controlled guest logins and create/share 'dropbox' style links to protected resources.
|
||||
UI:
|
||||
Use icons instead of iconic text constructs
|
||||
Only request geolocation permission when creating a post, not on page load
|
||||
provide 'redeliver' option on Delivery Report page for when things really stuff up
|
||||
CalDAV/CardDAV management pages with heaps of functionality
|
||||
Lib:
|
||||
z_fetch_url() updated to accept different request methods and request bodies
|
||||
item_store(), item_store_update() now return the stored items
|
||||
vcard microformat changes to remain spec compliant
|
||||
microformat meta tags added to post/comments
|
||||
AbConfig API changed to use channel_id rather than channel_hash, which was overly complicated to use
|
||||
SuperCurl class added to provide a framework for re-use of obscure CURL options
|
||||
Allow absolute links to CSS/JS files on CDN
|
||||
Add Let'sEncrypt intermediate cert to lib in case you forget to install it on the server
|
||||
Update fullcalendar and jquery (3.1) libs
|
||||
Update sabre/dav to 3.2.0
|
||||
Change content export from a month/year system to begin/end
|
||||
Use streaming I/O for delivering large photos
|
||||
Allow multiple App description files in a single plugin directory
|
||||
optimise a couple of troublesome/inefficient SQL queries
|
||||
avoid sending clone sync packets to dead sites
|
||||
Resolved Issues:
|
||||
channel home page not providing content to clients with javascript disabled
|
||||
Replace '@' obfuscation with html entity rather than the unicode look-alike
|
||||
xchan_query() failing to detect duplicates, resulting in inefficient queries
|
||||
issues with 'use existing photo' for profile photo
|
||||
layout editor "list all layouts" returned empty
|
||||
oembed - better detect video file URLs so they aren't loaded into memory.
|
||||
handcrafted bbcode tables could end up with way too much whitespace due to CRLF translation
|
||||
refresh permissions whitescreen in 1.8
|
||||
force immediate profile photo update on local site
|
||||
regression: 'save bookmarks' post action missing
|
||||
|
||||
Hubzilla 1.8
|
||||
Administration:
|
||||
Cleanup and resolve some edge cases with addon repository manager
|
||||
|
12
README.md
12
README.md
@ -47,4 +47,16 @@ Possible website applications include
|
||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
</p>
|
||||
|
||||
**Who Are We and What Are Our Principles?**
|
||||
|
||||
The Hubzilla community is powered by passionate volunteers creating an open source **commons** of decentralised services which are highly integrated and can rival the feature set of centralised providers. We are open to sponsorship and donations to cover expenses and compensate for our time and energy, however the project core is basically non-profit and is not designed for the purpose of commercial gain or exploitation.
|
||||
|
||||
Some sites may include monetisation strategies such as subscriptions and *freemium* models where members pay for resources they consume beyond a basic level. The project community supports such monetisation initiatives (nobody should be forced to pay "out of pocket" to provide a service to others), but we maintain the **commons** to provide open and free access of the software to all.
|
||||
|
||||
The software is not designed for data collection of its members or providing advertising. We don't have a need or desire for these things and feel that software built around these goals is poorly designed and represents compromised principles and ethics.
|
||||
|
||||
As a project, we are inclusive of all beliefs and cultures and do what we are able to provide an environment that is free from hostility and harrassment. Whether or not we succeed in this endaevour requires constant vigilance and help from all members of the community, working together to build an inter-networking tool with amazing potential.
|
||||
|
||||
|
||||
|
||||
[](https://travis-ci.org/redmatrix/hubzilla)
|
||||
|
@ -62,6 +62,15 @@ class Cron {
|
||||
}
|
||||
|
||||
|
||||
// delete expired access tokens
|
||||
|
||||
q("delete from atoken where atoken_expires != '%s' && atoken_expires < %s",
|
||||
dbesc(NULL_DATE),
|
||||
dbutcnow()
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Ensure that every channel pings a directory server once a month. This way we can discover
|
||||
// channels and sites that quietly vanished and prevent the directory from accumulating stale
|
||||
// or dead entries.
|
||||
|
@ -5,8 +5,10 @@ namespace Zotlabs\Lib;
|
||||
|
||||
class AbConfig {
|
||||
|
||||
static public function Load($chan,$xhash) {
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s'",
|
||||
static public function Load($chan,$xhash,$family = '') {
|
||||
if($family)
|
||||
$where = sprintf(" and family = '%s' ",dbesc($family));
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' $where",
|
||||
intval($chan),
|
||||
dbesc($xhash)
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
if(class_exists('PermissionDescription')) return;
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once("include/permissions.php");
|
||||
require_once("include/language.php");
|
@ -1,7 +1,18 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/* ACL selector json backend */
|
||||
/*
|
||||
* ACL selector json backend
|
||||
* This module provides JSON lists of connections and local/remote channels
|
||||
* (xchans) to populate various tools such as the ACL (AccessControlList) popup
|
||||
* and various auto-complete functions (such as email recipients, search, and
|
||||
* mention targets.
|
||||
* There are two primary output structural formats. One for the ACL widget and
|
||||
* the other for auto-completion.
|
||||
* Many of the behaviour variations are triggered on the use of single character keys
|
||||
* however this functionality has grown in an ad-hoc manner and has gotten quite messy over time.
|
||||
*/
|
||||
|
||||
require_once("include/acl_selectors.php");
|
||||
require_once("include/group.php");
|
||||
|
||||
@ -10,40 +21,63 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init(){
|
||||
|
||||
// logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||
// logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||
|
||||
$start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
|
||||
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
|
||||
$search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
|
||||
$type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
|
||||
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : '');
|
||||
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : '');
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
|
||||
|
||||
// $type =
|
||||
// '' => standard ACL request
|
||||
// 'g' => Groups only ACL request
|
||||
// 'c' => Connections only ACL request or editor (textarea) mention request
|
||||
// $_REQUEST['search'] contains ACL search text.
|
||||
|
||||
|
||||
// $type =
|
||||
// 'm' => autocomplete private mail recipient (checks post_mail permission)
|
||||
// 'a' => autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos)
|
||||
// 'x' => nav search bar autocomplete (match any xchan)
|
||||
// $_REQUEST['query'] contains autocomplete search text.
|
||||
|
||||
// List of channels whose connections to also suggest, e.g. currently viewed channel or channels mentioned in a post
|
||||
// List of channels whose connections to also suggest,
|
||||
// e.g. currently viewed channel or channels mentioned in a post
|
||||
|
||||
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
|
||||
|
||||
// For use with jquery.autocomplete for private mail completion
|
||||
// The different autocomplete libraries use different names for the search text
|
||||
// parameter. Internaly we'll use $search to represent the search text no matter
|
||||
// what request variable it was attached to.
|
||||
|
||||
if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
|
||||
if(! $type)
|
||||
$type = 'm';
|
||||
if(array_key_exists('query',$_REQUEST)) {
|
||||
$search = $_REQUEST['query'];
|
||||
}
|
||||
|
||||
if(!(local_channel()))
|
||||
if(!($type == 'x' || $type == 'c'))
|
||||
killme();
|
||||
if( (! local_channel()) && (! ($type == 'x' || $type == 'c')))
|
||||
killme();
|
||||
|
||||
if ($search != "") {
|
||||
if($search) {
|
||||
$sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
||||
|
||||
// This horrible mess is needed because position also returns 0 if nothing is found. W/ould be MUCH easier if it instead returned a very large value
|
||||
// Otherwise we could just order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
|
||||
$order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) ." then POSITION('".dbesc($search)."' IN xchan_name) else position('".dbesc($search)."' IN xchan_addr) end, ";
|
||||
// This horrible mess is needed because position also returns 0 if nothing is found.
|
||||
// Would be MUCH easier if it instead returned a very large value
|
||||
// Otherwise we could just
|
||||
// order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
|
||||
|
||||
$order_extra2 = "CASE WHEN xchan_name LIKE "
|
||||
. protect_sprintf( "'%" . dbesc($search) . "%'" )
|
||||
. " then POSITION('" . dbesc($search)
|
||||
. "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
|
||||
|
||||
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
|
||||
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = "";
|
||||
}
|
||||
|
||||
@ -51,7 +85,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$groups = array();
|
||||
$contacts = array();
|
||||
|
||||
if ($type=='' || $type=='g'){
|
||||
if($type == '' || $type == 'g') {
|
||||
|
||||
$r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname`
|
||||
FROM `groups`,`group_member`
|
||||
@ -82,7 +116,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if ($type=='' || $type=='c') {
|
||||
if($type == '' || $type == 'c') {
|
||||
$extra_channels_sql = '';
|
||||
// Only include channels who allow the observer to view their permissions
|
||||
foreach($extra_channels as $channel) {
|
||||
@ -96,13 +130,40 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
if(local_channel()) {
|
||||
if($extra_channels_sql != '')
|
||||
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
|
||||
|
||||
$r2 = null;
|
||||
|
||||
$r1 = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r1) {
|
||||
require_once('include/security.php');
|
||||
$r2 = array();
|
||||
foreach($r1 as $rr) {
|
||||
$x = atoken_xchan($rr);
|
||||
$r2[] = [
|
||||
'id' => 'a' . $rr['atoken_id'] ,
|
||||
'hash' => $x['xchan_hash'],
|
||||
'name' => $x['xchan_name'],
|
||||
'micro' => $x['xchan_photo_m'],
|
||||
'url' => z_root(),
|
||||
'nick' => $x['xchan_addr'],
|
||||
'abook_their_perms' => 0,
|
||||
'abook_flags' => 0,
|
||||
'abook_self' => 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($r2)
|
||||
$r = array_merge($r2,$r);
|
||||
|
||||
}
|
||||
else { // Visitors
|
||||
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
|
||||
@ -171,7 +232,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
intval(PERMS_W_MAIL)
|
||||
);
|
||||
}
|
||||
elseif(($type == 'a') || ($type == 'p')) {
|
||||
elseif($type == 'a') {
|
||||
|
||||
$r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d
|
||||
@ -296,7 +357,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$url = $directory['url'] . '/dirsearch';
|
||||
}
|
||||
|
||||
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
||||
if($url) {
|
||||
$query = $url . '?f=' ;
|
||||
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : '');
|
||||
|
@ -9,7 +9,6 @@ require_once('include/security.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/permissions.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
class Channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
@ -133,7 +132,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
||||
'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
|
||||
'nickname' => \App::$profile['channel_address'],
|
||||
'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
|
||||
'showacl' => (($is_owner) ? 'yes' : ''),
|
||||
'bang' => '',
|
||||
'visitor' => (($is_owner || $observer) ? true : false),
|
||||
|
@ -13,6 +13,9 @@ use \Zotlabs\Storage;
|
||||
// composer autoloader for SabreDAV
|
||||
require_once('vendor/autoload.php');
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fires up the SabreDAV server.
|
||||
*
|
||||
|
@ -14,6 +14,7 @@ use \Zotlabs\Storage;
|
||||
// composer autoloader for SabreDAV
|
||||
require_once('vendor/autoload.php');
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
/**
|
||||
* @brief Fires up the SabreDAV server.
|
||||
|
@ -4,7 +4,6 @@ namespace Zotlabs\Module;
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
@ -151,7 +150,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
'body' => undo_post_tagging($itm[0]['body']),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => ($is_owner) ? true : false,
|
||||
'acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'showacl' => ($is_owner) ? true : false,
|
||||
'mimetype' => $mimetype,
|
||||
'mimeselect' => true,
|
||||
|
@ -159,7 +159,7 @@ function embedphotos_widget_album($args) {
|
||||
'$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)),
|
||||
'$order' => false,
|
||||
'$upload_form' => $upload_form,
|
||||
'$usage' => $usage_message
|
||||
'$no_fullscreen_btn' => true
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
@ -6,7 +6,6 @@ require_once('include/bbcode.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/event.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Events extends \Zotlabs\Web\Controller {
|
||||
@ -471,7 +470,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
'$permissions' => t('Permission settings'),
|
||||
// populating the acl dialog was a permission description from view_stream because Cal.php, which
|
||||
// displays events, says "since we don't currently have an event permission - use the stream permission"
|
||||
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \PermissionDescription::fromGlobalPermission('view_stream'))),
|
||||
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'))),
|
||||
'$submit' => t('Submit'),
|
||||
'$advanced' => t('Advanced Options')
|
||||
|
||||
|
@ -6,7 +6,6 @@ namespace Zotlabs\Module;
|
||||
*/
|
||||
|
||||
require_once('include/attach.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
/**
|
||||
@ -134,7 +133,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
||||
$cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : '');
|
||||
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
|
||||
|
||||
$aclselect_e = populate_acl($f, false, \PermissionDescription::fromGlobalPermission('view_storage'));
|
||||
$aclselect_e = populate_acl($f, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage'));
|
||||
$is_a_dir = (intval($f['is_dir']) ? true : false);
|
||||
|
||||
$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock');
|
||||
|
@ -28,6 +28,19 @@ class Home extends \Zotlabs\Web\Controller {
|
||||
|
||||
goaway($dest);
|
||||
}
|
||||
|
||||
if(remote_channel() && (! $splash) && $_SESSION['atoken']) {
|
||||
$r = q("select * from atoken where atoken_id = %d",
|
||||
intval($_SESSION['atoken'])
|
||||
);
|
||||
if($r) {
|
||||
$x = channelx_by_n($r[0]['atoken_uid']);
|
||||
if($x) {
|
||||
goaway(z_root() . '/channel/' . $x['channel_address']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(get_account_id() && ! $splash) {
|
||||
goaway(z_root() . '/new_channel');
|
||||
|
@ -905,7 +905,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
}
|
||||
}
|
||||
if(! $nopush)
|
||||
@ -1000,7 +1000,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1014,11 +1014,6 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
logger('post_complete');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// figure out how to return, depending on from whence we came
|
||||
|
||||
if($api_source)
|
||||
|
@ -1,17 +1,31 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
class Lockview extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$atokens = array();
|
||||
|
||||
if(local_channel()) {
|
||||
$at = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($at) {
|
||||
foreach($at as $t) {
|
||||
$atokens[] = atoken_xchan($t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$type = ((argc() > 1) ? argv(1) : 0);
|
||||
if (is_numeric($type)) {
|
||||
$item_id = intval($type);
|
||||
$type='item';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$item_id = ((argc() > 2) ? intval(argv(2)) : 0);
|
||||
}
|
||||
|
||||
@ -98,6 +112,13 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<li>' . $rr['xchan_name'] . '</li>';
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) {
|
||||
$l[] = '<li>' . $at['xchan_name'] . '</li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($deny_groups)) {
|
||||
$r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
|
||||
@ -110,6 +131,16 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<li><strike>' . $rr['xchan_name'] . '</strike></li>';
|
||||
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) {
|
||||
$l[] = '<li><strike>' . $at['xchan_name'] . '</strike></li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $o . implode($l);
|
||||
|
@ -6,8 +6,6 @@ require_once('include/group.php');
|
||||
require_once('include/contact_widgets.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
|
||||
class Network extends \Zotlabs\Web\Controller {
|
||||
@ -171,7 +169,7 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'bang' => (($private_editing) ? '!' : ''),
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
|
@ -9,8 +9,6 @@ require_once('include/bbcode.php');
|
||||
require_once('include/security.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/text.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
|
||||
class Photos extends \Zotlabs\Web\Controller {
|
||||
@ -633,7 +631,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
$lockstate = (($acl->is_private()) ? 'lock' : 'unlock');
|
||||
}
|
||||
|
||||
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
|
||||
// this is wrong but is to work around an issue with js_upload wherein it chokes if these variables
|
||||
// don't exist. They really should be set to a parseable representation of the channel's default permissions
|
||||
@ -1023,7 +1021,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
if($can_post) {
|
||||
$album_e = $ph[0]['album'];
|
||||
$caption_e = $ph[0]['description'];
|
||||
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
|
||||
|
||||
$_SESSION['album_return'] = bin2hex($ph[0]['album']);
|
||||
|
@ -7,7 +7,6 @@ require_once('include/items.php');
|
||||
require_once('include/taxonomy.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/zot.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
/**
|
||||
* remote post
|
||||
@ -116,7 +115,7 @@ class Rpost extends \Zotlabs\Web\Controller {
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl($channel_acl, true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'bang' => '',
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
|
@ -2,8 +2,6 @@
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
|
||||
class Settings extends \Zotlabs\Web\Controller {
|
||||
@ -30,7 +28,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
@ -119,6 +117,60 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
build_sync_packet();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 1) && (argv(1) == 'tokens')) {
|
||||
check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
|
||||
$token_errs = 0;
|
||||
if(array_key_exists('token',$_POST)) {
|
||||
$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
|
||||
$name = trim(escape_tags($_POST['name']));
|
||||
$token = trim($_POST['token']);
|
||||
if((! $name) || (! $token))
|
||||
$token_errs ++;
|
||||
if(trim($_POST['expires']))
|
||||
$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
|
||||
else
|
||||
$expires = NULL_DATE;
|
||||
$max_atokens = service_class_fetch(local_channel(),'access_tokens');
|
||||
if($max_atokens) {
|
||||
$r = q("select count(atoken_id) as total where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r && intval($r[0]['total']) >= $max_tokens) {
|
||||
notice( sprintf( t('This channel is limited to %d tokens'), $max_tokens) . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($token_errs) {
|
||||
notice( t('Name and Password are required.') . EOL);
|
||||
return;
|
||||
}
|
||||
if($atoken_id) {
|
||||
$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expires = '%s'
|
||||
where atoken_id = %d and atoken_uid = %d",
|
||||
dbesc($name),
|
||||
dbesc($token),
|
||||
dbesc($expires),
|
||||
intval($atoken_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )
|
||||
values ( %d, %d, '%s', '%s', '%s' ) ",
|
||||
intval($channel['channel_account_id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name),
|
||||
dbesc($token),
|
||||
dbesc($expires)
|
||||
);
|
||||
}
|
||||
|
||||
info( t('Token saved.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -708,6 +760,53 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
if((argc() > 1) && (argv(1) === 'tokens')) {
|
||||
$atoken = null;
|
||||
if(argc() > 2) {
|
||||
$id = argv(2);
|
||||
|
||||
$atoken = q("select * from atoken where atoken_id = %d and atoken_uid = %d",
|
||||
intval($id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($atoken)
|
||||
$atoken = $atoken[0];
|
||||
|
||||
if($atoken && argc() > 3 && argv(3) === 'drop') {
|
||||
$r = q("delete from atoken where atoken_id = %d",
|
||||
intval($id)
|
||||
);
|
||||
}
|
||||
}
|
||||
$t = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access the private content.');
|
||||
|
||||
$desc2 = t('You may also provide <em>dropbox</em> style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:');
|
||||
|
||||
$tpl = get_markup_template("settings_tokens.tpl");
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$form_security_token' => get_form_security_token("settings_tokens"),
|
||||
'$title' => t('Guest Access Tokens'),
|
||||
'$desc' => $desc,
|
||||
'$desc2' => $desc2,
|
||||
'$tokens' => $t,
|
||||
'$atoken' => $atoken,
|
||||
'$url1' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'$url2' => z_root() . '/photos/' . $channel['channel_address'],
|
||||
'$name' => array('name', t('Login Name') . ' <span class="required">*</span>', (($atoken) ? $atoken['atoken_name'] : ''),''),
|
||||
'$token'=> array('token', t('Login Password') . ' <span class="required">*</span>',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''),
|
||||
'$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] != NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1066,7 +1165,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
'$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')),
|
||||
'$permissions' => t('Default Post and Publish Permissions'),
|
||||
'$permdesc' => t("\x28click to open/close\x29"),
|
||||
'$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
|
||||
'$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
|
||||
'$suggestme' => $suggestme,
|
||||
'$group_select' => $group_select,
|
||||
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()),
|
||||
|
@ -493,7 +493,6 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$this->check_add($ck_funcs, t('OpenSSL PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mb_string PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mcrypt PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('xml PHP module'), true, true);
|
||||
|
||||
if(function_exists('apache_get_modules')){
|
||||
@ -530,10 +529,6 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$ck_funcs[4]['status'] = false;
|
||||
$ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.');
|
||||
}
|
||||
if(! function_exists('mcrypt_encrypt')) {
|
||||
$ck_funcs[5]['status'] = false;
|
||||
$ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.');
|
||||
}
|
||||
if(! extension_loaded('xml')) {
|
||||
$ck_funcs[6]['status'] = false;
|
||||
$ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.');
|
||||
|
@ -4,7 +4,6 @@ namespace Zotlabs\Module;
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Webpages extends \Zotlabs\Web\Controller {
|
||||
@ -105,7 +104,7 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
'is_owner' => true,
|
||||
'nickname' => \App::$profile['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => true,
|
||||
|
@ -231,7 +231,7 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the timezone from the channel in RedBasicAuth.
|
||||
* @brief Sets the timezone from the channel in BasicAuth.
|
||||
*
|
||||
* Set in mod/cloud.php if the channel has a timezone set.
|
||||
*
|
||||
|
@ -206,7 +206,6 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
$mimetype = z_mime_content_type($name);
|
||||
|
||||
|
@ -337,6 +337,10 @@ class File extends DAV\Node implements DAV\IFile {
|
||||
}
|
||||
}
|
||||
|
||||
if(get_pconfig($this->auth->owner_id,'system','os_delete_prohibit') && \App::$module == 'dav') {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
attach_delete($this->auth->owner_id, $this->data['hash']);
|
||||
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
|
@ -24,7 +24,8 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
return $r[0]['sess_data'];
|
||||
}
|
||||
else {
|
||||
q("INSERT INTO `session` (sid, expire) values ('%s', '%s')",
|
||||
q("INSERT INTO `session` (sess_data, sid, expire) values ('%s', '%s', '%s')",
|
||||
dbesc(''),
|
||||
dbesc($id),
|
||||
dbesc(time() + 300)
|
||||
);
|
||||
|
@ -59,7 +59,14 @@ class WebServer {
|
||||
\App::$query_string = strip_zids(\App::$query_string);
|
||||
if(! local_channel()) {
|
||||
$_SESSION['my_address'] = $_GET['zid'];
|
||||
zid_init($a);
|
||||
zid_init();
|
||||
}
|
||||
}
|
||||
|
||||
if((x($_GET,'zat')) && (! \App::$install)) {
|
||||
\App::$query_string = strip_zats(\App::$query_string);
|
||||
if(! local_channel()) {
|
||||
zat_init();
|
||||
}
|
||||
}
|
||||
|
||||
|
18
boot.php
18
boot.php
@ -44,10 +44,10 @@ require_once('include/account.php');
|
||||
|
||||
|
||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||
define ( 'STD_VERSION', '1.9' );
|
||||
define ( 'STD_VERSION', '1.11' );
|
||||
define ( 'ZOT_REVISION', '1.1' );
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1179 );
|
||||
define ( 'DB_UPDATE_VERSION', 1180 );
|
||||
|
||||
|
||||
/**
|
||||
@ -1703,7 +1703,7 @@ function login($register = false, $form_id = 'main-login', $hiddens=false) {
|
||||
'$logout' => t('Logout'),
|
||||
'$login' => t('Login'),
|
||||
'$form_id' => $form_id,
|
||||
'$lname' => array('username', t('Email') , '', ''),
|
||||
'$lname' => array('username', t('Login/Email') , '', ''),
|
||||
'$lpassword' => array('password', t('Password'), '', ''),
|
||||
'$remember_me' => array('remember_me', t('Remember me'), '', '',array(t('No'),t('Yes'))),
|
||||
'$hiddens' => $hiddens,
|
||||
@ -2457,24 +2457,16 @@ function check_cron_broken() {
|
||||
set_config('system','lastcroncheck',datetime_convert());
|
||||
return;
|
||||
}
|
||||
$t = get_config('system','lastcroncheck');
|
||||
if($t === false) {
|
||||
// This is serious. Config storage isn't working.
|
||||
// We just set lastcroncheck. The system is horked.
|
||||
// However don't add insult to injury by sending an email
|
||||
// to the admin every time a page is accessed.
|
||||
// just quietly
|
||||
return;
|
||||
}
|
||||
|
||||
if($t > datetime_convert('UTC','UTC','now - 3 days')) {
|
||||
// Wait for 3 days before we do anything so as not to swamp the admin with messages
|
||||
return;
|
||||
}
|
||||
|
||||
set_config('system','lastcroncheck',datetime_convert());
|
||||
|
||||
if(($d) && ($d > datetime_convert('UTC','UTC','now - 3 days'))) {
|
||||
// Scheduled tasks have run successfully in the last 3 days.
|
||||
set_config('system','lastcroncheck',datetime_convert());
|
||||
return;
|
||||
}
|
||||
|
||||
|
11
doc/hook/change_channel.bb
Normal file
11
doc/hook/change_channel.bb
Normal file
@ -0,0 +1,11 @@
|
||||
[h2]change_channel[/h2]
|
||||
|
||||
Called when entering a logged in state in a channel context (as opposed to an account context).
|
||||
The hook array provides two arguments, 'channel_id' and 'chanx'. 'chanx' is a union of the channel
|
||||
and xchan records for the now active channel.
|
||||
|
||||
Use this to capture what would traditionally be known as 'login events'. In this platform, login is
|
||||
a separate authentication activity and doesn't necessarily require "connecting to an identity", which
|
||||
is what the change_channel activity represents.
|
||||
|
||||
|
@ -73,6 +73,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
|
||||
[zrl=[baseurl]/help/hook/bb_translate_video]bb_translate_video[/zrl]
|
||||
Called when extracting embedded services from bbcode video elements (rarely used)
|
||||
|
||||
[zrl=[baseurl]/help/hook/change_channel]change_channel[/zrl]
|
||||
Called when logging in to a channel (either during login or afterward through the channel manager)
|
||||
|
||||
[zrl=[baseurl]/help/hook/channel_remove]channel_remove[/zrl]
|
||||
Called when removing a channel
|
||||
|
||||
|
@ -35,3 +35,4 @@ attach_upload_limit - maximum file upload storage (bytes)
|
||||
minimum_feedcheck_minutes - lowest setting allowed for polling rss feeds
|
||||
chatrooms - maximum chatrooms
|
||||
chatters_inroom - maximum chatters per room
|
||||
access_tokens - maximum number of Guest Access Tokens per channel
|
@ -7,8 +7,6 @@
|
||||
* @package acl_selectors
|
||||
*/
|
||||
|
||||
require_once("include/PermissionDescription.php");
|
||||
|
||||
function group_select($selname,$selclass,$preselected = false,$size = 4) {
|
||||
|
||||
$o = '';
|
||||
@ -231,7 +229,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
|
||||
if(! $emptyACL_description) {
|
||||
$showall_caption = t('Visible to your default audience');
|
||||
|
||||
} else if (is_a($emptyACL_description, 'PermissionDescription')) {
|
||||
} else if (is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) {
|
||||
$showall_caption = $emptyACL_description->get_permission_description();
|
||||
$showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : '');
|
||||
$showall_icon = $emptyACL_description->get_permission_icon();
|
||||
|
@ -36,22 +36,33 @@ function account_verify_password($email, $pass) {
|
||||
// you have to verify the email and then go through the account approval workflow before
|
||||
// letting them login.
|
||||
|
||||
if(($email_verify) && ($register_policy == REGISTER_OPEN) && ($record['account_flags'] & ACCOUNT_UNVERIFIED))
|
||||
return null;
|
||||
// @bug there is no record here
|
||||
//if(($email_verify) && ($register_policy == REGISTER_OPEN) && ($record['account_flags'] & ACCOUNT_UNVERIFIED))
|
||||
// return null;
|
||||
|
||||
$r = q("select * from account where account_email = '%s'",
|
||||
dbesc($email)
|
||||
);
|
||||
if(! ($r && count($r)))
|
||||
return null;
|
||||
if($r) {
|
||||
|
||||
foreach($r as $record) {
|
||||
if(($record['account_flags'] == ACCOUNT_OK)
|
||||
&& (hash('whirlpool', $record['account_salt'] . $pass) === $record['account_password'])) {
|
||||
logger('password verified for ' . $email);
|
||||
return $record;
|
||||
foreach($r as $record) {
|
||||
if(($record['account_flags'] == ACCOUNT_OK)
|
||||
&& (hash('whirlpool', $record['account_salt'] . $pass) === $record['account_password'])) {
|
||||
logger('password verified for ' . $email);
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$x = q("select * from atoken where atoken_name = '%s' and atoken_token = '%s' limit 1",
|
||||
dbesc($email),
|
||||
dbesc($pass)
|
||||
);
|
||||
if($x) {
|
||||
atoken_login($x[0]);
|
||||
return $x[0];
|
||||
}
|
||||
|
||||
$error = 'password failed for ' . $email;
|
||||
logger($error);
|
||||
|
||||
@ -123,10 +134,18 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
authenticate_success($x[0], true, true);
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1",
|
||||
dbesc($_SESSION['visitor_id'])
|
||||
);
|
||||
if(array_key_exists('atoken',$_SESSION)) {
|
||||
$y = q("select * from atoken where atoken_id = %d limit 1",
|
||||
intval($_SESSION['atoken'])
|
||||
);
|
||||
if($y)
|
||||
$r = array(atoken_xchan($y[0]));
|
||||
}
|
||||
else {
|
||||
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1",
|
||||
dbesc($_SESSION['visitor_id'])
|
||||
);
|
||||
}
|
||||
if($r) {
|
||||
App::set_observer($r[0]);
|
||||
}
|
||||
@ -199,20 +218,27 @@ else {
|
||||
|
||||
call_hooks('authenticate', $addon_auth);
|
||||
|
||||
$atoken = false;
|
||||
|
||||
if(($addon_auth['authenticated']) && (count($addon_auth['user_record']))) {
|
||||
$record = $addon_auth['user_record'];
|
||||
}
|
||||
else {
|
||||
$record = App::$account = account_verify_password($_POST['username'], $_POST['password']);
|
||||
$x = account_verify_password($_POST['username'], $_POST['password']);
|
||||
if(array_key_exists('atoken',$x))
|
||||
$atoken = true;
|
||||
if(! $atoken) {
|
||||
$record = App::$account = $x;
|
||||
|
||||
if(App::$account) {
|
||||
$_SESSION['account_id'] = App::$account['account_id'];
|
||||
}
|
||||
else {
|
||||
notice( t('Failed authentication') . EOL);
|
||||
}
|
||||
if(App::$account) {
|
||||
$_SESSION['account_id'] = App::$account['account_id'];
|
||||
}
|
||||
else {
|
||||
notice( t('Failed authentication') . EOL);
|
||||
}
|
||||
|
||||
logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL);
|
||||
logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
if((! $record) || (! count($record))) {
|
||||
@ -252,7 +278,8 @@ else {
|
||||
// if we haven't failed up this point, log them in.
|
||||
|
||||
$_SESSION['last_login_date'] = datetime_convert();
|
||||
authenticate_success($record, true, true);
|
||||
if(! $atoken)
|
||||
authenticate_success($record, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,6 +297,7 @@ else {
|
||||
* @return int|bool
|
||||
* Return channel_id from pconfig or false.
|
||||
*/
|
||||
|
||||
function match_openid($authid) {
|
||||
// Query the uid/channel_id from pconfig for a given value.
|
||||
$r = q("SELECT uid FROM pconfig WHERE cat = 'system' AND k = 'openid' AND v = '%s' LIMIT 1",
|
||||
|
@ -1310,13 +1310,12 @@ function get_my_address() {
|
||||
* If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already.
|
||||
* And if they aren't already authenticated here, attempt reverse magic auth.
|
||||
*
|
||||
* @param App &$a
|
||||
*
|
||||
* @hooks 'zid_init'
|
||||
* string 'zid' - their zid
|
||||
* string 'url' - the destination url
|
||||
*/
|
||||
function zid_init(&$a) {
|
||||
function zid_init() {
|
||||
$tmp_str = get_my_address();
|
||||
if(validate_email($tmp_str)) {
|
||||
Zotlabs\Daemon\Master::Summon(array('Gprobe',bin2hex($tmp_str)));
|
||||
@ -1342,6 +1341,28 @@ function zid_init(&$a) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* If somebody arrives at our site using a zat, authenticate them
|
||||
*
|
||||
*/
|
||||
|
||||
function zat_init() {
|
||||
if(local_channel() || remote_channel())
|
||||
return;
|
||||
|
||||
$r = q("select * from atoken where atoken_token = '%s' limit 1",
|
||||
dbesc($_REQUEST['zat'])
|
||||
);
|
||||
if($r) {
|
||||
atoken_login($r[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a zid parameter to a url.
|
||||
*
|
||||
|
@ -98,8 +98,8 @@ function del_aconfig($account_id, $family, $key) {
|
||||
}
|
||||
|
||||
|
||||
function load_abconfig($chan,$xhash) {
|
||||
Zlib\AbConfig::Load($chan,$xhash);
|
||||
function load_abconfig($chan, $xhash, $family = '') {
|
||||
return Zlib\AbConfig::Load($chan,$xhash,$family);
|
||||
}
|
||||
|
||||
function get_abconfig($chan,$xhash,$family,$key) {
|
||||
|
@ -4154,32 +4154,19 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo
|
||||
}
|
||||
|
||||
if($page_type) {
|
||||
|
||||
// store page info as an alternate message_id so we can access it via
|
||||
// https://sitename/page/$channelname/$pagetitle
|
||||
// if no pagetitle was given or it couldn't be transliterated into a url, use the first
|
||||
// sixteen bytes of the mid - which makes the link portable and not quite as daunting
|
||||
// as the entire mid. If it were the post_id the link would be less portable.
|
||||
|
||||
$r = q("select * from item_id where iid = %d and uid = %d and service = '%s' limit 1",
|
||||
\Zotlabs\Lib\IConfig::Set(
|
||||
intval($post_id),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($page_type)
|
||||
'system',
|
||||
$page_type,
|
||||
($pagetitle) ? $pagetitle : substr($mid,0,16),
|
||||
false
|
||||
);
|
||||
if($r) {
|
||||
q("update item_id set sid = '%s' where id = %d",
|
||||
dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)),
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
q("insert into item_id ( iid, uid, sid, service ) values ( %d, %d, '%s','%s' )",
|
||||
intval($post_id),
|
||||
intval($channel['channel_id']),
|
||||
dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)),
|
||||
dbesc($page_type)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,6 +626,7 @@ function head_get_js() {
|
||||
|
||||
$str = '';
|
||||
if(App::$js_sources) {
|
||||
ksort(App::$js_sources,SORT_NUMERIC);
|
||||
foreach(App::$js_sources as $sources) {
|
||||
if(count($sources)) {
|
||||
foreach($sources as $source) {
|
||||
|
@ -82,6 +82,44 @@ function authenticate_success($user_record, $login_initial = false, $interactive
|
||||
/* else just return */
|
||||
}
|
||||
|
||||
function atoken_login($atoken) {
|
||||
if(! $atoken)
|
||||
return false;
|
||||
|
||||
$xchan = atoken_xchan($atoken);
|
||||
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['visitor_id'] = $xchan['xchan_hash'];
|
||||
$_SESSION['atoken'] = $atoken['atoken_id'];
|
||||
|
||||
\App::set_observer($xchan);
|
||||
|
||||
return [ 'atoken' => true ];
|
||||
}
|
||||
|
||||
|
||||
function atoken_xchan($atoken) {
|
||||
|
||||
$c = channelx_by_n($atoken['atoken_uid']);
|
||||
if($c) {
|
||||
return [
|
||||
'xchan_hash' => substr($c['channel_hash'],0,16) . '.' . $atoken['atoken_name'],
|
||||
'xchan_name' => $atoken['atoken_name'],
|
||||
'xchan_addr' => t('guest:') . $atoken['atoken_name'] . '@' . \App::get_hostname(),
|
||||
'xchan_network' => 'unknown',
|
||||
'xchan_hidden' => 1,
|
||||
'xchan_photo_mimetype' => 'image/jpeg',
|
||||
'xchan_photo_l' => get_default_profile_photo(300),
|
||||
'xchan_photo_m' => get_default_profile_photo(80),
|
||||
'xchan_photo_s' => get_default_profile_photo(48)
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Change to another channel with current logged-in account.
|
||||
*
|
||||
@ -125,13 +163,17 @@ function change_channel($change_channel) {
|
||||
);
|
||||
if($x) {
|
||||
$_SESSION['my_url'] = $x[0]['xchan_url'];
|
||||
$_SESSION['my_address'] = $r[0]['channel_address'] . '@' . substr(z_root(), strpos(z_root(), '://') + 3);
|
||||
$_SESSION['my_address'] = $r[0]['channel_address'] . '@' . App::get_hostname();
|
||||
|
||||
App::set_observer($x[0]);
|
||||
App::set_perms(get_all_perms(local_channel(), $hash));
|
||||
}
|
||||
if(! is_dir('store/' . $r[0]['channel_address']))
|
||||
@os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS,true);
|
||||
|
||||
$arr = [ 'channel_id' => $change_channel, 'chanx' => $ret ];
|
||||
call_hooks('change_channel', $arr);
|
||||
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@ -687,7 +687,7 @@ function get_tags($s) {
|
||||
|
||||
// ignore anything in a code block
|
||||
|
||||
$s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
|
||||
$s = preg_replace('/\[code(.*?)\](.*?)\[\/code\]/sm','',$s);
|
||||
|
||||
// ignore anything in [style= ]
|
||||
$s = preg_replace('/\[style=(.*?)\]/sm','',$s);
|
||||
@ -774,6 +774,10 @@ function strip_zids($s) {
|
||||
return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s);
|
||||
}
|
||||
|
||||
function strip_zats($s) {
|
||||
return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s);
|
||||
}
|
||||
|
||||
|
||||
// quick and dirty quoted_printable encoding
|
||||
|
||||
|
@ -296,7 +296,7 @@ function widget_filer($arr) {
|
||||
$selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : '');
|
||||
|
||||
$terms = array();
|
||||
$r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc",
|
||||
$r = q("select distinct term from term where uid = %d and ttype = %d order by term asc",
|
||||
intval(local_channel()),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
@ -609,6 +609,15 @@ function widget_settings_menu($arr) {
|
||||
'selected' => ((argv(1) === 'oauth') ? 'active' : ''),
|
||||
);
|
||||
|
||||
if(! UNO) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Guest Access Tokens'),
|
||||
'url' => z_root() . '/settings/tokens',
|
||||
'selected' => ((argv(1) === 'tokens') ? 'active' : ''),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if($role === false || $role === 'custom') {
|
||||
$tabs[] = array(
|
||||
'label' => t('Connection Default Permissions'),
|
||||
|
@ -3014,7 +3014,12 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
||||
if($x['hubloc_host'] == App::get_hostname())
|
||||
continue;
|
||||
|
||||
$synchubs[] = $x;
|
||||
$y = q("select site_dead from site where site_url = '%s' limit 1",
|
||||
dbesc($x['hubloc_url'])
|
||||
);
|
||||
|
||||
if((! $y) || ($y[0]['site_dead'] == 0))
|
||||
$synchubs[] = $x;
|
||||
}
|
||||
|
||||
if(! $synchubs)
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `abconfig` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`chan` int(10) unsigned NOT NULL DEFAULT '',
|
||||
`chan` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`xchan` char(255) NOT NULL DEFAULT '',
|
||||
`cat` char(255) NOT NULL DEFAULT '',
|
||||
`k` char(255) NOT NULL DEFAULT '',
|
||||
@ -141,6 +141,23 @@ CREATE TABLE IF NOT EXISTS `app` (
|
||||
KEY `app_edited` (`app_edited`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `atoken` (
|
||||
`atoken_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`atoken_aid` int(11) NOT NULL DEFAULT 0,
|
||||
`atoken_uid` int(11) NOT NULL DEFAULT 0,
|
||||
`atoken_name` char(255) NOT NULL DEFAULT '',
|
||||
`atoken_token` char(255) NOT NULL DEFAULT '',
|
||||
`atoken_expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (`atoken_id`),
|
||||
KEY `atoken_aid` (`atoken_aid`),
|
||||
KEY `atoken_uid` (`atoken_uid`),
|
||||
KEY `atoken_uid_2` (`atoken_uid`),
|
||||
KEY `atoken_name` (`atoken_name`),
|
||||
KEY `atoken_token` (`atoken_token`),
|
||||
KEY `atoken_expires` (`atoken_expires`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `attach` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`aid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
|
@ -1,6 +1,6 @@
|
||||
CREATE TABLE "abconfig" (
|
||||
"id" serial NOT NULL,
|
||||
"chan" bigint NOT NULL,
|
||||
"chan" bigint NOT NULL DEFAULT '0',
|
||||
"xchan" text NOT NULL,
|
||||
"cat" text NOT NULL,
|
||||
"k" text NOT NULL,
|
||||
@ -137,6 +137,21 @@ create index "app_created" on app ("app_created");
|
||||
create index "app_edited" on app ("app_edited");
|
||||
create index "app_deleted" on app ("app_deleted");
|
||||
create index "app_system" on app ("app_system");
|
||||
|
||||
CREATE TABLE "atoken" (
|
||||
"atoken_id" serial NOT NULL,
|
||||
"atoken_aid" bigint NOT NULL DEFAULT 0,
|
||||
"atoken_uid" bigint NOT NULL DEFAULT 0,
|
||||
"atoken_name" varchar(255) NOT NULL DEFAULT '',
|
||||
"atoken_token" varchar(255) NOT NULL DEFAULT '',
|
||||
"atoken_expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
|
||||
PRIMARY KEY ("atoken_id"));
|
||||
create index atoken_aid on atoken (atoken_aid);
|
||||
create index atoken_uid on atoken (atoken_uid);
|
||||
create index atoken_name on atoken (atoken_name);
|
||||
create index atoken_token on atoken (atoken_token);
|
||||
create index atoken_expires on atoken (atoken_expires);
|
||||
|
||||
CREATE TABLE "attach" (
|
||||
"id" serial NOT NULL,
|
||||
"aid" bigint NOT NULL DEFAULT '0',
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
define( 'UPDATE_VERSION' , 1179 );
|
||||
define( 'UPDATE_VERSION' , 1180 );
|
||||
|
||||
/**
|
||||
*
|
||||
@ -2360,4 +2360,47 @@ function update_r1178() {
|
||||
if($r1)
|
||||
return UPDATE_SUCCESS;
|
||||
return UPDATE_FAILED;
|
||||
}
|
||||
|
||||
function update_r1179() {
|
||||
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$r1 = q("CREATE TABLE atoken (
|
||||
atoken_id serial NOT NULL,
|
||||
atoken_aid bigint NOT NULL DEFAULT 0,
|
||||
atoken_uid bigint NOT NULL DEFAULT 0,
|
||||
atoken_name varchar(255) NOT NULL DEFAULT '',
|
||||
atoken_token varchar(255) NOT NULL DEFAULT '',
|
||||
atoken_expires timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
|
||||
PRIMARY KEY (atoken_id)) ");
|
||||
$r2 = q("create index atoken_aid on atoken (atoken_aid)");
|
||||
$r3 = q("create index atoken_uid on atoken (atoken_uid)");
|
||||
$r4 = q("create index atoken_name on atoken (atoken_name)");
|
||||
$r5 = q("create index atoken_token on atoken (atoken_token)");
|
||||
$r6 = q("create index atoken_expires on atoken (atoken_expires)");
|
||||
|
||||
$r = $r1 && $r2 && $r3 && $r4 && $r5 && $r6;
|
||||
|
||||
}
|
||||
else {
|
||||
$r = q("CREATE TABLE IF NOT EXISTS `atoken` (
|
||||
`atoken_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`atoken_aid` int(11) NOT NULL DEFAULT 0,
|
||||
`atoken_uid` int(11) NOT NULL DEFAULT 0,
|
||||
`atoken_name` char(255) NOT NULL DEFAULT '',
|
||||
`atoken_token` char(255) NOT NULL DEFAULT '',
|
||||
`atoken_expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (`atoken_id`),
|
||||
KEY `atoken_aid` (`atoken_aid`),
|
||||
KEY `atoken_uid` (`atoken_uid`),
|
||||
KEY `atoken_name` (`atoken_name`),
|
||||
KEY `atoken_token` (`atoken_token`),
|
||||
KEY `atoken_expires` (`atoken_expires`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ");
|
||||
}
|
||||
if($r)
|
||||
return UPDATE_SUCCESS;
|
||||
return UPDATE_FAILED;
|
||||
|
||||
|
||||
}
|
4231
util/hmessages.po
4231
util/hmessages.po
File diff suppressed because it is too large
Load Diff
@ -56,7 +56,7 @@ if($argc == 3) {
|
||||
echo "service_class $oclass\t\t\033[1m" . $argv[2] . "\033[0m\n";
|
||||
|
||||
$new = get_config('service_class', $argv[2]);
|
||||
foreach(array('photo_upload_limit','total_items','total_pages','total_identities','total_channels','total_feeds','attach_upload_limit','minimum_feedcheck_minutes','chatrooms','chatters_inroom') as $prop) {
|
||||
foreach(array('photo_upload_limit','total_items','total_pages','total_identities','total_channels','total_feeds','attach_upload_limit','minimum_feedcheck_minutes','chatrooms','chatters_inroom','access_tokens') as $prop) {
|
||||
echo $prop . str_repeat(' ',26 - strlen($prop)) . (($old && $old[$prop]) ? $old[$prop] : 'unlimited') . "\t\t\033[1m" . (($new && $new[$prop]) ? $new[$prop] : 'unlimited') . "\033[0m\n";
|
||||
}
|
||||
$r = '';
|
||||
|
4
view/css/bootstrap-red.css
vendored
4
view/css/bootstrap-red.css
vendored
@ -5,6 +5,7 @@
|
||||
nav .badge {
|
||||
position: relative;
|
||||
top: -49px;
|
||||
left: 2px;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
line-height: 20px;
|
||||
@ -59,7 +60,8 @@ aside .nav-pills > li > a,
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.wall-item-tools .dropdown-menu {
|
||||
.wall-item-tools .dropdown-menu,
|
||||
.section-title-wrapper .dropdown-menu {
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ a.wall-item-name-link {
|
||||
}
|
||||
|
||||
.wall-item-content {
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wall-item-content h1,
|
||||
@ -316,4 +316,4 @@ code.inline-code {
|
||||
img.smiley.emoji:hover {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
@ -30,5 +30,5 @@
|
||||
}
|
||||
|
||||
.directory-collapse {
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -7,5 +7,22 @@
|
||||
}
|
||||
|
||||
.channel-menu {
|
||||
margin-top: 24px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.zat-example {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#atoken-index {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#atoken-index td:nth-child(1){
|
||||
padding: 7px 3px 7px 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.atoken-index-tool {
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Red people autocomplete
|
||||
* general autocomplete support
|
||||
*
|
||||
* require jQuery, jquery.textcomplete
|
||||
*/
|
||||
|
@ -1,511 +0,0 @@
|
||||
/*!
|
||||
* jQuery Migrate - v1.1.1 - 2013-02-16
|
||||
* https://github.com/jquery/jquery-migrate
|
||||
* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
|
||||
*/
|
||||
(function( jQuery, window, undefined ) {
|
||||
// See http://bugs.jquery.com/ticket/13335
|
||||
// "use strict";
|
||||
|
||||
|
||||
var warnedAbout = {};
|
||||
|
||||
// List of warnings already given; public read only
|
||||
jQuery.migrateWarnings = [];
|
||||
|
||||
// Set to true to prevent console output; migrateWarnings still maintained
|
||||
// jQuery.migrateMute = false;
|
||||
|
||||
// Show a message on the console so devs know we're active
|
||||
if ( !jQuery.migrateMute && window.console && console.log ) {
|
||||
console.log("JQMIGRATE: Logging is active");
|
||||
}
|
||||
|
||||
// Set to false to disable traces that appear with warnings
|
||||
if ( jQuery.migrateTrace === undefined ) {
|
||||
jQuery.migrateTrace = true;
|
||||
}
|
||||
|
||||
// Forget any warnings we've already given; public
|
||||
jQuery.migrateReset = function() {
|
||||
warnedAbout = {};
|
||||
jQuery.migrateWarnings.length = 0;
|
||||
};
|
||||
|
||||
function migrateWarn( msg) {
|
||||
if ( !warnedAbout[ msg ] ) {
|
||||
warnedAbout[ msg ] = true;
|
||||
jQuery.migrateWarnings.push( msg );
|
||||
if ( window.console && console.warn && !jQuery.migrateMute ) {
|
||||
console.warn( "JQMIGRATE: " + msg );
|
||||
if ( jQuery.migrateTrace && console.trace ) {
|
||||
console.trace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function migrateWarnProp( obj, prop, value, msg ) {
|
||||
if ( Object.defineProperty ) {
|
||||
// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
|
||||
// allow property to be overwritten in case some other plugin wants it
|
||||
try {
|
||||
Object.defineProperty( obj, prop, {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
migrateWarn( msg );
|
||||
return value;
|
||||
},
|
||||
set: function( newValue ) {
|
||||
migrateWarn( msg );
|
||||
value = newValue;
|
||||
}
|
||||
});
|
||||
return;
|
||||
} catch( err ) {
|
||||
// IE8 is a dope about Object.defineProperty, can't warn there
|
||||
}
|
||||
}
|
||||
|
||||
// Non-ES5 (or broken) browser; just set the property
|
||||
jQuery._definePropertyBroken = true;
|
||||
obj[ prop ] = value;
|
||||
}
|
||||
|
||||
if ( document.compatMode === "BackCompat" ) {
|
||||
// jQuery has never supported or tested Quirks Mode
|
||||
migrateWarn( "jQuery is not compatible with Quirks Mode" );
|
||||
}
|
||||
|
||||
|
||||
var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
|
||||
oldAttr = jQuery.attr,
|
||||
valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
|
||||
function() { return null; },
|
||||
valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
|
||||
function() { return undefined; },
|
||||
rnoType = /^(?:input|button)$/i,
|
||||
rnoAttrNodeType = /^[238]$/,
|
||||
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
|
||||
ruseDefault = /^(?:checked|selected)$/i;
|
||||
|
||||
// jQuery.attrFn
|
||||
migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
|
||||
|
||||
jQuery.attr = function( elem, name, value, pass ) {
|
||||
var lowerName = name.toLowerCase(),
|
||||
nType = elem && elem.nodeType;
|
||||
|
||||
if ( pass ) {
|
||||
// Since pass is used internally, we only warn for new jQuery
|
||||
// versions where there isn't a pass arg in the formal params
|
||||
if ( oldAttr.length < 4 ) {
|
||||
migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
|
||||
}
|
||||
if ( elem && !rnoAttrNodeType.test( nType ) &&
|
||||
(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
|
||||
return jQuery( elem )[ name ]( value );
|
||||
}
|
||||
}
|
||||
|
||||
// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
|
||||
// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
|
||||
if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
|
||||
migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
|
||||
}
|
||||
|
||||
// Restore boolHook for boolean property/attribute synchronization
|
||||
if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
|
||||
jQuery.attrHooks[ lowerName ] = {
|
||||
get: function( elem, name ) {
|
||||
// Align boolean attributes with corresponding properties
|
||||
// Fall back to attribute presence where some booleans are not supported
|
||||
var attrNode,
|
||||
property = jQuery.prop( elem, name );
|
||||
return property === true || typeof property !== "boolean" &&
|
||||
( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
|
||||
|
||||
name.toLowerCase() :
|
||||
undefined;
|
||||
},
|
||||
set: function( elem, value, name ) {
|
||||
var propName;
|
||||
if ( value === false ) {
|
||||
// Remove boolean attributes when set to false
|
||||
jQuery.removeAttr( elem, name );
|
||||
} else {
|
||||
// value is true since we know at this point it's type boolean and not false
|
||||
// Set boolean attributes to the same name and set the DOM property
|
||||
propName = jQuery.propFix[ name ] || name;
|
||||
if ( propName in elem ) {
|
||||
// Only set the IDL specifically if it already exists on the element
|
||||
elem[ propName ] = true;
|
||||
}
|
||||
|
||||
elem.setAttribute( name, name.toLowerCase() );
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
// Warn only for attributes that can remain distinct from their properties post-1.9
|
||||
if ( ruseDefault.test( lowerName ) ) {
|
||||
migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
|
||||
}
|
||||
}
|
||||
|
||||
return oldAttr.call( jQuery, elem, name, value );
|
||||
};
|
||||
|
||||
// attrHooks: value
|
||||
jQuery.attrHooks.value = {
|
||||
get: function( elem, name ) {
|
||||
var nodeName = ( elem.nodeName || "" ).toLowerCase();
|
||||
if ( nodeName === "button" ) {
|
||||
return valueAttrGet.apply( this, arguments );
|
||||
}
|
||||
if ( nodeName !== "input" && nodeName !== "option" ) {
|
||||
migrateWarn("jQuery.fn.attr('value') no longer gets properties");
|
||||
}
|
||||
return name in elem ?
|
||||
elem.value :
|
||||
null;
|
||||
},
|
||||
set: function( elem, value ) {
|
||||
var nodeName = ( elem.nodeName || "" ).toLowerCase();
|
||||
if ( nodeName === "button" ) {
|
||||
return valueAttrSet.apply( this, arguments );
|
||||
}
|
||||
if ( nodeName !== "input" && nodeName !== "option" ) {
|
||||
migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
|
||||
}
|
||||
// Does not return so that setAttribute is also used
|
||||
elem.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var matched, browser,
|
||||
oldInit = jQuery.fn.init,
|
||||
oldParseJSON = jQuery.parseJSON,
|
||||
// Note this does NOT include the #9521 XSS fix from 1.7!
|
||||
rquickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*|#([\w\-]*))$/;
|
||||
|
||||
// $(html) "looks like html" rule change
|
||||
jQuery.fn.init = function( selector, context, rootjQuery ) {
|
||||
var match;
|
||||
|
||||
if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
|
||||
(match = rquickExpr.exec( selector )) && match[1] ) {
|
||||
// This is an HTML string according to the "old" rules; is it still?
|
||||
if ( selector.charAt( 0 ) !== "<" ) {
|
||||
migrateWarn("$(html) HTML strings must start with '<' character");
|
||||
}
|
||||
// Now process using loose rules; let pre-1.8 play too
|
||||
if ( context && context.context ) {
|
||||
// jQuery object as context; parseHTML expects a DOM object
|
||||
context = context.context;
|
||||
}
|
||||
if ( jQuery.parseHTML ) {
|
||||
return oldInit.call( this, jQuery.parseHTML( jQuery.trim(selector), context, true ),
|
||||
context, rootjQuery );
|
||||
}
|
||||
}
|
||||
return oldInit.apply( this, arguments );
|
||||
};
|
||||
jQuery.fn.init.prototype = jQuery.fn;
|
||||
|
||||
// Let $.parseJSON(falsy_value) return null
|
||||
jQuery.parseJSON = function( json ) {
|
||||
if ( !json && json !== null ) {
|
||||
migrateWarn("jQuery.parseJSON requires a valid JSON string");
|
||||
return null;
|
||||
}
|
||||
return oldParseJSON.apply( this, arguments );
|
||||
};
|
||||
|
||||
jQuery.uaMatch = function( ua ) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
|
||||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
|
||||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
|
||||
/(msie) ([\w.]+)/.exec( ua ) ||
|
||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
browser: match[ 1 ] || "",
|
||||
version: match[ 2 ] || "0"
|
||||
};
|
||||
};
|
||||
|
||||
// Don't clobber any existing jQuery.browser in case it's different
|
||||
if ( !jQuery.browser ) {
|
||||
matched = jQuery.uaMatch( navigator.userAgent );
|
||||
browser = {};
|
||||
|
||||
if ( matched.browser ) {
|
||||
browser[ matched.browser ] = true;
|
||||
browser.version = matched.version;
|
||||
}
|
||||
|
||||
// Chrome is Webkit, but Webkit is also Safari.
|
||||
if ( browser.chrome ) {
|
||||
browser.webkit = true;
|
||||
} else if ( browser.webkit ) {
|
||||
browser.safari = true;
|
||||
}
|
||||
|
||||
jQuery.browser = browser;
|
||||
}
|
||||
|
||||
// Warn if the code tries to get jQuery.browser
|
||||
migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
|
||||
|
||||
jQuery.sub = function() {
|
||||
function jQuerySub( selector, context ) {
|
||||
return new jQuerySub.fn.init( selector, context );
|
||||
}
|
||||
jQuery.extend( true, jQuerySub, this );
|
||||
jQuerySub.superclass = this;
|
||||
jQuerySub.fn = jQuerySub.prototype = this();
|
||||
jQuerySub.fn.constructor = jQuerySub;
|
||||
jQuerySub.sub = this.sub;
|
||||
jQuerySub.fn.init = function init( selector, context ) {
|
||||
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
|
||||
context = jQuerySub( context );
|
||||
}
|
||||
|
||||
return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
|
||||
};
|
||||
jQuerySub.fn.init.prototype = jQuerySub.fn;
|
||||
var rootjQuerySub = jQuerySub(document);
|
||||
migrateWarn( "jQuery.sub() is deprecated" );
|
||||
return jQuerySub;
|
||||
};
|
||||
|
||||
|
||||
// Ensure that $.ajax gets the new parseJSON defined in core.js
|
||||
jQuery.ajaxSetup({
|
||||
converters: {
|
||||
"text json": jQuery.parseJSON
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var oldFnData = jQuery.fn.data;
|
||||
|
||||
jQuery.fn.data = function( name ) {
|
||||
var ret, evt,
|
||||
elem = this[0];
|
||||
|
||||
// Handles 1.7 which has this behavior and 1.8 which doesn't
|
||||
if ( elem && name === "events" && arguments.length === 1 ) {
|
||||
ret = jQuery.data( elem, name );
|
||||
evt = jQuery._data( elem, name );
|
||||
if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
|
||||
migrateWarn("Use of jQuery.fn.data('events') is deprecated");
|
||||
return evt;
|
||||
}
|
||||
}
|
||||
return oldFnData.apply( this, arguments );
|
||||
};
|
||||
|
||||
|
||||
var rscriptType = /\/(java|ecma)script/i,
|
||||
oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
|
||||
|
||||
jQuery.fn.andSelf = function() {
|
||||
migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
|
||||
return oldSelf.apply( this, arguments );
|
||||
};
|
||||
|
||||
// Since jQuery.clean is used internally on older versions, we only shim if it's missing
|
||||
if ( !jQuery.clean ) {
|
||||
jQuery.clean = function( elems, context, fragment, scripts ) {
|
||||
// Set context per 1.8 logic
|
||||
context = context || document;
|
||||
context = !context.nodeType && context[0] || context;
|
||||
context = context.ownerDocument || context;
|
||||
|
||||
migrateWarn("jQuery.clean() is deprecated");
|
||||
|
||||
var i, elem, handleScript, jsTags,
|
||||
ret = [];
|
||||
|
||||
jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
|
||||
|
||||
// Complex logic lifted directly from jQuery 1.8
|
||||
if ( fragment ) {
|
||||
// Special handling of each script element
|
||||
handleScript = function( elem ) {
|
||||
// Check if we consider it executable
|
||||
if ( !elem.type || rscriptType.test( elem.type ) ) {
|
||||
// Detach the script and store it in the scripts array (if provided) or the fragment
|
||||
// Return truthy to indicate that it has been handled
|
||||
return scripts ?
|
||||
scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
|
||||
fragment.appendChild( elem );
|
||||
}
|
||||
};
|
||||
|
||||
for ( i = 0; (elem = ret[i]) != null; i++ ) {
|
||||
// Check if we're done after handling an executable script
|
||||
if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
|
||||
// Append to fragment and handle embedded scripts
|
||||
fragment.appendChild( elem );
|
||||
if ( typeof elem.getElementsByTagName !== "undefined" ) {
|
||||
// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
|
||||
jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
|
||||
|
||||
// Splice the scripts into ret after their former ancestor and advance our index beyond them
|
||||
ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
|
||||
i += jsTags.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
var eventAdd = jQuery.event.add,
|
||||
eventRemove = jQuery.event.remove,
|
||||
eventTrigger = jQuery.event.trigger,
|
||||
oldToggle = jQuery.fn.toggle,
|
||||
oldLive = jQuery.fn.live,
|
||||
oldDie = jQuery.fn.die,
|
||||
ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
|
||||
rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
|
||||
rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
|
||||
hoverHack = function( events ) {
|
||||
if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
|
||||
return events;
|
||||
}
|
||||
if ( rhoverHack.test( events ) ) {
|
||||
migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
|
||||
}
|
||||
return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
|
||||
};
|
||||
|
||||
// Event props removed in 1.9, put them back if needed; no practical way to warn them
|
||||
if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
|
||||
jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
|
||||
}
|
||||
|
||||
// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
|
||||
if ( jQuery.event.dispatch ) {
|
||||
migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
|
||||
}
|
||||
|
||||
// Support for 'hover' pseudo-event and ajax event warnings
|
||||
jQuery.event.add = function( elem, types, handler, data, selector ){
|
||||
if ( elem !== document && rajaxEvent.test( types ) ) {
|
||||
migrateWarn( "AJAX events should be attached to document: " + types );
|
||||
}
|
||||
eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
|
||||
};
|
||||
jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
|
||||
eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
|
||||
};
|
||||
|
||||
jQuery.fn.error = function() {
|
||||
var args = Array.prototype.slice.call( arguments, 0);
|
||||
migrateWarn("jQuery.fn.error() is deprecated");
|
||||
args.splice( 0, 0, "error" );
|
||||
if ( arguments.length ) {
|
||||
return this.bind.apply( this, args );
|
||||
}
|
||||
// error event should not bubble to window, although it does pre-1.7
|
||||
this.triggerHandler.apply( this, args );
|
||||
return this;
|
||||
};
|
||||
|
||||
jQuery.fn.toggle = function( fn, fn2 ) {
|
||||
|
||||
// Don't mess with animation or css toggles
|
||||
if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
|
||||
return oldToggle.apply( this, arguments );
|
||||
}
|
||||
migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
|
||||
|
||||
// Save reference to arguments for access in closure
|
||||
var args = arguments,
|
||||
guid = fn.guid || jQuery.guid++,
|
||||
i = 0,
|
||||
toggler = function( event ) {
|
||||
// Figure out which function to execute
|
||||
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
|
||||
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
|
||||
|
||||
// Make sure that clicks stop
|
||||
event.preventDefault();
|
||||
|
||||
// and execute the function
|
||||
return args[ lastToggle ].apply( this, arguments ) || false;
|
||||
};
|
||||
|
||||
// link all the functions, so any of them can unbind this click handler
|
||||
toggler.guid = guid;
|
||||
while ( i < args.length ) {
|
||||
args[ i++ ].guid = guid;
|
||||
}
|
||||
|
||||
return this.click( toggler );
|
||||
};
|
||||
|
||||
jQuery.fn.live = function( types, data, fn ) {
|
||||
migrateWarn("jQuery.fn.live() is deprecated");
|
||||
if ( oldLive ) {
|
||||
return oldLive.apply( this, arguments );
|
||||
}
|
||||
jQuery( this.context ).on( types, this.selector, data, fn );
|
||||
return this;
|
||||
};
|
||||
|
||||
jQuery.fn.die = function( types, fn ) {
|
||||
migrateWarn("jQuery.fn.die() is deprecated");
|
||||
if ( oldDie ) {
|
||||
return oldDie.apply( this, arguments );
|
||||
}
|
||||
jQuery( this.context ).off( types, this.selector || "**", fn );
|
||||
return this;
|
||||
};
|
||||
|
||||
// Turn global events into document-triggered events
|
||||
jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
|
||||
if ( !elem && !rajaxEvent.test( event ) ) {
|
||||
migrateWarn( "Global events are undocumented and deprecated" );
|
||||
}
|
||||
return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
|
||||
};
|
||||
jQuery.each( ajaxEvents.split("|"),
|
||||
function( _, name ) {
|
||||
jQuery.event.special[ name ] = {
|
||||
setup: function() {
|
||||
var elem = this;
|
||||
|
||||
// The document needs no shimming; must be !== for oldIE
|
||||
if ( elem !== document ) {
|
||||
jQuery.event.add( document, name + "." + jQuery.guid, function() {
|
||||
jQuery.event.trigger( name, null, elem, true );
|
||||
});
|
||||
jQuery._data( this, name, jQuery.guid++ );
|
||||
}
|
||||
return false;
|
||||
},
|
||||
teardown: function() {
|
||||
if ( this !== document ) {
|
||||
jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
})( jQuery, window );
|
8
view/js/jquery.js
vendored
8
view/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
2
view/js/jquery.migrate-3.0.0.js
Normal file
2
view/js/jquery.migrate-3.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -283,12 +283,13 @@ $(function() {
|
||||
/* Turn elements with one of our special rel tags into popup menus */
|
||||
/* CHANGES: let bootstrap handle popups and only do the loading here */
|
||||
|
||||
$('a[rel^=#]').click(function(e){
|
||||
|
||||
$('a[rel^="#"]').click(function(e){
|
||||
manage_popup_menu(this, e);
|
||||
return;
|
||||
});
|
||||
|
||||
$('span[rel^=#]').click(function(e){
|
||||
$('span[rel^="#"]').click(function(e){
|
||||
manage_popup_menu(this, e);
|
||||
return;
|
||||
});
|
||||
@ -639,7 +640,7 @@ function updateConvItems(mode,data) {
|
||||
var bimgcount = bimgs.length;
|
||||
|
||||
if (bimgcount) {
|
||||
bimgs.load(function() {
|
||||
bimgs.on('load',function() {
|
||||
bimgcount--;
|
||||
if (! bimgcount) {
|
||||
collapseHeight();
|
||||
@ -652,7 +653,7 @@ function updateConvItems(mode,data) {
|
||||
}
|
||||
|
||||
function collapseHeight() {
|
||||
var origContentHeight = parseInt($("#region_2").height());
|
||||
var origContentHeight = Math.ceil($("#region_2").height());
|
||||
var cDiff = 0;
|
||||
var i = 0;
|
||||
var position = $(window).scrollTop();
|
||||
@ -662,25 +663,19 @@ function collapseHeight() {
|
||||
if(orgHeight > divmore_height) {
|
||||
if(! $(this).hasClass('divmore')) {
|
||||
|
||||
//var trigger = $(window).scrollTop() < $(this).offset().top ? true : false;
|
||||
//console.log($(this).offset().top + divmore_height - $(window).scrollTop() + cDiff - ($(".divgrow-showmore").outerHeight() * i));
|
||||
|
||||
// check if we will collapse some content above the visible content and compensate the diff later
|
||||
if($(this).offset().top + divmore_height - $(window).scrollTop() + cDiff - ($(".divgrow-showmore").outerHeight() * i) < 65) {
|
||||
//$(this).css('color', 'red');
|
||||
//console.log($(this).offset().top + divmore_height + ' / ' + $(window).scrollTop());
|
||||
diff = orgHeight - divmore_height;
|
||||
cDiff = cDiff + diff;
|
||||
i++;
|
||||
}
|
||||
|
||||
//if(trigger) {
|
||||
$(this).readmore({
|
||||
speed: 0,
|
||||
heightMargin: 50,
|
||||
collapsedHeight: divmore_height,
|
||||
moreLink: '<a href="#" class="divgrow-showmore">' + aStr.divgrowmore + '</a>',
|
||||
lessLink: '<a href="#" class="divgrow-showmore">' + aStr.divgrowless + '</a>',
|
||||
moreLink: '<a href="#" class="divgrow-showmore fakelink">' + aStr.divgrowmore + '</a>',
|
||||
lessLink: '<a href="#" class="divgrow-showmore fakelink">' + aStr.divgrowless + '</a>',
|
||||
beforeToggle: function(trigger, element, expanded) {
|
||||
if(expanded) {
|
||||
if((($(element).offset().top + divmore_height) - $(window).scrollTop()) < 65 ) {
|
||||
@ -690,12 +685,11 @@ function collapseHeight() {
|
||||
}
|
||||
});
|
||||
$(this).addClass('divmore');
|
||||
//}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var collapsedContentHeight = parseInt($("#region_2").height());
|
||||
var collapsedContentHeight = Math.ceil($("#region_2").height());
|
||||
contentHeightDiff = origContentHeight - collapsedContentHeight;
|
||||
console.log('collapseHeight() - contentHeightDiff: ' + contentHeightDiff + 'px');
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
$(document).ready(function() {
|
||||
$("#recip").name_autocomplete(baseurl + '/acl', '', false, function(data) {
|
||||
$("#recip").name_autocomplete(baseurl + '/acl', 'm', false, function(data) {
|
||||
$("#recip-complete").val(data.xid);
|
||||
});
|
||||
$(".autotime").timeago()
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
|
||||
$("#photo-edit-newtag").contact_autocomplete(baseurl + '/acl', 'p', false, function(data) {
|
||||
$("#photo-edit-newtag").contact_autocomplete(baseurl + '/acl', 'a', false, function(data) {
|
||||
$("#photo-edit-newtag").val('@' + data.name);
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
$(document).ready(function() {
|
||||
$('form').areYouSure({'addRemoveFieldsMarksDirty':true, 'message': aStr['leavethispage'] }); // Warn user about unsaved settings
|
||||
|
||||
$('.token-mirror').html($('#id_token').val());
|
||||
$('#id_token').keyup( function() { $('.token-mirror').html($('#id_token').val()); });
|
||||
|
||||
$("#id_permissions_role").change(function() {
|
||||
var role = $("#id_permissions_role").val();
|
||||
if(role == 'custom')
|
||||
|
@ -13,7 +13,7 @@ head_add_css('library/justifiedGallery/justifiedGallery.min.css');
|
||||
head_add_css('library/Text_Highlighter/sample.css');
|
||||
|
||||
head_add_js('jquery.js');
|
||||
//head_add_js('jquery-migrate-1.1.1.js');
|
||||
//head_add_js('jquery.migrate-3.0.0.js');
|
||||
head_add_js('library/justifiedGallery/jquery.justifiedGallery.min.js');
|
||||
head_add_js('library/sprintf.js/dist/sprintf.min.js');
|
||||
|
||||
|
@ -1416,9 +1416,6 @@ img.mail-conv-sender-photo {
|
||||
display: block;
|
||||
border-top: 1px dashed #ccc;
|
||||
text-align: center;
|
||||
font-size: $body_font_size;
|
||||
color: $link_colour;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.divgrow-showmore:hover {
|
||||
@ -1658,6 +1655,7 @@ main.fullscreen .section-content-wrapper-np {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.atoken-index-row:hover td,
|
||||
.chatroom-index-row:hover td,
|
||||
.locs-index-row:hover td,
|
||||
[id^="cloud-index-"]:hover td,
|
||||
|
@ -56,13 +56,14 @@ $(document).ready(function() {
|
||||
function makeFullScreen(full) {
|
||||
if(typeof full=='undefined' || full == true) {
|
||||
$('main').css({'transition': 'none'}).addClass('fullscreen');
|
||||
$('#fullscreen-btn, header, nav, aside, #tabs-collapse-1').css({'visibility': 'hidden'});
|
||||
$('header, nav, aside, #fullscreen-btn').hide();
|
||||
$('#tabs-collapse-1').css({'visibility': 'hidden'});
|
||||
$('#inline-btn').show();
|
||||
|
||||
}
|
||||
else {
|
||||
$('main').removeClass('fullscreen');
|
||||
$('#fullscreen-btn, header, nav, aside, #tabs-collapse-1').css({'visibility': ''});
|
||||
$('header, nav, aside, #fullscreen-btn').show();
|
||||
$('#tabs-collapse-1').css({'visibility': ''});
|
||||
$('#inline-btn').hide();
|
||||
$('main').css({'transition': ''});
|
||||
}
|
||||
|
@ -153,6 +153,18 @@ if(file_exists('view/theme/redbasic/css/style.css')) {
|
||||
|
||||
$x = file_get_contents('view/theme/redbasic/css/style.css');
|
||||
|
||||
if($narrow_navbar && file_exists('view/theme/redbasic/css/narrow_navbar.css')) {
|
||||
$x .= file_get_contents('view/theme/redbasic/css/narrow_navbar.css');
|
||||
}
|
||||
|
||||
if($align_left && file_exists('view/theme/redbasic/css/align_left.css')) {
|
||||
$x .= file_get_contents('view/theme/redbasic/css/align_left.css');
|
||||
}
|
||||
|
||||
if($schemecss) {
|
||||
$x .= $schemecss;
|
||||
}
|
||||
|
||||
$aside_width = 287;
|
||||
|
||||
// left aside and right aside are 285px + converse width
|
||||
@ -204,18 +216,6 @@ if(file_exists('view/theme/redbasic/css/style.css')) {
|
||||
|
||||
}
|
||||
|
||||
if($narrow_navbar && file_exists('view/theme/redbasic/css/narrow_navbar.css')) {
|
||||
echo file_get_contents('view/theme/redbasic/css/narrow_navbar.css');
|
||||
}
|
||||
|
||||
if($align_left && file_exists('view/theme/redbasic/css/align_left.css')) {
|
||||
echo file_get_contents('view/theme/redbasic/css/align_left.css');
|
||||
}
|
||||
|
||||
if($schemecss) {
|
||||
echo $schemecss;
|
||||
}
|
||||
|
||||
// Set the schema to the default schema in derived themes. See the documentation for creating derived themes how to override this.
|
||||
|
||||
if(local_channel() && App::$channel && App::$channel['channel_theme'] != 'redbasic')
|
||||
|
@ -1,8 +1,6 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(); adjustFullscreenTopBarHeight();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false); adjustInlineTopBarHeight();"><i class="fa fa-compress"></i></button>
|
||||
{{if $is_owner}}
|
||||
<form id="chat-destroy" method="post" action="chat">
|
||||
<input type="hidden" name="room_name" value="{{$room_name}}" />
|
||||
@ -10,6 +8,8 @@
|
||||
<button class="btn btn-danger btn-xs" type="submit" name="submit" value="{{$drop}}" onclick="return confirmDelete();"><i class="fa fa-trash-o"></i> {{$drop}}</button>
|
||||
</form>
|
||||
{{/if}}
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(); adjustFullscreenTopBarHeight();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false); adjustInlineTopBarHeight();"><i class="fa fa-compress"></i></button>
|
||||
</div>
|
||||
<h2>{{$room_name}}</h2>
|
||||
<div class="clear"></div>
|
||||
|
@ -11,4 +11,3 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
|
@ -1,8 +1,17 @@
|
||||
<script>
|
||||
var aside_padding_top;
|
||||
var section_padding_top;
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
aside_padding_top = parseInt($('aside').css('padding-top'));
|
||||
section_padding_top = parseInt($('section').css('padding-top'));
|
||||
|
||||
if($('#cover-photo').length && $(window).width() > 755) {
|
||||
$('.navbar-fixed-top').css('position', 'relative');
|
||||
$('aside, section').css('padding-top', 0 + 'px');
|
||||
$('main').css('margin-top', - $('nav').outerHeight(true) + 'px');
|
||||
$('aside').css('padding-top', aside_padding_top - $('nav').outerHeight() + 'px');
|
||||
$('section').css('padding-top', section_padding_top - $('nav').outerHeight() + 'px');
|
||||
$('main').css('opacity', 0);
|
||||
$('header').hide();
|
||||
}
|
||||
@ -15,9 +24,11 @@
|
||||
if($('#cover-photo').length && $(window).width() > 755 && $(window).scrollTop() >= $('#cover-photo').height()) {
|
||||
$('header').fadeIn();
|
||||
$('main').css('opacity', 1);
|
||||
$('aside, section').css('padding-top', $('nav').outerHeight(true) + 'px');
|
||||
$('aside').css('padding-top', aside_padding_top + 'px');
|
||||
$('section').css('padding-top', section_padding_top + 'px');
|
||||
$(window).scrollTop($(window).scrollTop() - $('#cover-photo').height())
|
||||
$('.navbar-fixed-top').css('position', 'fixed');
|
||||
$('main').css('margin-top', '');
|
||||
$('#cover-photo').remove();
|
||||
}
|
||||
if($('#cover-photo').length) {
|
||||
@ -28,7 +39,8 @@
|
||||
$(window).resize(function () {
|
||||
if($('#cover-photo').length && $(window).width() < 755) {
|
||||
$('main').css('opacity', 1);
|
||||
$('aside, section').css('padding-top', $('nav').outerHeight(true) + 'px');
|
||||
$('aside').css('padding-top', aside_padding_top + 'px');
|
||||
$('section').css('padding-top', section_padding_top + 'px');
|
||||
$('.navbar-fixed-top').css('position', 'fixed');
|
||||
$('#cover-photo').remove();
|
||||
}
|
||||
@ -36,7 +48,7 @@
|
||||
});
|
||||
|
||||
function slideUpCover() {
|
||||
$('html, body').animate({scrollTop: $('#cover-photo').height() + 'px'});
|
||||
$('html, body').animate({scrollTop: Math.ceil($('#cover-photo').height()) + 'px' });
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<div class="dropdown">
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><i class="fa fa-caret-down"></i> {{$view_label}}</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#" onclick="changeView('changeView', 'month'); return false;">{{$month}}</a></li>
|
||||
@ -16,6 +14,8 @@
|
||||
<button id="events-spinner" class="btn btn-default btn-xs" onclick="changeView('today', false);" title="{{$today}}"><i class="fa fa-bullseye"></i></button>
|
||||
<button class="btn btn-default btn-xs" onclick="changeView('next', false);" title="{{$next}}"><i class="fa fa-forward"></i></button>
|
||||
</div>
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<h2 id="title"></h2>
|
||||
|
@ -2,13 +2,13 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-default btn-xs" onclick="changeView('prev', false);" title="{{$prev}}"><i class="fa fa-backward"></i></button>
|
||||
<button id="events-spinner" class="btn btn-default btn-xs" onclick="changeView('today', false);" title="{{$today}}"><i class="fa fa-bullseye"></i></button>
|
||||
<button class="btn btn-default btn-xs" onclick="changeView('next', false);" title="{{$next}}"><i class="fa fa-forward"></i></button>
|
||||
</div>
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
</div>
|
||||
<h2 id="title"></h2>
|
||||
<div class="clear"></div>
|
||||
|
@ -1,8 +1,6 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
{{if $order}}
|
||||
<a class="btn btn-default btn-xs" href="{{$order.1}}" title="{{$order.0}}"><i class="fa fa-sort"></i></a>
|
||||
{{/if}}
|
||||
@ -14,6 +12,10 @@
|
||||
<button class="btn btn-xs btn-success btn-xs" title="{{$usage}}" onclick="openClose('photo-upload-form'); closeMenu('photo-album-edit-wrapper');"><i class="fa fa-arrow-circle-o-up"></i> {{$upload.0}}</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{if !$no_fullscreen_btn}}
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
{{/if}}
|
||||
</div>
|
||||
<h2>{{$album}}</h2>
|
||||
<div class="clear"></div>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
{{if $can_post}}
|
||||
<button class="btn btn-xs btn-success" title="{{$usage}}" onclick="openClose('photo-upload-form');"><i class="fa fa-arrow-circle-o-up"></i> {{$upload.0}}</button>
|
||||
{{/if}}
|
||||
<button id="fullscreen-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
|
||||
<button id="inline-btn" type="button" class="btn btn-default btn-xs" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
|
||||
</div>
|
||||
<h2>{{$title}}</h2>
|
||||
<div class="clear"></div>
|
||||
|
40
view/tpl/settings_tokens.tpl
Normal file
40
view/tpl/settings_tokens.tpl
Normal file
@ -0,0 +1,40 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<h2>{{$title}}</h2>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="section-content-tools-wrapper">
|
||||
<div class="section-content-info-wrapper">
|
||||
{{$desc}}
|
||||
</div>
|
||||
|
||||
<form action="settings/tokens" id="settings-account-form" method="post" autocomplete="off" >
|
||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||
{{if $atoken}}<input type="hidden" name="atoken_id" value="{{$atoken.atoken_id}}" />{{/if}}
|
||||
{{include file="field_input.tpl" field=$name}}
|
||||
{{include file="field_input.tpl" field=$token}}
|
||||
{{include file="field_input.tpl" field=$expires}}
|
||||
<div class="settings-submit-wrapper form-group">
|
||||
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="descriptive-text">{{$desc2}}</div>
|
||||
<ul>
|
||||
<li>{{$url1}}<span class="zat-example">?f=&zat=<span class="token-mirror"></span></span></li>
|
||||
<li>{{$url2}}<span class="zat-example">?f=&zat=<span class="token-mirror"></span></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{if $tokens}}
|
||||
<div class="section-content-wrapper-np">
|
||||
<table id="atoken-index">
|
||||
{{foreach $tokens as $t}}
|
||||
<tr id="atoken-index-{{$t.atoken_id}}" class="atoken-index-row">
|
||||
<td width="99%"><a href="settings/tokens/{{$t.atoken_id}}">{{$t.atoken_name}}</a></td>
|
||||
<td width="1%" class="atoken-index-tool"><i class="fa fa-trash-o drop-icons" onClick="dropItem('/settings/tokens/{{$t.atoken_id}}/drop', '#atoken-index-{{$t.atoken_id}}')"></i></td>
|
||||
</tr>
|
||||
{{/foreach}}
|
||||
</table>
|
||||
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
Reference in New Issue
Block a user