Merge branch 'dev' into sabre32

This commit is contained in:
Mario Vavti 2016-06-09 09:09:13 +02:00
commit 11045b92fb
25 changed files with 7044 additions and 7015 deletions

View file

@ -3,8 +3,11 @@
Hubzilla - Community Server
===========================
Connected and linked web communities.
-------------------------------------
Groupware re-imagined and re-invented.
--------------------------------------
Connect and link decentralised web communities.
-----------------------------------------------
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>

25
Zotlabs/Lib/AConfig.php Normal file
View file

@ -0,0 +1,25 @@
<?php
namespace Zotlabs\Lib;
// account configuration storage is built on top of the under-utilised xconfig
class AConfig {
static public function Load($account_id) {
return XConfig::Load('a_' . $account_id);
}
static public function Get($account_id,$family,$key) {
return XConfig::Get('a_' . $account_id,$family,$key);
}
static public function Set($account_id,$family,$key,$value) {
return XConfig::Get('a_' . $account_id,$family,$key,$value);
}
static public function Delete($account_id,$family,$key) {
return XConfig::Delete('a_' . $account_id,$family,$key);
}
}

73
Zotlabs/Lib/AbConfig.php Normal file
View file

@ -0,0 +1,73 @@
<?php
namespace Zotlabs\Lib;
class AbConfig {
static public function Load($chash,$xhash) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
dbesc($chash),
dbesc($xhash)
);
return $r;
}
static public function Get($chash,$xhash,$family,$key) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
if($r) {
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
}
return false;
}
static public function Set($chash,$xhash,$family,$key,$value) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(self::Get($chash,$xhash,$family,$key) === false) {
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
}
else {
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
}
if($r)
return $value;
return false;
}
static public function Delete($chash,$xhash,$family,$key) {
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
return $r;
}
}

165
Zotlabs/Lib/IConfig.php Normal file
View file

@ -0,0 +1,165 @@
<?php
namespace Zotlabs\Lib;
class IConfig {
static public function Load(&$item) {
return;
}
static public function Get(&$item, $family, $key) {
$is_item = false;
if(is_array($item)) {
$is_item = true;
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
$item['iconfig'] = array();
if(array_key_exists('item_id',$item))
$iid = $item['item_id'];
else
$iid = $item['id'];
}
elseif(intval($item))
$iid = $item;
if(! $iid)
return false;
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
foreach($item['iconfig'] as $c) {
if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
return $c['v'];
}
}
$r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
intval($iid),
dbesc($family),
dbesc($key)
);
if($r) {
$r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
if($is_item)
$item['iconfig'][] = $r[0];
return $r[0]['v'];
}
return false;
}
/**
* IConfig::Set(&$item, $family, $key, $value, $sharing = false);
*
* $item - item array or item id. If passed an array the iconfig meta information is
* added to the item structure (which will need to be saved with item_store eventually).
* If passed an id, the DB is updated, but may not be federated and/or cloned.
* $family - namespace of meta variable
* $key - key of meta variable
* $value - value of meta variable
* $sharing - boolean (default false); if true the meta information is propagated with the item
* to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
* If the meta information is added after delivery and you wish it to be shared, it may be necessary to
* alter the item edited timestamp and invoke the delivery process on the updated item. The edited
* timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
*/
static public function Set(&$item, $family, $key, $value, $sharing = false) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
$is_item = false;
$idx = null;
if(is_array($item)) {
$is_item = true;
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
$item['iconfig'] = array();
elseif($item['iconfig']) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
$idx = $x;
}
}
}
$entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
if(is_null($idx))
$item['iconfig'][] = $entry;
else
$item['iconfig'][$idx] = $entry;
return $value;
}
if(intval($item))
$iid = intval($item);
if(! $iid)
return false;
if(self::Get($item, $family, $key) === false) {
$r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
intval($iid),
dbesc($family),
dbesc($key),
dbesc($dbvalue),
intval($sharing)
);
}
else {
$r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
intval($sharing),
intval($iid),
dbesc($family),
dbesc($key)
);
}
if(! $r)
return false;
return $value;
}
static public function Delete(&$item, $family, $key) {
$is_item = false;
$idx = null;
if(is_array($item)) {
$is_item = true;
if(is_array($item['iconfig'])) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
unset($item['iconfig'][$x]);
}
}
}
return true;
}
if(intval($item))
$iid = intval($item);
if(! $iid)
return false;
return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
intval($iid),
dbesc($family),
dbesc($key)
);
}
}

189
Zotlabs/Lib/PConfig.php Normal file
View file

@ -0,0 +1,189 @@
<?php /** @file */
namespace Zotlabs\Lib;
class PConfig {
/**
* @brief Loads all configuration values of a channel into a cached storage.
*
* All configuration values of the given channel are stored in global cache
* which is available under the global variable App::$config[$uid].
*
* @param string $uid
* The channel_id
* @return void|false Nothing or false if $uid is false
*/
static public function Load($uid) {
if($uid === false)
return false;
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
$r = q("SELECT * FROM pconfig WHERE uid = %d",
intval($uid)
);
if($r) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, \App::$config[$uid])) {
\App::$config[$uid][$c] = array();
\App::$config[$uid][$c]['config_loaded'] = true;
}
\App::$config[$uid][$c][$k] = $rr['v'];
}
}
}
/**
* @brief Get a particular channel's config variable given the category name
* ($family) and a key.
*
* Get a particular channel's config value from the given category ($family)
* and the $key from a cached storage in App::$config[$uid].
*
* Returns false if not set.
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param boolean $instore (deprecated, without function)
* @return mixed Stored value or false if it does not exist
*/
static public function Get($uid,$family,$key,$instore = false) {
if($uid === false)
return false;
if(! array_key_exists($uid, \App::$config))
self::Load($uid);
if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
return false;
return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))
? unserialize(\App::$config[$uid][$family][$key])
: \App::$config[$uid][$family][$key]
);
}
/**
* @brief Sets a configuration value for a channel.
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the channel_id $uid.
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
static public function Set($uid, $family, $key, $value) {
// this catches subtle errors where this function has been called
// with local_channel() when not logged in (which returns false)
// and throws an error in array_key_exists below.
// we provide a function backtrace in the logs so that we can find
// and fix the calling function.
if($uid === false) {
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
return;
}
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_pconfig($uid, $family, $key) === false) {
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
if(! array_key_exists($family, \App::$config[$uid]))
\App::$config[$uid][$family] = array();
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
}
else {
$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'",
dbesc($dbvalue),
intval($uid),
dbesc($family),
dbesc($key)
);
}
// keep a separate copy for all variables which were
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', \App::$config[$uid]))
\App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, \App::$config[$uid]['transient']))
\App::$config[$uid]['transient'][$family] = array();
\App::$config[$uid][$family][$key] = $value;
\App::$config[$uid]['transient'][$family][$key] = $value;
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the channel's configuration.
*
* Removes the configured value from the stored cache in App::$config[$uid]
* and removes it from the database.
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
static public function Delete($uid, $family, $key) {
$ret = false;
if(array_key_exists($key, \App::$config[$uid][$family]))
unset(\App::$config[$uid][$family][$key]);
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
intval($uid),
dbesc($family),
dbesc($key)
);
return $ret;
}
}

View file

@ -15,7 +15,7 @@ class ThreadItem {
private $comment_box_template = 'comment_item.tpl';
private $commentable = false;
// list of supported reaction emojis - a site can over-ride this via config system.reactions
private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f622','1f62e','1f634','1f61c','1f607','1f608'];
private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608'];
private $toplevel = false;
private $children = array();
private $parent = null;

160
Zotlabs/Lib/XConfig.php Normal file
View file

@ -0,0 +1,160 @@
<?php
namespace Zotlabs\Lib;
class XConfig {
/**
* @brief Loads a full xchan's configuration into a cached storage.
*
* All configuration values of the given observer hash are stored in global
* cache which is available under the global variable App::$config[$xchan].
*
* @param string $xchan
* The observer's hash
* @return void|false Returns false if xchan is not set
*/
static public function Load($xchan) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, \App::$config))
\App::$config[$xchan] = array();
$r = q("SELECT * FROM xconfig WHERE xchan = '%s'",
dbesc($xchan)
);
if($r) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, \App::$config[$xchan])) {
\App::$config[$xchan][$c] = array();
\App::$config[$xchan][$c]['config_loaded'] = true;
}
\App::$config[$xchan][$c][$k] = $rr['v'];
}
}
}
/**
* @brief Get a particular observer's config variable given the category
* name ($family) and a key.
*
* Get a particular observer's config value from the given category ($family)
* and the $key from a cached storage in App::$config[$xchan].
*
* Returns false if not set.
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @return mixed Stored $value or false if it does not exist
*/
static public function Get($xchan, $family, $key) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, \App::$config))
load_xconfig($xchan);
if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family])))
return false;
return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key]))
? unserialize(\App::$config[$xchan][$family][$key])
: \App::$config[$xchan][$family][$key]
);
}
/**
* @brief Sets a configuration value for an observer.
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the observer's $xchan hash.
*
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
static public function Set($xchan, $family, $key, $value) {
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(self::Get($xchan, $family, $key) === false) {
if(! array_key_exists($xchan, \App::$config))
\App::$config[$xchan] = array();
if(! array_key_exists($family, \App::$config[$xchan]))
\App::$config[$xchan][$family] = array();
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
dbesc($xchan),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
}
else {
$ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'",
dbesc($dbvalue),
dbesc($xchan),
dbesc($family),
dbesc($key)
);
}
App::$config[$xchan][$family][$key] = $value;
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the observer's config.
*
* Removes the configured value from the stored cache in App::$config[$xchan]
* and removes it from the database.
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
static public function Delete($xchan, $family, $key) {
if(x(\App::$config[$xchan][$family], $key))
unset(\App::$config[$xchan][$family][$key]);
$ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
dbesc($xchan),
dbesc($family),
dbesc($key)
);
return $ret;
}
}

View file

@ -32,8 +32,8 @@ class Admin extends \Zotlabs\Web\Controller {
case 'site':
$this->admin_page_site_post($a);
break;
case 'users':
$this->admin_page_users_post($a);
case 'accounts':
$this->admin_page_accounts_post($a);
break;
case 'channels':
$this->admin_page_channels_post($a);
@ -127,8 +127,8 @@ class Admin extends \Zotlabs\Web\Controller {
case 'site':
$o = $this->admin_page_site($a);
break;
case 'users':
$o = $this->admin_page_users($a);
case 'accounts':
$o = $this->admin_page_accounts($a);
break;
case 'channels':
$o = $this->admin_page_channels($a);
@ -872,20 +872,20 @@ class Admin extends \Zotlabs\Web\Controller {
}
/**
* @brief Handle POST actions on users admin page.
* @brief Handle POST actions on accounts admin page.
*
* This function is called when on the admin user/account page the form was
* submitted to handle multiple operations at once. If one of the icons next
* to an entry are pressed the function admin_page_users() will handle this.
* to an entry are pressed the function admin_page_accounts() will handle this.
*
* @param App $a
*/
function admin_page_users_post($a) {
function admin_page_accounts_post($a) {
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() );
check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
// change to switch structure?
// account block/unblock button was submitted
@ -901,7 +901,7 @@ class Admin extends \Zotlabs\Web\Controller {
notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) );
}
// account delete button was submitted
if (x($_POST, 'page_users_delete')) {
if (x($_POST, 'page_accounts_delete')) {
foreach ($users as $uid){
account_remove($uid, true, false);
}
@ -920,20 +920,20 @@ class Admin extends \Zotlabs\Web\Controller {
}
}
goaway(z_root() . '/admin/users' );
goaway(z_root() . '/admin/accounts' );
}
/**
* @brief Generate users admin page and handle single item operations.
* @brief Generate accounts admin page and handle single item operations.
*
* This function generates the users/account admin page and handles the actions
* This function generates the accounts/account admin page and handles the actions
* if an icon next to an entry was clicked. If several items were selected and
* the form was submitted it is handled by the function admin_page_users_post().
* the form was submitted it is handled by the function admin_page_accounts_post().
*
* @param App &$a
* @return string
*/
function admin_page_users(&$a){
function admin_page_accounts(&$a){
if (argc() > 2) {
$uid = argv(3);
$account = q("SELECT * FROM account WHERE account_id = %d",
@ -942,10 +942,10 @@ class Admin extends \Zotlabs\Web\Controller {
if (! $account) {
notice( t('Account not found') . EOL);
goaway(z_root() . '/admin/users' );
goaway(z_root() . '/admin/accounts' );
}
check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
switch (argv(2)){
case 'delete':
@ -972,7 +972,7 @@ class Admin extends \Zotlabs\Web\Controller {
break;
}
goaway(z_root() . '/admin/users' );
goaway(z_root() . '/admin/accounts' );
}
/* get pending */
@ -980,7 +980,7 @@ class Admin extends \Zotlabs\Web\Controller {
intval(ACCOUNT_PENDING)
);
/* get users */
/* get accounts */
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
@ -988,22 +988,20 @@ class Admin extends \Zotlabs\Web\Controller {
\App::set_pager_itemspage(100);
}
// We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet.
// That's where we need to be doing last post/channel flags/etc, not here.
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
$order = " order by account_email asc ";
if($_REQUEST['order'] === 'expires')
$order = " order by account_expires desc ";
if($_REQUEST['order'] === 'created')
$order = " order by account_created desc ";
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
$dir = 'asc';
if(array_key_exists('dir',$_REQUEST))
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
$base = z_root() . '/admin/accounts?f=';
$odir = (($dir === 'asc') ? '0' : '1');
$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " .
"(SELECT %s FROM channel as ch " .
"WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " .
"FROM account as ac where true $serviceclass $order limit %d offset %d ",
"FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ",
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
intval(\App::$pager['itemspage']),
@ -1026,14 +1024,14 @@ class Admin extends \Zotlabs\Web\Controller {
// }
// $users = array_map("_setup_users", $users);
$t = get_markup_template('admin_users.tpl');
$t = get_markup_template('admin_accounts.tpl');
$o = replace_macros($t, array(
// strings //
'$title' => t('Administration'),
'$page' => t('Users'),
'$page' => t('Accounts'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$h_pending' => t('User registrations waiting for confirm'),
'$h_pending' => t('Registrations waiting for confirm'),
'$th_pending' => array( t('Request date'), t('Email') ),
'$no_pending' => t('No registrations.'),
'$approve' => t('Approve'),
@ -1041,14 +1039,22 @@ class Admin extends \Zotlabs\Web\Controller {
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
'$h_users' => t('Users'),
'$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')),
'$odir' => $odir,
'$base' => $base,
'$h_users' => t('Accounts'),
'$th_users' => array(
[ t('ID'), 'account_id' ],
[ t('Email'), 'account_email' ],
[ t('All Channels'), 'channels' ],
[ t('Register date'), 'account_created' ],
[ t('Last login'), 'account_lastlog' ],
[ t('Expires'), 'account_expires' ],
[ t('Service Class'), 'account_service_class'] ),
'$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'),
'$form_security_token' => get_form_security_token("admin_users"),
'$form_security_token' => get_form_security_token("admin_accounts"),
// values //
'$baseurl' => z_root(),
@ -1159,6 +1165,17 @@ class Admin extends \Zotlabs\Web\Controller {
goaway(z_root() . '/admin/channels' );
}
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id');
$dir = 'asc';
if(array_key_exists('dir',$_REQUEST))
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
$base = z_root() . '/admin/channels?f=';
$odir = (($dir === 'asc') ? '0' : '1');
/* get channels */
$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0");
@ -1167,9 +1184,7 @@ class Admin extends \Zotlabs\Web\Controller {
\App::set_pager_itemspage(100);
}
$order = " order by channel_name asc ";
$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ",
$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ",
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
);
@ -1201,7 +1216,12 @@ class Admin extends \Zotlabs\Web\Controller {
'$code' => t('Allow Code'),
'$uncode' => t('Disallow Code'),
'$h_channels' => t('Channel'),
'$th_channels' => array( t('UID'), t('Name'), t('Address')),
'$base' => $base,
'$odir' => $odir,
'$th_channels' => array(
[ t('UID'), 'channel_id' ],
[ t('Name'), 'channel_name' ],
[ t('Address'), 'channel_address' ]),
'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'),

View file

@ -1277,11 +1277,9 @@ class Photos extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
$r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'
$r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d
and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`",
intval(\App::$data['channel']['channel_id']),
dbesc('Contact Photos'),
dbesc( t('Contact Photos')),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe)
@ -1291,15 +1289,13 @@ class Photos extends \Zotlabs\Web\Controller {
\App::set_pager_itemspage(60);
}
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo as p
INNER JOIN ( SELECT resource_id, max(imgscale) as imgscale FROM photo
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p
INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo
WHERE uid = %d AND photo_usage IN ( %d, %d )
AND is_nsfw = %d $sql_extra group by resource_id ) as ph
AND is_nsfw = %d $sql_extra group by resource_id ) ph
ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale)
ORDER by p.created DESC LIMIT %d OFFSET %d",
intval(\App::$data['channel']['channel_id']),
dbesc('Contact Photos'),
dbesc( t('Contact Photos')),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe),

View file

@ -1466,6 +1466,12 @@ function check_config(&$a) {
//send the administrator an e-mail
file_put_contents($lockfile, $x);
$r = q("select account_language from account where account_email = '%s' limit 1",
dbesc(App::$config['system']['admin_email'])
);
push_lang(($r) ? $r[0]['account_language'] : 'en');
$email_tpl = get_intltext_template("update_fail_eml.tpl");
$email_msg = replace_macros($email_tpl, array(
'$sitename' => App::$config['system']['sitename'],
@ -1482,6 +1488,7 @@ function check_config(&$a) {
. 'Content-transfer-encoding: 8bit' );
//try the logger
logger('CRITICAL: Update Failed: ' . $x);
pop_lang();
}
else
set_config('database','update_r' . $x, 'success');

View file

@ -86,6 +86,13 @@
[h3]Addon Repositories[/h3]
We [b]strongly recommend[/b] that authors of addons publish/submit them to the project addon repository. This has several advantages. Project developers can easily fix security flaws and make changes to comply with recent changes in core code. Addons provided in third-party repositories are considered untrusted. If the project core code changes in an incompatible way, there may be no alternative but to physically remove or rename the addon files in order to get your site working again. Often only the plugin/addon author can help you regain control of your website, and project developers are unable to assist you; because by definition your site configuration has been modified in ways that we cannot easily test or verify.
For these reasons we [b]strongly recommend[/b] that you do NOT install addons from third-party repositories.
We also recognise that some developers prefer working on their own and do not wish their code to be mingled with the project repository for a variety of reasons. These developers can ease troubleshooting and debugging by providing a README file in their respective code repository outlining the process for submitting patches and bug fixes. It is also recommended that these projects provide both a 'dev' (development) and 'master' (production) branch which tracks the current project branches of those names. This is because dev and master are often not compatible from the viewpoint of library interfaces. It is also highly recommended that your repository versions are tagged and moved forward within 24 hours of project releases. This is a major inconvenience for everybdy involved, and can present downtime for production sites while this process is being carried out; which is one more reason why we [b]strongly recommend[/b] that addons be submitted to the project addon repository and that you do NOT install such third-party addons.
[url=https://github.com/redmatrix/hubzilla-addons]https://github.com/redmatrix/hubzilla-addons[/url] Main project addon repository
[url=https://github.com/23n/red-addons]https://github.com/23n/red-addons[/url] Oliver's repository (mayan_places and flip)

View file

@ -1904,10 +1904,15 @@ require_once('include/api_auth.php');
$ret = array();
$x = array('items' => $r,'api_user' => api_user(),'user_info' => $user_info);
call_hooks('api_format_items',$x);
$r = $x['items'];
if(! $r)
return $ret;
foreach($r as $item) {
localize_item($item);
$status_user = (($item['author_xchan']==$user_info['guid'])?$user_info: api_item_get_user($a,$item));

View file

@ -33,617 +33,99 @@
use Zotlabs\Lib as Zlib;
function load_config($family) {
Zlib\Config::Load($family);
}
function get_config($family, $key) {
return Zlib\Config::Get($family,$key);
}
function set_config($family, $key, $value) {
return Zlib\Config::Set($family,$key,$value);
}
function del_config($family, $key) {
return Zlib\Config::Delete($family,$key);
}
/**
* @brief Loads all configuration values of a channel into a cached storage.
*
* All configuration values of the given channel are stored in global cache
* which is available under the global variable App::$config[$uid].
*
* @param string $uid
* The channel_id
* @return void|false Nothing or false if $uid is false
*/
function load_pconfig($uid) {
if($uid === false)
return false;
if(! array_key_exists($uid, App::$config))
App::$config[$uid] = array();
$r = q("SELECT * FROM pconfig WHERE uid = %d",
intval($uid)
);
if($r) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, App::$config[$uid])) {
App::$config[$uid][$c] = array();
App::$config[$uid][$c]['config_loaded'] = true;
}
App::$config[$uid][$c][$k] = $rr['v'];
}
}
Zlib\PConfig::Load($uid);
}
/**
* @brief Get a particular channel's config variable given the category name
* ($family) and a key.
*
* Get a particular channel's config value from the given category ($family)
* and the $key from a cached storage in App::$config[$uid].
*
* Returns false if not set.
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param boolean $instore (deprecated, without function)
* @return mixed Stored value or false if it does not exist
*/
function get_pconfig($uid, $family, $key, $instore = false) {
// logger('include/config.php: get_pconfig() deprecated instore param used', LOGGER_DEBUG);
if($uid === false)
return false;
if(! array_key_exists($uid, App::$config))
load_pconfig($uid);
if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family])))
return false;
return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key]))
? unserialize(App::$config[$uid][$family][$key])
: App::$config[$uid][$family][$key]
);
return Zlib\PConfig::Get($uid,$family,$key,$instore = false);
}
/**
* @brief Sets a configuration value for a channel.
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the channel_id $uid.
*
* @note Please do not store booleans - convert to 0/1 integer values!
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
function set_pconfig($uid, $family, $key, $value) {
// this catches subtle errors where this function has been called
// with local_channel() when not logged in (which returns false)
// and throws an error in array_key_exists below.
// we provide a function backtrace in the logs so that we can find
// and fix the calling function.
if($uid === false) {
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
return;
return Zlib\PConfig::Set($uid,$family,$key,$value);
}
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_pconfig($uid, $family, $key) === false) {
if(! array_key_exists($uid, App::$config))
App::$config[$uid] = array();
if(! array_key_exists($family, App::$config[$uid]))
App::$config[$uid][$family] = array();
// keep a separate copy for all variables which were
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', App::$config[$uid]))
App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, App::$config[$uid]['transient']))
App::$config[$uid]['transient'][$family] = array();
App::$config[$uid][$family][$key] = $value;
App::$config[$uid]['transient'][$family][$key] = $value;
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
}
$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'",
dbesc($dbvalue),
intval($uid),
dbesc($family),
dbesc($key)
);
// keep a separate copy for all variables which were
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', App::$config[$uid]))
App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, App::$config[$uid]['transient']))
App::$config[$uid]['transient'][$family] = array();
App::$config[$uid][$family][$key] = $value;
App::$config[$uid]['transient'][$family][$key] = $value;
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the channel's configuration.
*
* Removes the configured value from the stored cache in App::$config[$uid]
* and removes it from the database.
*
* @param string $uid
* The channel_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
function del_pconfig($uid, $family, $key) {
$ret = false;
if (x(App::$config[$uid][$family], $key))
unset(App::$config[$uid][$family][$key]);
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
intval($uid),
dbesc($family),
dbesc($key)
);
return $ret;
return Zlib\PConfig::Delete($uid,$family,$key);
}
/**
* @brief Loads a full xchan's configuration into a cached storage.
*
* All configuration values of the given observer hash are stored in global
* cache which is available under the global variable App::$config[$xchan].
*
* @param string $xchan
* The observer's hash
* @return void|false Returns false if xchan is not set
*/
function load_xconfig($xchan) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, App::$config))
App::$config[$xchan] = array();
$r = q("SELECT * FROM xconfig WHERE xchan = '%s'",
dbesc($xchan)
);
if($r) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, App::$config[$xchan])) {
App::$config[$xchan][$c] = array();
App::$config[$xchan][$c]['config_loaded'] = true;
}
App::$config[$xchan][$c][$k] = $rr['v'];
}
}
Zlib\XConfig::Load($xchan);
}
/**
* @brief Get a particular observer's config variable given the category
* name ($family) and a key.
*
* Get a particular observer's config value from the given category ($family)
* and the $key from a cached storage in App::$config[$xchan].
*
* Returns false if not set.
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @return mixed Stored $value or false if it does not exist
*/
function get_xconfig($xchan, $family, $key) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, App::$config))
load_xconfig($xchan);
if((! array_key_exists($family, App::$config[$xchan])) || (! array_key_exists($key, App::$config[$xchan][$family])))
return false;
return ((! is_array(App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$xchan][$family][$key]))
? unserialize(App::$config[$xchan][$family][$key])
: App::$config[$xchan][$family][$key]
);
return Zlib\XConfig::Get($xchan,$family,$key);
}
/**
* @brief Sets a configuration value for an observer.
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the observer's $xchan hash.
*
* @note Please do not store booleans - convert to 0/1 integer values!
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
function set_xconfig($xchan, $family, $key, $value) {
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_xconfig($xchan, $family, $key) === false) {
if(! array_key_exists($xchan, App::$config))
App::$config[$xchan] = array();
if(! array_key_exists($family, App::$config[$xchan]))
App::$config[$xchan][$family] = array();
App::$config[$xchan][$family][$key] = $value;
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
dbesc($xchan),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
return Zlib\XConfig::Set($xchan,$family,$key,$value);
}
$ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'",
dbesc($dbvalue),
dbesc($xchan),
dbesc($family),
dbesc($key)
);
App::$config[$xchan][$family][$key] = $value;
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the observer's config.
*
* Removes the configured value from the stored cache in App::$config[$xchan]
* and removes it from the database.
*
* @param string $xchan
* The observer's hash
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
function del_xconfig($xchan, $family, $key) {
$ret = false;
if(x(App::$config[$xchan][$family], $key))
unset(App::$config[$xchan][$family][$key]);
$ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
dbesc($xchan),
dbesc($family),
dbesc($key)
);
return $ret;
return Zlib\XConfig::Delete($xchan,$family,$key);
}
// account configuration storage is built on top of the under-utilised xconfig
function load_aconfig($account_id) {
load_xconfig('a_' . $account_id);
Zlib\AConfig::Load($account_id);
}
function get_aconfig($account_id, $family, $key) {
return get_xconfig('a_' . $account_id, $family, $key);
return Zlib\AConfig::Get($account_id, $family, $key);
}
function set_aconfig($account_id, $family, $key, $value) {
return set_xconfig('a_' . $account_id, $family, $key, $value);
return Zlib\AConfig::Set($account_id, $family, $key, $value);
}
function del_aconfig($account_id, $family, $key) {
return del_xconfig('a_' . $account_id, $family, $key);
return Zlib\AConfig::Delete($account_id, $family, $key);
}
function load_abconfig($chash,$xhash) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
dbesc($chash),
dbesc($xhash)
);
return $r;
Zlib\AbConfig::Load($chash,$xhash);
}
function get_abconfig($chash,$xhash,$family,$key) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
if($r) {
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
return Zlib\AbConfig::Get($chash,$xhash,$family,$key);
}
return false;
}
function set_abconfig($chash,$xhash,$family,$key,$value) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_abconfig($chash,$xhash,$family,$key) === false) {
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
return Zlib\AbConfig::Set($chash,$xhash,$family,$key,$value);
}
else {
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
}
if($r)
return $value;
return false;
}
function del_abconfig($chash,$xhash,$family,$key) {
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
return $r;
return Zlib\AbConfig::Delete($chash,$xhash,$family,$key);
}
function load_iconfig(&$item) {
Zlib\IConfig::Load($item);
}
function get_iconfig(&$item, $family, $key) {
$is_item = false;
if(is_array($item)) {
$is_item = true;
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
$item['iconfig'] = array();
if(array_key_exists('item_id',$item))
$iid = $item['item_id'];
else
$iid = $item['id'];
return Zlib\IConfig::Get($item, $family, $key);
}
elseif(intval($item))
$iid = $item;
if(! $iid)
return false;
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
foreach($item['iconfig'] as $c) {
if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
return $c['v'];
}
}
$r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
intval($iid),
dbesc($family),
dbesc($key)
);
if($r) {
$r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
if($is_item)
$item['iconfig'][] = $r[0];
return $r[0]['v'];
}
return false;
}
/**
* set_iconfig(&$item, $family, $key, $value, $sharing = false);
*
* $item - item array or item id. If passed an array the iconfig meta information is
* added to the item structure (which will need to be saved with item_store eventually).
* If passed an id, the DB is updated, but may not be federated and/or cloned.
* $family - namespace of meta variable
* $key - key of meta variable
* $value - value of meta variable
* $sharing - boolean (default false); if true the meta information is propagated with the item
* to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
* If the meta information is added after delivery and you wish it to be shared, it may be necessary to
* alter the item edited timestamp and invoke the delivery process on the updated item. The edited
* timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
*/
function set_iconfig(&$item, $family, $key, $value, $sharing = false) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
$is_item = false;
$idx = null;
if(is_array($item)) {
$is_item = true;
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
$item['iconfig'] = array();
elseif($item['iconfig']) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
$idx = $x;
return Zlib\IConfig::Set($item, $family, $key, $value, $sharing = false);
}
}
}
$entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
if(is_null($idx))
$item['iconfig'][] = $entry;
else
$item['iconfig'][$idx] = $entry;
return $value;
}
if(intval($item))
$iid = intval($item);
if(! $iid)
return false;
if(get_iconfig($item, $family, $key) === false) {
$r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
intval($iid),
dbesc($family),
dbesc($key),
dbesc($dbvalue),
intval($sharing)
);
}
else {
$r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
intval($sharing),
intval($iid),
dbesc($family),
dbesc($key)
);
}
if(! $r)
return false;
return $value;
}
function del_iconfig(&$item, $family, $key) {
$is_item = false;
$idx = null;
if(is_array($item)) {
$is_item = true;
if(is_array($item['iconfig'])) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
unset($item['iconfig'][$x]);
return Zlib\IConfig::Delete($item, $family, $key);
}
}
}
return true;
}
if(intval($item))
$iid = intval($item);
if(! $iid)
return false;
return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
intval($iid),
dbesc($family),
dbesc($key)
);
}

View file

@ -590,7 +590,8 @@ function random_profile() {
for($i = 0; $i < $retryrandom; $i++) {
$r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1",
$r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_addr not like '%s' and hubloc_connected > %s - interval %s order by $randfunc limit 1",
dbesc('sys@%'),
db_utcnow(), db_quoteinterval('30 day')
);

View file

@ -443,7 +443,7 @@ function photo_upload($channel, $observer, $args) {
* * success (bool)
* * albums (array)
*/
function photos_albums_list($channel, $observer) {
function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') {
$channel_id = $channel['channel_id'];
$observer_xchan = (($observer) ? $observer['xchan_hash'] : '');
@ -451,11 +451,15 @@ function photos_albums_list($channel, $observer) {
if(! perm_is_allowed($channel_id, $observer_xchan, 'view_storage'))
return false;
/** @FIXME create a permissions SQL which works on arbitrary observers and channels, regardless of login or web status */
$sql_extra = permissions_sql($channel_id);
$sql_extra = permissions_sql($channel_id,$observer_xchan);
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by max(created) desc",
$sort_key = dbesc($sort_key);
$direction = dbesc($direction);
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction",
intval($channel_id),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
@ -483,20 +487,14 @@ function photos_albums_list($channel, $observer) {
return $ret;
}
function photos_album_widget($channelx,$observer,$albums = null) {
function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = 'asc') {
$o = '';
// If we weren't passed an album list, see if the photos module
// dropped one for us to find in App::$data['albums'].
// If all else fails, load it.
if(! $albums) {
if(array_key_exists('albums', App::$data))
$albums = App::$data['albums'];
else
$albums = photos_albums_list($channelx,$observer);
}
$albums = photos_albums_list($channelx,$observer,$sortkey,$direction);
if($albums['success']) {
$o = replace_macros(get_markup_template('photo_albums.tpl'),array(

View file

@ -799,8 +799,10 @@ function widget_photo_albums($arr) {
if((! $channelx) || (! perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_storage')))
return '';
require_once('include/photos.php');
$sortkey = ((array_key_exists('sortkey',$arr)) ? $arr['sortkey'] : 'album');
$direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc');
return photos_album_widget($channelx, App::get_observer());
return photos_album_widget($channelx, App::get_observer(),$sortkey,$direction);
}
@ -1378,7 +1380,7 @@ function widget_admin($arr) {
$aside = array(
'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
'users' => array(z_root() . '/admin/users/', t('Accounts'), 'users', 'pending-update', t('Member registrations waiting for confirmation')),
'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')),
'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
'security' => array(z_root() . '/admin/security/', t('Security'), 'security'),
'features' => array(z_root() . '/admin/features/', t('Features'), 'features'),

View file

@ -17,7 +17,6 @@ EOT;
require_once('include/cli_startup.php');
cli_startup();
$a = get_app();
$plugs = get_config('system', 'addon');
$plugins_arr = array();

27
util/safemode Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
if [ $# == 0 ] ; then
echo Usage: $0 on '|' $0 off
echo on saves current addons to addons-safemode and uninstalls all of them
echo off installs all addons in addons-safemode
exit
fi
if [ $1 == 'on' ] ; then
util/addons list > addons-safemode
for a in `cat addons-safemode` ; do
util/addons uninstall $a
done
exit
fi
if [ $1 == 'off' ] ; then
for a in `cat addons-safemode` ; do
util/addons install $a
done
exit
fi

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -183,7 +183,7 @@ function string2bb(element) {
};
smilies = {
match: /(^|\s)(:[a-z]{2,})$/,
match: /(^|\s)(:[a-z_:]{2,})$/,
index: 2,
search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); },
template: function(item) { return item.icon + item.text; },

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
<div class="generic-content-wrapper-styled" id="adminpage">
<h1>{{$title}} - {{$page}}</h1>
<form action="{{$baseurl}}/admin/users" method="post">
<form action="{{$baseurl}}/admin/accounts" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<h3>{{$h_pending}}</h3>
@ -52,7 +52,7 @@
<table id="users">
<thead>
<tr>
{{foreach $th_users as $th}}<th>{{$th}}</th>{{/foreach}}
{{foreach $th_users as $th}}<th><a href="{{$base}}&key={{$th.1}}&dir={{$odir}}">{{$th.0}}</a></th>{{/foreach}}
<th></th>
<th></th>
</tr>
@ -73,7 +73,7 @@
<td class="service_class">{{$u.account_service_class}}</td>
<td class="checkbox_bulkedit"><input type="checkbox" class="users_ckbx" id="id_user_{{$u.account_id}}" name="user[]" value="{{$u.account_id}}"><input type="hidden" name="blocked[]" value="{{$u.blocked}}"></td>
<td class="tools">
<a href="{{$baseurl}}/admin/users/{{if ($u.blocked)}}un{{/if}}block/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{if ($u.blocked)}}{{$unblock}}{{else}}{{$block}}{{/if}}'><i class="fa fa-ban admin-icons{{if ($u.blocked)}} dim{{/if}}"></i></a><a href="{{$baseurl}}/admin/users/delete/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{$delete}}' onclick="return confirm_delete('{{$u.name}}')"><i class="fa fa-trash-o admin-icons"></i></a>
<a href="{{$baseurl}}/admin/accounts/{{if ($u.blocked)}}un{{/if}}block/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{if ($u.blocked)}}{{$unblock}}{{else}}{{$block}}{{/if}}'><i class="fa fa-ban admin-icons{{if ($u.blocked)}} dim{{/if}}"></i></a><a href="{{$baseurl}}/admin/accounts/delete/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{$delete}}' onclick="return confirm_delete('{{$u.name}}')"><i class="fa fa-trash-o admin-icons"></i></a>
</td>
</tr>
{{/foreach}}

View file

@ -21,7 +21,7 @@
<table id='channels'>
<thead>
<tr>
{{foreach $th_channels as $th}}<th>{{$th}}</th>{{/foreach}}
{{foreach $th_channels as $th}}<th><a href="{{$base}}&key={{$th.1}}&dir={{$odir}}">{{$th.0}}</a></th>{{/foreach}}
<th></th>
<th></th>
</tr>