psr12 updates

This commit is contained in:
nobody 2021-12-03 10:02:31 +11:00
parent 389b2e5b17
commit f602a393a5
687 changed files with 63552 additions and 62782 deletions

View file

@ -5,5 +5,5 @@ self.addEventListener('install', function(e) {
self.addEventListener('fetch', function(e) {
// nothing here yet
return;
});

View file

@ -12,153 +12,158 @@ namespace Zotlabs\Access;
* and @ref ::Zotlabs::Lib::Permcat "Permcat"s individual content ACLs are evaluated.
* These answer the question "Can Joe view *this* album/photo?".
*/
class AccessControl {
/**
* @brief Allow contacts
* @var string
*/
private $allow_cid;
/**
* @brief Allow groups
* @var string
*/
private $allow_gid;
/**
* @brief Deny contacts
* @var string
*/
private $deny_cid;
/**
* @brief Deny groups
* @var string
*/
private $deny_gid;
/**
* @brief Indicates if we are using the default constructor values or
* values that have been set explicitly.
* @var boolean
*/
private $explicit;
class AccessControl
{
/**
* @brief Allow contacts
* @var string
*/
private $allow_cid;
/**
* @brief Allow groups
* @var string
*/
private $allow_gid;
/**
* @brief Deny contacts
* @var string
*/
private $deny_cid;
/**
* @brief Deny groups
* @var string
*/
private $deny_gid;
/**
* @brief Indicates if we are using the default constructor values or
* values that have been set explicitly.
* @var bool
*/
private $explicit;
/**
* @brief Constructor for AccessList class.
*
* @note The array to pass to the constructor is different from the array
* that you provide to the set() or set_from_array() functions.
*
* @param array $channel A channel array, where these entries are evaluated:
* * \e string \b channel_allow_cid => string of allowed cids
* * \e string \b channel_allow_gid => string of allowed gids
* * \e string \b channel_deny_cid => string of denied cids
* * \e string \b channel_deny_gid => string of denied gids
*/
function __construct($channel) {
if($channel) {
$this->allow_cid = $channel['channel_allow_cid'];
$this->allow_gid = $channel['channel_allow_gid'];
$this->deny_cid = $channel['channel_deny_cid'];
$this->deny_gid = $channel['channel_deny_gid'];
}
else {
$this->allow_cid = '';
$this->allow_gid = '';
$this->deny_cid = '';
$this->deny_gid = '';
}
/**
* @brief Constructor for AccessList class.
*
* @note The array to pass to the constructor is different from the array
* that you provide to the set() or set_from_array() functions.
*
* @param array $channel A channel array, where these entries are evaluated:
* * \e string \b channel_allow_cid => string of allowed cids
* * \e string \b channel_allow_gid => string of allowed gids
* * \e string \b channel_deny_cid => string of denied cids
* * \e string \b channel_deny_gid => string of denied gids
*/
public function __construct($channel)
{
if ($channel) {
$this->allow_cid = $channel['channel_allow_cid'];
$this->allow_gid = $channel['channel_allow_gid'];
$this->deny_cid = $channel['channel_deny_cid'];
$this->deny_gid = $channel['channel_deny_gid'];
} else {
$this->allow_cid = '';
$this->allow_gid = '';
$this->deny_cid = '';
$this->deny_gid = '';
}
$this->explicit = false;
}
$this->explicit = false;
}
/**
* @brief Get if we are using the default constructor values
* or values that have been set explicitly.
*
* @return boolean
*/
function get_explicit() {
return $this->explicit;
}
/**
* @brief Get if we are using the default constructor values
* or values that have been set explicitly.
*
* @return bool
*/
public function get_explicit()
{
return $this->explicit;
}
/**
* @brief Set access list from strings such as those in already
* existing stored data items.
*
* @note The array to pass to this set function is different from the array
* that you provide to the constructor or set_from_array().
*
* @param array $arr
* * \e string \b allow_cid => string of allowed cids
* * \e string \b allow_gid => string of allowed gids
* * \e string \b deny_cid => string of denied cids
* * \e string \b deny_gid => string of denied gids
* @param boolean $explicit (optional) default true
*/
function set($arr, $explicit = true) {
$this->allow_cid = $arr['allow_cid'];
$this->allow_gid = $arr['allow_gid'];
$this->deny_cid = $arr['deny_cid'];
$this->deny_gid = $arr['deny_gid'];
/**
* @brief Set access list from strings such as those in already
* existing stored data items.
*
* @note The array to pass to this set function is different from the array
* that you provide to the constructor or set_from_array().
*
* @param array $arr
* * \e string \b allow_cid => string of allowed cids
* * \e string \b allow_gid => string of allowed gids
* * \e string \b deny_cid => string of denied cids
* * \e string \b deny_gid => string of denied gids
* @param bool $explicit (optional) default true
*/
public function set($arr, $explicit = true)
{
$this->allow_cid = $arr['allow_cid'];
$this->allow_gid = $arr['allow_gid'];
$this->deny_cid = $arr['deny_cid'];
$this->deny_gid = $arr['deny_gid'];
$this->explicit = $explicit;
}
$this->explicit = $explicit;
}
/**
* @brief Return an array consisting of the current access list components
* where the elements are directly storable.
*
* @return array An associative array with:
* * \e string \b allow_cid => string of allowed cids
* * \e string \b allow_gid => string of allowed gids
* * \e string \b deny_cid => string of denied cids
* * \e string \b deny_gid => string of denied gids
*/
function get() {
return [
'allow_cid' => $this->allow_cid,
'allow_gid' => $this->allow_gid,
'deny_cid' => $this->deny_cid,
'deny_gid' => $this->deny_gid,
];
}
/**
* @brief Return an array consisting of the current access list components
* where the elements are directly storable.
*
* @return array An associative array with:
* * \e string \b allow_cid => string of allowed cids
* * \e string \b allow_gid => string of allowed gids
* * \e string \b deny_cid => string of denied cids
* * \e string \b deny_gid => string of denied gids
*/
public function get()
{
return [
'allow_cid' => $this->allow_cid,
'allow_gid' => $this->allow_gid,
'deny_cid' => $this->deny_cid,
'deny_gid' => $this->deny_gid,
];
}
/**
* @brief Set access list components from arrays, such as those provided by
* acl_selector().
*
* For convenience, a string (or non-array) input is assumed to be a
* comma-separated list and auto-converted into an array.
*
* @note The array to pass to this set function is different from the array
* that you provide to the constructor or set().
*
* @param array $arr An associative array with:
* * \e array|string \b contact_allow => array with cids or comma-seperated string
* * \e array|string \b group_allow => array with gids or comma-seperated string
* * \e array|string \b contact_deny => array with cids or comma-seperated string
* * \e array|string \b group_deny => array with gids or comma-seperated string
* @param boolean $explicit (optional) default true
*/
function set_from_array($arr, $explicit = true) {
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
? $arr['contact_allow'] : explode(',', $arr['contact_allow']));
$this->allow_gid = perms2str((is_array($arr['group_allow']))
? $arr['group_allow'] : explode(',', $arr['group_allow']));
$this->deny_cid = perms2str((is_array($arr['contact_deny']))
? $arr['contact_deny'] : explode(',', $arr['contact_deny']));
$this->deny_gid = perms2str((is_array($arr['group_deny']))
? $arr['group_deny'] : explode(',', $arr['group_deny']));
/**
* @brief Set access list components from arrays, such as those provided by
* acl_selector().
*
* For convenience, a string (or non-array) input is assumed to be a
* comma-separated list and auto-converted into an array.
*
* @note The array to pass to this set function is different from the array
* that you provide to the constructor or set().
*
* @param array $arr An associative array with:
* * \e array|string \b contact_allow => array with cids or comma-seperated string
* * \e array|string \b group_allow => array with gids or comma-seperated string
* * \e array|string \b contact_deny => array with cids or comma-seperated string
* * \e array|string \b group_deny => array with gids or comma-seperated string
* @param bool $explicit (optional) default true
*/
public function set_from_array($arr, $explicit = true)
{
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
? $arr['contact_allow'] : explode(',', $arr['contact_allow']));
$this->allow_gid = perms2str((is_array($arr['group_allow']))
? $arr['group_allow'] : explode(',', $arr['group_allow']));
$this->deny_cid = perms2str((is_array($arr['contact_deny']))
? $arr['contact_deny'] : explode(',', $arr['contact_deny']));
$this->deny_gid = perms2str((is_array($arr['group_deny']))
? $arr['group_deny'] : explode(',', $arr['group_deny']));
$this->explicit = $explicit;
}
/**
* @brief Returns true if any access lists component is set.
*
* @return boolean Return true if any of allow_* deny_* values is set.
*/
function is_private() {
return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
}
$this->explicit = $explicit;
}
/**
* @brief Returns true if any access lists component is set.
*
* @return bool Return true if any of allow_* deny_* values is set.
*/
public function is_private()
{
return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
}
}

View file

@ -26,78 +26,83 @@ use Zotlabs\Lib\PConfig;
*
* @see Permissions
*/
class PermissionLimits {
class PermissionLimits
{
/**
* @brief Get standard permission limits.
*
* Viewing permissions and post_comments permission are set to 'anybody',
* other permissions are set to 'those I allow'.
*
* The list of permissions comes from Permissions::Perms().
*
* @return array
*/
static public function Std_Limits() {
$limits = [];
$perms = Permissions::Perms();
/**
* @brief Get standard permission limits.
*
* Viewing permissions and post_comments permission are set to 'anybody',
* other permissions are set to 'those I allow'.
*
* The list of permissions comes from Permissions::Perms().
*
* @return array
*/
public static function Std_Limits()
{
$limits = [];
$perms = Permissions::Perms();
foreach($perms as $k => $v) {
if(strstr($k, 'view'))
$limits[$k] = PERMS_PUBLIC;
else
$limits[$k] = PERMS_SPECIFIC;
}
foreach ($perms as $k => $v) {
if (strstr($k, 'view')) {
$limits[$k] = PERMS_PUBLIC;
} else {
$limits[$k] = PERMS_SPECIFIC;
}
}
return $limits;
}
return $limits;
}
/**
* @brief Sets a permission limit for a channel.
*
* @param int $channel_id
* @param string $perm
* @param int $perm_limit one of PERMS_* constants
*/
static public function Set($channel_id, $perm, $perm_limit) {
PConfig::Set($channel_id, 'perm_limits', $perm, $perm_limit);
}
/**
* @brief Sets a permission limit for a channel.
*
* @param int $channel_id
* @param string $perm
* @param int $perm_limit one of PERMS_* constants
*/
public static function Set($channel_id, $perm, $perm_limit)
{
PConfig::Set($channel_id, 'perm_limits', $perm, $perm_limit);
}
/**
* @brief Get a channel's permission limits.
*
* Return a channel's permission limits from PConfig. If $perm is set just
* return this permission limit, if not set, return an array with all
* permission limits.
*
* @param int $channel_id
* @param string $perm (optional)
* @return
* * \b false if no perm_limits set for this channel
* * \b int if $perm is set, return one of PERMS_* constants for this permission, default 0
* * \b array with all permission limits, if $perm is not set
*/
static public function Get($channel_id, $perm = '') {
/**
* @brief Get a channel's permission limits.
*
* Return a channel's permission limits from PConfig. If $perm is set just
* return this permission limit, if not set, return an array with all
* permission limits.
*
* @param int $channel_id
* @param string $perm (optional)
* @return
* * \b false if no perm_limits set for this channel
* * \b int if $perm is set, return one of PERMS_* constants for this permission, default 0
* * \b array with all permission limits, if $perm is not set
*/
public static function Get($channel_id, $perm = '')
{
if (! intval($channel_id)) {
return false;
}
if (! intval($channel_id)) {
return false;
}
if($perm) {
$x = PConfig::Get($channel_id, 'perm_limits', $perm);
if($x === false) {
$a = [ 'channel_id' => $channel_id, 'permission' => $perm, 'value' => $x ];
call_hooks('permission_limits_get',$a);
return intval($a['value']);
}
return intval($x);
}
if ($perm) {
$x = PConfig::Get($channel_id, 'perm_limits', $perm);
if ($x === false) {
$a = [ 'channel_id' => $channel_id, 'permission' => $perm, 'value' => $x ];
call_hooks('permission_limits_get', $a);
return intval($a['value']);
}
return intval($x);
}
PConfig::Load($channel_id);
if(array_key_exists($channel_id, App::$config) && array_key_exists('perm_limits', App::$config[$channel_id])) {
return App::$config[$channel_id]['perm_limits'];
}
PConfig::Load($channel_id);
if (array_key_exists($channel_id, App::$config) && array_key_exists('perm_limits', App::$config[$channel_id])) {
return App::$config[$channel_id]['perm_limits'];
}
return false;
}
return false;
}
}

View file

@ -7,193 +7,197 @@ namespace Zotlabs\Access;
*
* @see Permissions
*/
class PermissionRoles {
class PermissionRoles
{
/**
* @brief PermissionRoles version.
*
* This must match the version in Permissions.php before permission updates can run.
*
* @return number
*/
static public function version() {
return 3;
}
/**
* @brief PermissionRoles version.
*
* This must match the version in Permissions.php before permission updates can run.
*
* @return number
*/
public static function version()
{
return 3;
}
static function role_perms($role) {
public static function role_perms($role)
{
$ret = [];
$ret = [];
$ret['role'] = $role;
$ret['role'] = $role;
switch($role) {
case 'social':
$ret['perms_auto'] = false;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
switch ($role) {
case 'social':
$ret['perms_auto'] = false;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
case 'social_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
break;
case 'social_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
break;
case 'forum':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'write_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
case 'forum':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'write_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;
break;
case 'forum_moderated':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments', 'moderated'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
case 'forum_moderated':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments', 'moderated'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;
break;
case 'forum_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'write_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['channel_type'] = 'group';
break;
case 'forum_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'write_storage',
'view_pages', 'post_mail', 'post_wall', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['channel_type'] = 'group';
break;
case 'collection':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_mail', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'collection';
case 'collection':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_mail', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'collection';
break;
break;
case 'collection_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_storage',
'view_pages', 'post_mail', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['channel_type'] = 'collection';
break;
case 'collection_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_storage',
'view_pages', 'post_mail', 'post_comments'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['channel_type'] = 'collection';
break;
case 'feed':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments',
'republish'
];
$ret['limits'] = PermissionLimits::Std_Limits();
case 'feed':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_mail', 'post_wall', 'post_comments',
'republish'
];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
break;
case 'repository':
// Legacy settings to cover all channel_types previously in Libzot.php
$ret['channel_type'] = 'group';
case 'repository':
// Legacy settings to cover all channel_types previously in Libzot.php
$ret['channel_type'] = 'group';
default:
break;
}
default:
break;
}
$x = get_config('system','role_perms');
// let system settings over-ride any or all
if($x && is_array($x) && array_key_exists($role,$x))
$ret = array_merge($ret,$x[$role]);
$x = get_config('system', 'role_perms');
// let system settings over-ride any or all
if ($x && is_array($x) && array_key_exists($role, $x)) {
$ret = array_merge($ret, $x[$role]);
}
/**
* @hooks get_role_perms
* * \e array
*/
$x = [ 'role' => $role, 'result' => $ret ];
/**
* @hooks get_role_perms
* * \e array
*/
$x = ['role' => $role, 'result' => $ret];
call_hooks('get_role_perms', $x);
call_hooks('get_role_perms', $x);
return $x['result'];
}
return $x['result'];
}
/**
* @brief Array with translated role names and grouping.
*
* Return an associative array with grouped role names that can be used
* to create select groups like in \e field_select_grouped.tpl.
*
* @return array
*/
static public function roles() {
$roles = [
t('Social Networking') => [
'social' => t('Social - Normal'),
'social_restricted' => t('Social - Restricted')
],
/**
* @brief Array with translated role names and grouping.
*
* Return an associative array with grouped role names that can be used
* to create select groups like in \e field_select_grouped.tpl.
*
* @return array
*/
public static function roles()
{
$roles = [
t('Social Networking') => [
'social' => t('Social - Normal'),
'social_restricted' => t('Social - Restricted')
],
t('Community Group') => [
'forum' => t('Group - Normal'),
'forum_restricted' => t('Group - Restricted'),
'forum_moderated' => t('Group - Moderated')
],
t('Community Group') => [
'forum' => t('Group - Normal'),
'forum_restricted' => t('Group - Restricted'),
'forum_moderated' => t('Group - Moderated')
],
t('Collection') => [
'collection' => t('Collection - Normal'),
'collection_restricted' => t('Collection - Restricted')
]
t('Collection') => [
'collection' => t('Collection - Normal'),
'collection_restricted' => t('Collection - Restricted')
]
];
];
call_hooks('list_permission_roles',$roles);
return $roles;
}
call_hooks('list_permission_roles', $roles);
return $roles;
}
}

View file

@ -31,252 +31,266 @@ use Zotlabs\Lib as Zlib;
* something different for a specific permission within the given role.
*
*/
class Permissions {
class Permissions
{
/**
* @brief Permissions version.
*
* This must match the version in PermissionRoles.php before permission updates can run.
*
* @return number
*/
static public function version() {
return 3;
}
/**
* @brief Permissions version.
*
* This must match the version in PermissionRoles.php before permission updates can run.
*
* @return number
*/
public static function version()
{
return 3;
}
/**
* @brief Return an array with Permissions.
*
* @param string $filter (optional) only passed to hook permissions_list
* @return array Associative array with permissions and short description.
*/
static public function Perms($filter = '') {
/**
* @brief Return an array with Permissions.
*
* @param string $filter (optional) only passed to hook permissions_list
* @return array Associative array with permissions and short description.
*/
public static function Perms($filter = '')
{
$perms = [
'view_stream' => t('Grant viewing access to and delivery of your channel stream and posts'),
'view_profile' => t('Grant viewing access to your default channel profile'),
'view_contacts' => t('Grant viewing access to your address book (connections)'),
'view_storage' => t('Grant viewing access to your file storage and photos'),
'post_wall' => t('Grant permission to post on your channel (wall) page'),
'post_mail' => t('Accept delivery of direct messages and personal mail'),
'send_stream' => t('Accept delivery of their posts and all comments to their posts'),
'post_comments' => t('Accept delivery of their comments and likes on your posts'),
'write_storage' => t('Grant upload permissions to your file storage and photos'),
'republish' => t('Grant permission to republish/mirror your posts'),
'moderated' => t('Accept comments and wall posts only after approval (moderation)'),
'delegate' => t('Grant channel administration (delegation) permission')
];
$perms = [
'view_stream' => t('Grant viewing access to and delivery of your channel stream and posts'),
'view_profile' => t('Grant viewing access to your default channel profile'),
'view_contacts' => t('Grant viewing access to your address book (connections)'),
'view_storage' => t('Grant viewing access to your file storage and photos'),
'post_wall' => t('Grant permission to post on your channel (wall) page'),
'post_mail' => t('Accept delivery of direct messages and personal mail'),
'send_stream' => t('Accept delivery of their posts and all comments to their posts'),
'post_comments' => t('Accept delivery of their comments and likes on your posts'),
'write_storage' => t('Grant upload permissions to your file storage and photos'),
'republish' => t('Grant permission to republish/mirror your posts'),
'moderated' => t('Accept comments and wall posts only after approval (moderation)'),
'delegate' => t('Grant channel administration (delegation) permission')
];
$x = [
'permissions' => $perms,
'filter' => $filter
];
/**
* @hooks permissions_list
* * \e array \b permissions
* * \e string \b filter
*/
call_hooks('permissions_list', $x);
$x = [
'permissions' => $perms,
'filter' => $filter
];
/**
* @hooks permissions_list
* * \e array \b permissions
* * \e string \b filter
*/
call_hooks('permissions_list', $x);
return($x['permissions']);
}
return($x['permissions']);
}
/**
* @brief Perms from the above list that are blocked from anonymous observers.
*
* e.g. you must be authenticated.
*
* @return array Associative array with permissions and short description.
*/
static public function BlockedAnonPerms() {
/**
* @brief Perms from the above list that are blocked from anonymous observers.
*
* e.g. you must be authenticated.
*
* @return array Associative array with permissions and short description.
*/
public static function BlockedAnonPerms()
{
$res = [];
$perms = PermissionLimits::Std_limits();
foreach($perms as $perm => $limit) {
if($limit != PERMS_PUBLIC) {
$res[] = $perm;
}
}
$res = [];
$perms = PermissionLimits::Std_limits();
foreach ($perms as $perm => $limit) {
if ($limit != PERMS_PUBLIC) {
$res[] = $perm;
}
}
$x = ['permissions' => $res];
/**
* @hooks write_perms
* * \e array \b permissions
*/
call_hooks('write_perms', $x);
$x = ['permissions' => $res];
/**
* @hooks write_perms
* * \e array \b permissions
*/
call_hooks('write_perms', $x);
return($x['permissions']);
}
return($x['permissions']);
}
/**
* @brief Converts indexed perms array to associative perms array.
*
* Converts [ 0 => 'view_stream', ... ]
* to [ 'view_stream' => 1 ] for any permissions in $arr;
* Undeclared permissions which exist in Perms() are added and set to 0.
*
* @param array $arr
* @return array
*/
static public function FilledPerms($arr) {
if(is_null($arr) || (! is_array($arr))) {
btlogger('FilledPerms: ' . print_r($arr,true));
$arr = [];
}
/**
* @brief Converts indexed perms array to associative perms array.
*
* Converts [ 0 => 'view_stream', ... ]
* to [ 'view_stream' => 1 ] for any permissions in $arr;
* Undeclared permissions which exist in Perms() are added and set to 0.
*
* @param array $arr
* @return array
*/
public static function FilledPerms($arr)
{
if (is_null($arr) || (! is_array($arr))) {
btlogger('FilledPerms: ' . print_r($arr, true));
$arr = [];
}
$everything = self::Perms();
$ret = [];
foreach($everything as $k => $v) {
if(in_array($k, $arr))
$ret[$k] = 1;
else
$ret[$k] = 0;
}
$everything = self::Perms();
$ret = [];
foreach ($everything as $k => $v) {
if (in_array($k, $arr)) {
$ret[$k] = 1;
} else {
$ret[$k] = 0;
}
}
return $ret;
}
return $ret;
}
/**
* @brief Convert perms array to indexed array.
*
* Converts [ 'view_stream' => 1 ] for any permissions in $arr
* to [ 0 => ['name' => 'view_stream', 'value' => 1], ... ]
*
* @param array $arr associative perms array 'view_stream' => 1
* @return array Indexed array with elements that look like
* * \e string \b name the perm name (e.g. view_stream)
* * \e int \b value the value of the perm (e.g. 1)
*/
static public function OPerms($arr) {
$ret = [];
if($arr) {
foreach($arr as $k => $v) {
$ret[] = [ 'name' => $k, 'value' => $v ];
}
}
return $ret;
}
/**
* @brief Convert perms array to indexed array.
*
* Converts [ 'view_stream' => 1 ] for any permissions in $arr
* to [ 0 => ['name' => 'view_stream', 'value' => 1], ... ]
*
* @param array $arr associative perms array 'view_stream' => 1
* @return array Indexed array with elements that look like
* * \e string \b name the perm name (e.g. view_stream)
* * \e int \b value the value of the perm (e.g. 1)
*/
public static function OPerms($arr)
{
$ret = [];
if ($arr) {
foreach ($arr as $k => $v) {
$ret[] = [ 'name' => $k, 'value' => $v ];
}
}
return $ret;
}
/**
* @brief
*
* @param int $channel_id
* @return boolean|array
*/
static public function FilledAutoperms($channel_id) {
if(! intval(get_pconfig($channel_id,'system','autoperms')))
return false;
/**
* @brief
*
* @param int $channel_id
* @return bool|array
*/
public static function FilledAutoperms($channel_id)
{
if (! intval(get_pconfig($channel_id, 'system', 'autoperms'))) {
return false;
}
$arr = [];
$r = q("select * from pconfig where uid = %d and cat = 'autoperms'",
intval($channel_id)
);
if($r) {
foreach($r as $rr) {
$arr[$rr['k']] = intval($rr['v']);
}
}
return $arr;
}
$arr = [];
$r = q(
"select * from pconfig where uid = %d and cat = 'autoperms'",
intval($channel_id)
);
if ($r) {
foreach ($r as $rr) {
$arr[$rr['k']] = intval($rr['v']);
}
}
return $arr;
}
/**
* @brief Compares that all Permissions from $p1 exist also in $p2.
*
* @param array $p1 The perms that have to exist in $p2
* @param array $p2 The perms to compare against
* @return boolean true if all perms from $p1 exist also in $p2
*/
static public function PermsCompare($p1, $p2) {
foreach($p1 as $k => $v) {
if(! array_key_exists($k, $p2))
return false;
/**
* @brief Compares that all Permissions from $p1 exist also in $p2.
*
* @param array $p1 The perms that have to exist in $p2
* @param array $p2 The perms to compare against
* @return bool true if all perms from $p1 exist also in $p2
*/
public static function PermsCompare($p1, $p2)
{
foreach ($p1 as $k => $v) {
if (! array_key_exists($k, $p2)) {
return false;
}
if($p1[$k] != $p2[$k])
return false;
}
if ($p1[$k] != $p2[$k]) {
return false;
}
}
return true;
}
return true;
}
/**
* @brief
*
* @param int $channel_id A channel id
* @return array Associative array with
* * \e array \b perms Permission array
* * \e int \b automatic 0 or 1
*/
static public function connect_perms($channel_id) {
/**
* @brief
*
* @param int $channel_id A channel id
* @return array Associative array with
* * \e array \b perms Permission array
* * \e int \b automatic 0 or 1
*/
public static function connect_perms($channel_id)
{
$my_perms = [];
$permcat = null;
$automatic = 0;
$my_perms = [];
$permcat = null;
$automatic = 0;
// If a default permcat exists, use that
// If a default permcat exists, use that
$pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
if(! in_array($pc, [ '','default' ])) {
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
if($permcat && $permcat['perms']) {
foreach($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
}
}
$pc = ((feature_enabled($channel_id, 'permcats')) ? get_pconfig($channel_id, 'system', 'default_permcat') : 'default');
if (! in_array($pc, [ '','default' ])) {
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
if ($permcat && $permcat['perms']) {
foreach ($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
}
}
$automatic = intval(get_pconfig($channel_id,'system','autoperms'));
$automatic = intval(get_pconfig($channel_id, 'system', 'autoperms'));
// look up the permission role to see if it specified auto-connect
// and if there was no permcat or a default permcat, set the perms
// from the role
// look up the permission role to see if it specified auto-connect
// and if there was no permcat or a default permcat, set the perms
// from the role
$role = get_pconfig($channel_id,'system','permissions_role');
if($role) {
$xx = PermissionRoles::role_perms($role);
$role = get_pconfig($channel_id, 'system', 'permissions_role');
if ($role) {
$xx = PermissionRoles::role_perms($role);
if((! $my_perms) && ($xx['perms_connect'])) {
$default_perms = $xx['perms_connect'];
$my_perms = Permissions::FilledPerms($default_perms);
}
}
if ((! $my_perms) && ($xx['perms_connect'])) {
$default_perms = $xx['perms_connect'];
$my_perms = Permissions::FilledPerms($default_perms);
}
}
// If we reached this point without having any permission information,
// it is likely a custom permissions role. First see if there are any
// automatic permissions.
// If we reached this point without having any permission information,
// it is likely a custom permissions role. First see if there are any
// automatic permissions.
if(! $my_perms) {
$m = Permissions::FilledAutoperms($channel_id);
if($m) {
$my_perms = $m;
}
}
if (! $my_perms) {
$m = Permissions::FilledAutoperms($channel_id);
if ($m) {
$my_perms = $m;
}
}
// If we reached this point with no permissions, the channel is using
// custom perms but they are not automatic. They will be stored in abconfig with
// the channel's channel_hash (the 'self' connection).
// If we reached this point with no permissions, the channel is using
// custom perms but they are not automatic. They will be stored in abconfig with
// the channel's channel_hash (the 'self' connection).
if(! $my_perms) {
$c = channelx_by_n($channel_id);
if($c) {
$my_perms = Permissions::FilledPerms(explode(',',get_abconfig($channel_id,$c['channel_hash'],'system','my_perms',EMPTY_STR)));
}
}
if (! $my_perms) {
$c = channelx_by_n($channel_id);
if ($c) {
$my_perms = Permissions::FilledPerms(explode(',', get_abconfig($channel_id, $c['channel_hash'], 'system', 'my_perms', EMPTY_STR)));
}
}
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
}
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
}
static public function serialise($p) {
$n = [];
if($p) {
foreach($p as $k => $v) {
if(intval($v)) {
$n[] = $k;
}
}
}
return implode(',',$n);
}
public static function serialise($p)
{
$n = [];
if ($p) {
foreach ($p as $k => $v) {
if (intval($v)) {
$n[] = $k;
}
}
}
return implode(',', $n);
}
}

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Addon {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
call_hooks('daemon_addon',$argv);

View file

@ -6,7 +6,7 @@ require_once('include/photos.php');
class CacheThumb {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if (! $argc == 2) {
return;

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Cache_embeds {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if (! $argc == 2) {
return;

View file

@ -6,7 +6,7 @@ use Zotlabs\Lib\Img_cache;
class Cache_image {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
cli_startup();
logger('caching: ' . $argv[1] . ' to ' . $argv[2]);

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Channel_purge {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
cli_startup();

View file

@ -7,7 +7,7 @@ require_once('include/hubloc.php');
class Checksites {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
logger('checksites: start');

View file

@ -10,7 +10,7 @@ require_once('include/import.php');
class Content_importer {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
cli_startup();
$page = $argv[1];

View file

@ -8,7 +8,7 @@ use Zotlabs\Lib\ASCollection;
class Convo {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
logger('convo invoked: ' . print_r($argv,true));

View file

@ -6,7 +6,7 @@ use Zotlabs\Lib\Libsync;
class Cron {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)

View file

@ -6,7 +6,7 @@ use Zotlabs\Lib\Libzot;
class Cron_daily {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
logger('cron_daily: start');

View file

@ -4,7 +4,7 @@ namespace Zotlabs\Daemon;
class Cron_weekly {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
/**
* Cron Weekly

View file

@ -4,7 +4,7 @@ namespace Zotlabs\Daemon;
class Cronhooks {
static public function run($argc,$argv){
public static function run($argc, $argv){
logger('cronhooks: start');

View file

@ -12,7 +12,7 @@ use App;
class CurlAuth {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if($argc != 2)
return;

View file

@ -8,7 +8,7 @@ use Zotlabs\Lib\Queue;
class Deliver {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if($argc < 2)
return;

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Deliver_hooks {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if($argc < 2)
return;

View file

@ -8,7 +8,7 @@ namespace Zotlabs\Daemon;
class Delxitems {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
cli_startup();

View file

@ -11,7 +11,7 @@ use Zotlabs\Lib\Queue;
class Directory {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if ($argc < 2) {
return;

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Expire {
static public function run($argc,$argv){
public static function run($argc, $argv){
cli_startup();

View file

@ -10,7 +10,7 @@ require_once('include/import.php');
class File_importer {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
cli_startup();

View file

@ -10,7 +10,7 @@ use Zotlabs\Lib\Zotfinger;
class Gprobe {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if ($argc != 2) {

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Importdoc {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
require_once('include/help.php');
@ -13,7 +13,7 @@ class Importdoc {
}
static public function update_docs_dir($s) {
public static function update_docs_dir($s) {
$f = basename($s);
$d = dirname($s);
if($s === 'doc/html')

View file

@ -6,7 +6,7 @@ use Zotlabs\Lib\Libsync;
class Importfile {
static public function run($argc,$argv){
public static function run($argc, $argv){
logger('Importfile: ' . print_r($argv,true));

View file

@ -78,16 +78,16 @@ require_once('include/bbcode.php');
class Notifier {
static public $deliveries = [];
static public $recipients = [];
static public $env_recips = [];
static public $packet_type = 'activity';
static public $encoding = 'activitystreams';
static public $encoded_item = null;
static public $channel = null;
static public $private = false;
public static $deliveries = [];
public static $recipients = [];
public static $env_recips = [];
public static $packet_type = 'activity';
public static $encoding = 'activitystreams';
public static $encoded_item = null;
public static $channel = null;
public static $private = false;
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if ($argc < 3) {
return;

View file

@ -7,7 +7,7 @@ use Zotlabs\Lib\Libzotdir;
class Onedirsync {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
logger('onedirsync: start ' . intval($argv[1]));

View file

@ -13,7 +13,7 @@ require_once('include/socgraph.php');
class Onepoll {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
logger('onepoll: start');

View file

@ -4,7 +4,7 @@ namespace Zotlabs\Daemon;
class Poller {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)

View file

@ -7,7 +7,7 @@ use Zotlabs\Lib as Zlib;
class Queue {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if($argc > 1)
$queue_id = $argv[1];

View file

@ -27,7 +27,7 @@ class Run {
'Cron', 'Cron_daily', 'Cron_weekly', 'Delxitems', 'Expire', 'File_importer', 'Importfile'
];
static public function Summon($arr) {
public static function Summon($arr) {
if (file_exists('maintenance_lock') || file_exists('cache/maintenance_lock')) {
return;
}
@ -50,7 +50,7 @@ class Run {
proc_run('php','Zotlabs/Daemon/Run.php',$arr);
}
static public function Release($argc,$argv) {
public static function Release($argc, $argv) {
cli_startup();
$hookinfo = [

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Thumbnail {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if (! ($argc == 2)) {
return;

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Xchan_photo {
static public function run($argc,$argv) {
public static function run($argc, $argv) {
if ($argc != 3) {
return;

View file

@ -10,7 +10,7 @@ use App;
*/
class Hook {
static public function register($hook,$file,$function,$version = 1,$priority = 0) {
public static function register($hook, $file, $function, $version = 1, $priority = 0) {
if (is_array($function)) {
$function = serialize($function);
}
@ -46,7 +46,7 @@ class Hook {
return $r;
}
static public function register_array($file,$arr) {
public static function register_array($file, $arr) {
if ($arr) {
foreach ($arr as $k => $v) {
self::register($k,$file,$v);
@ -55,7 +55,7 @@ class Hook {
}
static public function unregister($hook,$file,$function,$version = 1,$priority = 0) {
public static function unregister($hook, $file, $function, $version = 1, $priority = 0) {
if (is_array($function)) {
$function = serialize($function);
}
@ -78,7 +78,7 @@ class Hook {
* @param string $file
*/
static public function unregister_by_file($file) {
public static function unregister_by_file($file) {
$r = q("DELETE FROM hook WHERE file = '%s' ",
dbesc($file)
);
@ -107,7 +107,7 @@ class Hook {
* @param int $priority
* currently not implemented in this function, would require the hook array to be resorted
*/
static public function insert($hook, $fn, $version = 0, $priority = 0) {
public static function insert($hook, $fn, $version = 0, $priority = 0) {
if (is_array($fn)) {
$fn = serialize($fn);
}

View file

@ -3,46 +3,52 @@
namespace Zotlabs\Extend;
class Route {
class Route
{
static function register($file,$modname) {
$rt = self::get();
$rt[] = [ $file, $modname ];
self::set($rt);
}
public static function register($file, $modname)
{
$rt = self::get();
$rt[] = [$file, $modname];
self::set($rt);
}
static function unregister($file,$modname) {
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file && $r[1] !== $modname) {
$n[] = $r;
}
}
self::set($n);
}
}
public static function unregister($file, $modname)
{
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file && $r[1] !== $modname) {
$n[] = $r;
}
}
self::set($n);
}
}
static function unregister_by_file($file) {
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file) {
$n[] = $r;
}
}
self::set($n);
}
}
public static function unregister_by_file($file)
{
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file) {
$n[] = $r;
}
}
self::set($n);
}
}
static function get() {
return get_config('system','routes',[]);
}
public static function get()
{
return get_config('system', 'routes', []);
}
static function set($r) {
return set_config('system','routes',$r);
}
public static function set($r)
{
return set_config('system', 'routes', $r);
}
}

View file

@ -3,45 +3,51 @@
namespace Zotlabs\Extend;
class Widget {
class Widget
{
static function register($file,$widget) {
$rt = self::get();
$rt[] = [ $file, $widget ];
self::set($rt);
}
public static function register($file, $widget)
{
$rt = self::get();
$rt[] = [$file, $widget];
self::set($rt);
}
static function unregister($file,$widget) {
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file && $r[1] !== $widget) {
$n[] = $r;
}
}
self::set($n);
}
}
public static function unregister($file, $widget)
{
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file && $r[1] !== $widget) {
$n[] = $r;
}
}
self::set($n);
}
}
static function unregister_by_file($file) {
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file) {
$n[] = $r;
}
}
self::set($n);
}
}
public static function unregister_by_file($file)
{
$rt = self::get();
if ($rt) {
$n = [];
foreach ($rt as $r) {
if ($r[0] !== $file) {
$n[] = $r;
}
}
self::set($n);
}
}
static function get() {
return get_config('system','widgets',[]);
}
public static function get()
{
return get_config('system', 'widgets', []);
}
static function set($r) {
return set_config('system','widgets',$r);
}
public static function set($r)
{
return set_config('system', 'widgets', $r);
}
}

View file

@ -12,352 +12,353 @@ use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Run;
class Friendica {
class Friendica
{
private $data;
private $settings;
private $data;
private $settings;
private $default_group = null;
private $default_group = null;
private $groups = null;
private $members = null;
private $contacts = null;
private $groups = null;
private $members = null;
private $contacts = null;
function __construct($data, $settings) {
$this->data = $data;
$this->settings = $settings;
$this->extract();
}
function extract() {
// channel stuff
$channel = [
'channel_name' => escape_tags($this->data['user']['username']),
'channel_address' => escape_tags($this->data['user']['nickname']),
'channel_guid' => escape_tags($this->data['user']['guid']),
'channel_guid_sig' => Libzot::sign($this->data['user']['guid'],$this->data['user']['prvkey']),
'channel_hash' => Libzot::make_xchan_hash($this->data['user']['guid'],$this->data['user']['pubkey']),
'channel_prvkey' => $this->data['user']['prvkey'],
'channel_pubkey' => $this->data['user']['pubkey'],
'channel_pageflags' => PAGE_NORMAL,
'channel_expire_days' => intval($this->data['user']['expire']),
'channel_timezone' => escape_tags($this->data['user']['timezone']),
'channel_location' => escape_tags($this->data['user']['default-location'])
];
$account_id = $this->settings['account_id'];
$max_identities = account_service_class_fetch($account_id,'total_identities');
if ($max_identities !== false) {
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 ",
intval($account_id)
);
if ($r && count($r) > $max_identities) {
notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
return;
}
}
// save channel or die
$channel = import_channel($channel,$this->settings['account_id'],$this->settings['sieze'],$this->settings['newname']);
if (! $channel) {
logger('no channel');
return;
}
// figure out channel permission roles
$permissions_role = 'social';
$pageflags = ((isset($this->data['user']['page-flags'])) ? intval($this->data['user']['page-flags']) : 0);
if ($pageflags === 2) {
$permissions_role = 'forum';
}
if ($pageflags === 5) {
$permissions_role = 'forum_restricted';
}
if ($pageflags === 0 && isset($this->data['user']['allow_gid']) && $this->data['user']['allow_gid']) {
$permissions_role = 'social_restricted';
}
// Friendica folks only have PERMS_AUTHED and "just me"
$post_comments = (($pageflags === 1) ? 0 : PERMS_AUTHED);
PermissionLimits::Set(local_channel(),'post_comments',$post_comments);
PConfig::Set($channel['channel_id'],'system','permissions_role',$permissions_role);
PConfig::Set($channel['channel_id'],'system','use_browser_location', (string) intval($this->data['user']['allow_location']));
// find the self contact
$self_contact = null;
if (isset($this->data['contact']) && is_array($this->data['contact'])) {
foreach ($this->data['contact'] as $contact) {
if (isset($contact['self']) && intval($contact['self'])) {
$self_contact = $contact;
break;
}
}
}
if (! is_array($self_contact)) {
logger('self contact not found.');
return;
}
// Create a verified hub location pointing to this site.
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_id_url' => channel_url($channel),
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_primary' => 1,
'hubloc_url' => z_root(),
'hubloc_url_sig' => Libzot::sign(z_root(),$channel['channel_prvkey']),
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(),get_config('system','pubkey')),
'hubloc_host' => App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_network' => 'zot6',
'hubloc_updated' => datetime_convert()
]
);
if (! $r) {
logger('Unable to store hub location');
}
if ($self_contact['avatar']) {
$p = z_fetch_url($self_contact['avatar'],true);
if ($p['success']) {
$h = explode("\n",$p['header']);
foreach ($h as $l) {
list($k,$v) = array_map("trim", explode(":", trim($l), 2));
$hdrs[strtolower($k)] = $v;
}
if (array_key_exists('content-type', $hdrs)) {
$phototype = $hdrs['content-type'];
}
else {
$phototype = 'image/jpeg';
}
import_channel_photo($p['body'],$phototype,$account_id,$channel['channel_id']);
}
}
$newuid = $channel['channel_id'];
$r = xchan_store_lowlevel(
[
'xchan_hash' => $channel['channel_hash'],
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_mimetype' => (($photo_type) ? $photo_type : 'image/png'),
'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}",
'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}",
'xchan_photo_s' => z_root() . "/photo/profile/s/{$newuid}",
'xchan_addr' => channel_reddress($channel),
'xchan_url' => channel_url($channel),
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot6',
'xchan_updated' => datetime_convert(),
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert(),
'xchan_system' => 0
]
);
$r = profile_store_lowlevel(
[
'aid' => intval($channel['channel_account_id']),
'uid' => intval($newuid),
'profile_guid' => new_uuid(),
'profile_name' => t('Default Profile'),
'is_default' => 1,
'publish' => ((isset($this->data['profile']['publish'])) ? $this->data['profile']['publish'] : 1),
'fullname' => $channel['channel_name'],
'photo' => z_root() . "/photo/profile/l/{$newuid}",
'thumb' => z_root() . "/photo/profile/m/{$newuid}",
'homepage' => ((isset($this->data['profile']['homepage'])) ? $this->data['profile']['homepage'] : EMPTY_STR),
]
);
if($role_permissions) {
$myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : [] );
}
else {
$x = PermissionRoles::role_perms('social');
$myperms = $x['perms_connect'];
}
$r = abook_store_lowlevel(
[
'abook_account' => intval($channel['channel_account_id']),
'abook_channel' => intval($newuid),
'abook_xchan' => $channel['channel_hash'],
'abook_closeness' => 0,
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_self' => 1
]
);
$x = Permissions::serialise(Permissions::FilledPerms($myperms));
set_abconfig($newuid,$channel['channel_hash'],'system','my_perms',$x);
if(intval($channel['channel_account_id'])) {
// Save our permissions role so we can perhaps call it up and modify it later.
if($role_permissions) {
if(array_key_exists('online',$role_permissions))
set_pconfig($newuid,'system','hide_presence',1-intval($role_permissions['online']));
if(array_key_exists('perms_auto',$role_permissions)) {
$autoperms = intval($role_permissions['perms_auto']);
set_pconfig($newuid,'system','autoperms',$autoperms);
}
}
// Create a group with yourself as a member. This allows somebody to use it
// right away as a default group for new contacts.
AccessList::add($newuid, t('Friends'));
AccessList::member_add($newuid,t('Friends'),$ret['channel']['channel_hash']);
// if our role_permissions indicate that we're using a default collection ACL, add it.
if(is_array($role_permissions) && $role_permissions['default_collection']) {
$r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1",
intval($newuid),
dbesc( t('Friends') )
);
if($r) {
q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d",
dbesc($r[0]['hash']),
dbesc('<' . $r[0]['hash'] . '>'),
intval($newuid)
);
}
}
set_pconfig($channel['channel_id'],'system','photo_path', '%Y/%Y-%m');
set_pconfig($channel['channel_id'],'system','attach_path','%Y/%Y-%m');
// auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big
// or it will impact registration time.
$accts = get_config('system','auto_follow');
if(($accts) && (! $total_identities)) {
if(! is_array($accts))
$accts = array($accts);
foreach($accts as $acct) {
if(trim($acct)) {
$f = connect_and_sync($channel,trim($acct));
if($f['success']) {
$can_view_stream = their_perms_contains($channel['channel_id'],$f['abook']['abook_xchan'],'view_stream');
// If we can view their stream, pull in some posts
if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) {
Run::Summon([ 'Onepoll',$f['abook']['abook_id'] ]);
}
}
}
}
}
call_hooks('create_identity', $newuid);
}
$this->groups = ((isset($this->data['group'])) ? $this->data['group'] : null);
$this->members = ((isset($this->data['group_member'])) ? $this->data['group_member'] : null);
// import contacts
if (isset($this->data['contact']) && is_array($this->data['contact'])) {
foreach ($this->data['contact'] as $contact) {
if (isset($contact['self']) && intval($contact['self'])) {
continue;
}
logger('connecting: ' . $contact['url'], LOGGER_DEBUG);
$result = Connect::connect($channel,(($contact['addr']) ? $contact['addr'] : $contact['url']));
if ($result['success'] && isset($result['abook'])) {
$contact['xchan_hash'] = $result['abook']['abook_xchan'];
$this->contacts[] = $contact;
}
}
}
// import pconfig
// it is unlikely we can make use of these unless we recongise them.
if (isset($this->data['pconfig']) && is_array($this->data['pconfig'])) {
foreach ($this->data['pconfig'] as $pc) {
$entry = [
'cat' => escape_tags(str_replace('.','__',$pc['cat'])),
'k' => escape_tags(str_replace('.','__',$pc['k'])),
'v' => ((preg_match('|^a:[0-9]+:{.*}$|s', $pc['v'])) ? serialise(unserialize($pc['v'])) : $pc['v']),
];
PConfig::Set($channel['channel_id'],$entry['cat'],$entry['k'],$entry['v']);
}
}
// The default 'Friends' group is already created and possibly populated.
// So some of the following code is redundant in that regard.
// Mostly this is used to create and populate any other groups.
if ($this->groups) {
foreach ($this->groups as $group) {
if (! intval($group['deleted'])) {
AccessList::add($channel['channel_id'], $group['name'], intval($group['visible']));
if ($this->members) {
foreach ($this->members as $member) {
if (intval($member['gid']) === intval(AccessList::byname($channel['channel_id'],$group['name']))) {
$contact_id = $member['contact-id'];
if ($this->contacts) {
foreach ($this->contacts as $contact) {
if (intval($contact['id']) === intval($contact_id)) {
AccessList::member_add($channel['channel_id'],$group['name'],$contact['xchan_hash']);
break;
}
}
}
}
}
}
}
}
}
change_channel($channel['channel_id']);
notice( t('Import complete.') . EOL);
goaway(z_root() . '/stream' );
}
public function __construct($data, $settings)
{
$this->data = $data;
$this->settings = $settings;
$this->extract();
}
public function extract()
{
// channel stuff
$channel = [
'channel_name' => escape_tags($this->data['user']['username']),
'channel_address' => escape_tags($this->data['user']['nickname']),
'channel_guid' => escape_tags($this->data['user']['guid']),
'channel_guid_sig' => Libzot::sign($this->data['user']['guid'], $this->data['user']['prvkey']),
'channel_hash' => Libzot::make_xchan_hash($this->data['user']['guid'], $this->data['user']['pubkey']),
'channel_prvkey' => $this->data['user']['prvkey'],
'channel_pubkey' => $this->data['user']['pubkey'],
'channel_pageflags' => PAGE_NORMAL,
'channel_expire_days' => intval($this->data['user']['expire']),
'channel_timezone' => escape_tags($this->data['user']['timezone']),
'channel_location' => escape_tags($this->data['user']['default-location'])
];
$account_id = $this->settings['account_id'];
$max_identities = account_service_class_fetch($account_id, 'total_identities');
if ($max_identities !== false) {
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 ",
intval($account_id)
);
if ($r && count($r) > $max_identities) {
notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL);
return;
}
}
// save channel or die
$channel = import_channel($channel, $this->settings['account_id'], $this->settings['sieze'], $this->settings['newname']);
if (!$channel) {
logger('no channel');
return;
}
// figure out channel permission roles
$permissions_role = 'social';
$pageflags = ((isset($this->data['user']['page-flags'])) ? intval($this->data['user']['page-flags']) : 0);
if ($pageflags === 2) {
$permissions_role = 'forum';
}
if ($pageflags === 5) {
$permissions_role = 'forum_restricted';
}
if ($pageflags === 0 && isset($this->data['user']['allow_gid']) && $this->data['user']['allow_gid']) {
$permissions_role = 'social_restricted';
}
// Friendica folks only have PERMS_AUTHED and "just me"
$post_comments = (($pageflags === 1) ? 0 : PERMS_AUTHED);
PermissionLimits::Set(local_channel(), 'post_comments', $post_comments);
PConfig::Set($channel['channel_id'], 'system', 'permissions_role', $permissions_role);
PConfig::Set($channel['channel_id'], 'system', 'use_browser_location', (string)intval($this->data['user']['allow_location']));
// find the self contact
$self_contact = null;
if (isset($this->data['contact']) && is_array($this->data['contact'])) {
foreach ($this->data['contact'] as $contact) {
if (isset($contact['self']) && intval($contact['self'])) {
$self_contact = $contact;
break;
}
}
}
if (!is_array($self_contact)) {
logger('self contact not found.');
return;
}
// Create a verified hub location pointing to this site.
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_id_url' => channel_url($channel),
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_primary' => 1,
'hubloc_url' => z_root(),
'hubloc_url_sig' => Libzot::sign(z_root(), $channel['channel_prvkey']),
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), get_config('system', 'pubkey')),
'hubloc_host' => App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_sitekey' => get_config('system', 'pubkey'),
'hubloc_network' => 'zot6',
'hubloc_updated' => datetime_convert()
]
);
if (!$r) {
logger('Unable to store hub location');
}
if ($self_contact['avatar']) {
$p = z_fetch_url($self_contact['avatar'], true);
if ($p['success']) {
$h = explode("\n", $p['header']);
foreach ($h as $l) {
list($k, $v) = array_map("trim", explode(":", trim($l), 2));
$hdrs[strtolower($k)] = $v;
}
if (array_key_exists('content-type', $hdrs)) {
$phototype = $hdrs['content-type'];
} else {
$phototype = 'image/jpeg';
}
import_channel_photo($p['body'], $phototype, $account_id, $channel['channel_id']);
}
}
$newuid = $channel['channel_id'];
$r = xchan_store_lowlevel(
[
'xchan_hash' => $channel['channel_hash'],
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_mimetype' => (($photo_type) ? $photo_type : 'image/png'),
'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}",
'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}",
'xchan_photo_s' => z_root() . "/photo/profile/s/{$newuid}",
'xchan_addr' => channel_reddress($channel),
'xchan_url' => channel_url($channel),
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot6',
'xchan_updated' => datetime_convert(),
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert(),
'xchan_system' => 0
]
);
$r = profile_store_lowlevel(
[
'aid' => intval($channel['channel_account_id']),
'uid' => intval($newuid),
'profile_guid' => new_uuid(),
'profile_name' => t('Default Profile'),
'is_default' => 1,
'publish' => ((isset($this->data['profile']['publish'])) ? $this->data['profile']['publish'] : 1),
'fullname' => $channel['channel_name'],
'photo' => z_root() . "/photo/profile/l/{$newuid}",
'thumb' => z_root() . "/photo/profile/m/{$newuid}",
'homepage' => ((isset($this->data['profile']['homepage'])) ? $this->data['profile']['homepage'] : EMPTY_STR),
]
);
if ($role_permissions) {
$myperms = ((array_key_exists('perms_connect', $role_permissions)) ? $role_permissions['perms_connect'] : []);
} else {
$x = PermissionRoles::role_perms('social');
$myperms = $x['perms_connect'];
}
$r = abook_store_lowlevel(
[
'abook_account' => intval($channel['channel_account_id']),
'abook_channel' => intval($newuid),
'abook_xchan' => $channel['channel_hash'],
'abook_closeness' => 0,
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_self' => 1
]
);
$x = Permissions::serialise(Permissions::FilledPerms($myperms));
set_abconfig($newuid, $channel['channel_hash'], 'system', 'my_perms', $x);
if (intval($channel['channel_account_id'])) {
// Save our permissions role so we can perhaps call it up and modify it later.
if ($role_permissions) {
if (array_key_exists('online', $role_permissions))
set_pconfig($newuid, 'system', 'hide_presence', 1 - intval($role_permissions['online']));
if (array_key_exists('perms_auto', $role_permissions)) {
$autoperms = intval($role_permissions['perms_auto']);
set_pconfig($newuid, 'system', 'autoperms', $autoperms);
}
}
// Create a group with yourself as a member. This allows somebody to use it
// right away as a default group for new contacts.
AccessList::add($newuid, t('Friends'));
AccessList::member_add($newuid, t('Friends'), $ret['channel']['channel_hash']);
// if our role_permissions indicate that we're using a default collection ACL, add it.
if (is_array($role_permissions) && $role_permissions['default_collection']) {
$r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1",
intval($newuid),
dbesc(t('Friends'))
);
if ($r) {
q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d",
dbesc($r[0]['hash']),
dbesc('<' . $r[0]['hash'] . '>'),
intval($newuid)
);
}
}
set_pconfig($channel['channel_id'], 'system', 'photo_path', '%Y/%Y-%m');
set_pconfig($channel['channel_id'], 'system', 'attach_path', '%Y/%Y-%m');
// auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big
// or it will impact registration time.
$accts = get_config('system', 'auto_follow');
if (($accts) && (!$total_identities)) {
if (!is_array($accts))
$accts = array($accts);
foreach ($accts as $acct) {
if (trim($acct)) {
$f = connect_and_sync($channel, trim($acct));
if ($f['success']) {
$can_view_stream = their_perms_contains($channel['channel_id'], $f['abook']['abook_xchan'], 'view_stream');
// If we can view their stream, pull in some posts
if (($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) {
Run::Summon(['Onepoll', $f['abook']['abook_id']]);
}
}
}
}
}
call_hooks('create_identity', $newuid);
}
$this->groups = ((isset($this->data['group'])) ? $this->data['group'] : null);
$this->members = ((isset($this->data['group_member'])) ? $this->data['group_member'] : null);
// import contacts
if (isset($this->data['contact']) && is_array($this->data['contact'])) {
foreach ($this->data['contact'] as $contact) {
if (isset($contact['self']) && intval($contact['self'])) {
continue;
}
logger('connecting: ' . $contact['url'], LOGGER_DEBUG);
$result = Connect::connect($channel, (($contact['addr']) ? $contact['addr'] : $contact['url']));
if ($result['success'] && isset($result['abook'])) {
$contact['xchan_hash'] = $result['abook']['abook_xchan'];
$this->contacts[] = $contact;
}
}
}
// import pconfig
// it is unlikely we can make use of these unless we recongise them.
if (isset($this->data['pconfig']) && is_array($this->data['pconfig'])) {
foreach ($this->data['pconfig'] as $pc) {
$entry = [
'cat' => escape_tags(str_replace('.', '__', $pc['cat'])),
'k' => escape_tags(str_replace('.', '__', $pc['k'])),
'v' => ((preg_match('|^a:[0-9]+:{.*}$|s', $pc['v'])) ? serialise(unserialize($pc['v'])) : $pc['v']),
];
PConfig::Set($channel['channel_id'], $entry['cat'], $entry['k'], $entry['v']);
}
}
// The default 'Friends' group is already created and possibly populated.
// So some of the following code is redundant in that regard.
// Mostly this is used to create and populate any other groups.
if ($this->groups) {
foreach ($this->groups as $group) {
if (!intval($group['deleted'])) {
AccessList::add($channel['channel_id'], $group['name'], intval($group['visible']));
if ($this->members) {
foreach ($this->members as $member) {
if (intval($member['gid']) === intval(AccessList::byname($channel['channel_id'], $group['name']))) {
$contact_id = $member['contact-id'];
if ($this->contacts) {
foreach ($this->contacts as $contact) {
if (intval($contact['id']) === intval($contact_id)) {
AccessList::member_add($channel['channel_id'], $group['name'], $contact['xchan_hash']);
break;
}
}
}
}
}
}
}
}
}
change_channel($channel['channel_id']);
notice(t('Import complete.') . EOL);
goaway(z_root() . '/stream');
}
}

View file

@ -6,19 +6,19 @@ namespace Zotlabs\Lib;
class AConfig {
static public function Load($account_id) {
public static function Load($account_id) {
return XConfig::Load('a_' . $account_id);
}
static public function Get($account_id,$family,$key,$default = false) {
public static function Get($account_id, $family, $key, $default = false) {
return XConfig::Get('a_' . $account_id,$family,$key, $default);
}
static public function Set($account_id,$family,$key,$value) {
public static function Set($account_id, $family, $key, $value) {
return XConfig::Set('a_' . $account_id,$family,$key,$value);
}
static public function Delete($account_id,$family,$key) {
public static function Delete($account_id, $family, $key) {
return XConfig::Delete('a_' . $account_id,$family,$key);
}

View file

@ -12,147 +12,140 @@ use Zotlabs\Lib\Activity;
* An optional limit to the number of records returned may also be specified.
* Use $class->get() to return an array of collection members.
*/
class ASCollection
{
private $channel = null;
private $nextpage = null;
private $limit = 0;
private $direction = 0; // 0 = forward, 1 = reverse
private $data = [];
private $history = [];
public function __construct($obj, $channel = null, $direction = 0, $limit = 0)
{
$this->channel = $channel;
$this->direction = $direction;
$this->limit = $limit;
class ASCollection {
if (is_array($obj)) {
$data = $obj;
}
private $channel = null;
private $nextpage = null;
private $limit = 0;
private $direction = 0; // 0 = forward, 1 = reverse
private $data = [];
private $history = [];
if (is_string($obj)) {
$data = Activity::fetch($obj, $channel);
$this->history[] = $obj;
}
if (!is_array($data)) {
return;
}
function __construct($obj, $channel = null, $direction = 0, $limit = 0) {
if (!in_array($data['type'], ['Collection', 'OrderedCollection'])) {
return false;
}
$this->channel = $channel;
$this->direction = $direction;
$this->limit = $limit;
if ($this->direction) {
if (array_key_exists('last', $data) && $data['last']) {
$this->nextpage = $data['last'];
}
} else {
if (array_key_exists('first', $data) && $data['first']) {
$this->nextpage = $data['first'];
}
}
if (is_array($obj)) {
$data = $obj;
}
if (isset($data['items']) && is_array($data['items'])) {
$this->data = (($this->direction) ? array_reverse($data['items']) : $data['items']);
} elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']);
}
if (is_string($obj)) {
$data = Activity::fetch($obj,$channel);
$this->history[] = $obj;
}
if ($limit) {
if (count($this->data) > $limit) {
$this->data = array_slice($this->data, 0, $limit);
return;
}
}
if (! is_array($data)) {
return;
}
do {
$x = $this->next();
} while ($x);
}
if (! in_array($data['type'], ['Collection','OrderedCollection'])) {
return false;
}
public function get()
{
return $this->data;
}
if ($this->direction) {
if (array_key_exists('last',$data) && $data['last']) {
$this->nextpage = $data['last'];
}
}
else {
if (array_key_exists('first',$data) && $data['first']) {
$this->nextpage = $data['first'];
}
}
public function next()
{
if (isset($data['items']) && is_array($data['items'])) {
$this->data = (($this->direction) ? array_reverse($data['items']) : $data['items']);
}
elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']);
}
if (!$this->nextpage) {
return false;
}
if ($limit) {
if (count($this->data) > $limit) {
$this->data = array_slice($this->data,0,$limit);
return;
}
}
if (is_array($this->nextpage)) {
$data = $this->nextpage;
}
do {
$x = $this->next();
} while ($x);
}
if (is_string($this->nextpage)) {
if (in_array($this->nextpage, $this->history)) {
// recursion detected
return false;
}
$data = Activity::fetch($this->nextpage, $this->channel);
$this->history[] = $this->nextpage;
}
function get() {
return $this->data;
}
if (!is_array($data)) {
return false;
}
function next() {
if (!in_array($data['type'], ['CollectionPage', 'OrderedCollectionPage'])) {
return false;
}
if (! $this->nextpage) {
return false;
}
$this->setnext($data);
if (is_array($this->nextpage)) {
$data = $this->nextpage;
}
if (isset($data['items']) && is_array($data['items'])) {
$this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['items']) : $data['items']));
} elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']));
}
if (is_string($this->nextpage)) {
if (in_array($this->nextpage,$this->history)) {
// recursion detected
return false;
}
$data = Activity::fetch($this->nextpage,$this->channel);
$this->history[] = $this->nextpage;
}
if ($limit) {
if (count($this->data) > $limit) {
$this->data = array_slice($this->data, 0, $limit);
$this->nextpage = false;
return true;
}
}
if (! is_array($data)) {
return false;
}
return true;
}
if (! in_array($data['type'], ['CollectionPage','OrderedCollectionPage'])) {
return false;
}
$this->setnext($data);
if (isset($data['items']) && is_array($data['items'])) {
$this->data = array_merge($this->data,(($this->direction) ? array_reverse($data['items']) : $data['items']));
}
elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = array_merge($this->data,(($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']));
}
if ($limit) {
if (count($this->data) > $limit) {
$this->data = array_slice($this->data,0,$limit);
$this->nextpage = false;
return true;
}
}
return true;
}
function setnext($data) {
if ($this->direction) {
if (array_key_exists('prev',$data) && $data['prev']) {
$this->nextpage = $data['prev'];
}
elseif (array_key_exists('first',$data) && $data['first']) {
$this->nextpage = $data['first'];
}
else {
$this->nextpage = false;
}
}
else {
if (array_key_exists('next',$data) && $data['next']) {
$this->nextpage = $data['next'];
}
elseif (array_key_exists('last',$data) && $data['last']) {
$this->nextpage = $data['last'];
}
else {
$this->nextpage = false;
}
}
logger('nextpage: ' . $this->nextpage, LOGGER_DEBUG);
}
public function setnext($data)
{
if ($this->direction) {
if (array_key_exists('prev', $data) && $data['prev']) {
$this->nextpage = $data['prev'];
} elseif (array_key_exists('first', $data) && $data['first']) {
$this->nextpage = $data['first'];
} else {
$this->nextpage = false;
}
} else {
if (array_key_exists('next', $data) && $data['next']) {
$this->nextpage = $data['next'];
} elseif (array_key_exists('last', $data) && $data['last']) {
$this->nextpage = $data['last'];
} else {
$this->nextpage = false;
}
}
logger('nextpage: ' . $this->nextpage, LOGGER_DEBUG);
}
}

View file

@ -5,7 +5,7 @@ namespace Zotlabs\Lib;
class AbConfig {
static public function Load($chan,$xhash,$family = '') {
public static function Load($chan, $xhash, $family = '') {
if($family)
$where = sprintf(" and cat = '%s' ",dbesc($family));
$r = q("select * from abconfig where chan = %d and xchan = '%s' $where",
@ -16,7 +16,7 @@ class AbConfig {
}
static public function Get($chan,$xhash,$family,$key, $default = false) {
public static function Get($chan, $xhash, $family, $key, $default = false) {
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
intval($chan),
dbesc($xhash),
@ -30,7 +30,7 @@ class AbConfig {
}
static public function Set($chan,$xhash,$family,$key,$value) {
public static function Set($chan, $xhash, $family, $key, $value) {
$dbvalue = ((is_array($value)) ? serialise($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
@ -60,7 +60,7 @@ class AbConfig {
}
static public function Delete($chan,$xhash,$family,$key) {
public static function Delete($chan, $xhash, $family, $key) {
$r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
intval($chan),

View file

@ -5,460 +5,470 @@ namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
class AccessList {
class AccessList
{
static function add($uid,$name,$public = 0) {
public static function add($uid, $name, $public = 0)
{
$ret = false;
if ($uid && $name) {
$r = self::byname($uid,$name); // check for dups
if ($r !== false) {
$ret = false;
if ($uid && $name) {
$r = self::byname($uid, $name); // check for dups
if ($r !== false) {
// This could be a problem.
// Let's assume we've just created a list which we once deleted
// all the old members are gone, but the list remains so we don't break any security
// access lists. What we're doing here is reviving the dead list, but old content which
// was restricted to this list may now be seen by the new list members.
// This could be a problem.
// Let's assume we've just created a list which we once deleted
// all the old members are gone, but the list remains so we don't break any security
// access lists. What we're doing here is reviving the dead list, but old content which
// was restricted to this list may now be seen by the new list members.
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
intval($r)
);
if(($z) && $z[0]['deleted']) {
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
notice( t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL);
}
$hash = self::by_id($uid,$r);
return $hash;
}
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
intval($r)
);
if (($z) && $z[0]['deleted']) {
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
notice(t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL);
}
$hash = self::by_id($uid, $r);
return $hash;
}
$hash = new_uuid();
$hash = new_uuid();
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname, rule )
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname, rule )
VALUES( '%s', %d, %d, '%s', '' ) ",
dbesc($hash),
intval($uid),
intval($public),
dbesc($name)
);
$ret = $r;
}
dbesc($hash),
intval($uid),
intval($public),
dbesc($name)
);
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return (($ret) ? $hash : $ret);
}
return (($ret) ? $hash : $ret);
}
static function remove($uid,$name) {
$ret = false;
if ($uid && $name) {
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
$group_id = $r[0]['id'];
$group_hash = $r[0]['hash'];
}
else {
return false;
}
public static function remove($uid, $name)
{
$ret = false;
if ($uid && $name) {
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
$group_id = $r[0]['id'];
$group_hash = $r[0]['hash'];
} else {
return false;
}
// remove group from default posting lists
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
);
if ($r) {
$user_info = array_shift($r);
$change = false;
// remove group from default posting lists
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
);
if ($r) {
$user_info = array_shift($r);
$change = false;
if ($user_info['channel_default_group'] == $group_hash) {
$user_info['channel_default_group'] = '';
$change = true;
}
if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
$change = true;
}
if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
$change = true;
}
if ($user_info['channel_default_group'] == $group_hash) {
$user_info['channel_default_group'] = '';
$change = true;
}
if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
$change = true;
}
if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
$change = true;
}
if ($change) {
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
if ($change) {
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
WHERE channel_id = %d",
intval($user_info['channel_default_group']),
dbesc($user_info['channel_allow_gid']),
dbesc($user_info['channel_deny_gid']),
intval($uid)
);
}
}
intval($user_info['channel_default_group']),
dbesc($user_info['channel_allow_gid']),
dbesc($user_info['channel_deny_gid']),
intval($uid)
);
}
}
// remove all members
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
intval($uid),
intval($group_id)
);
// remove all members
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
intval($uid),
intval($group_id)
);
// remove group
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);
// remove group
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);
$ret = $r;
$ret = $r;
}
}
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return $ret;
}
return $ret;
}
// returns the integer id of an access group owned by $uid and named $name
// or false.
// returns the integer id of an access group owned by $uid and named $name
// or false.
static function byname($uid,$name) {
if (! ($uid && $name)) {
return false;
}
$r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
return $r[0]['id'];
}
return false;
}
public static function byname($uid, $name)
{
if (!($uid && $name)) {
return false;
}
$r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
return $r[0]['id'];
}
return false;
}
static function by_id($uid,$id) {
if (! ($uid && $id)) {
return false;
}
public static function by_id($uid, $id)
{
if (!($uid && $id)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0",
intval($uid),
intval($id)
);
if ($r) {
return array_shift($r);
}
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0",
intval($uid),
intval($id)
);
if ($r) {
return array_shift($r);
}
return false;
}
static function rec_byhash($uid,$hash) {
if (! ( $uid && $hash)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($uid),
dbesc($hash)
);
if ($r) {
return array_shift($r);
}
return false;
}
public static function rec_byhash($uid, $hash)
{
if (!($uid && $hash)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($uid),
dbesc($hash)
);
if ($r) {
return array_shift($r);
}
return false;
}
static function member_remove($uid,$name,$member) {
$gid = self::byname($uid,$name);
if (! $gid) {
return false;
}
if (! ($uid && $gid && $member)) {
return false;
}
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
);
public static function member_remove($uid, $name, $member)
{
$gid = self::byname($uid, $name);
if (!$gid) {
return false;
}
if (!($uid && $gid && $member)) {
return false;
}
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
);
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return $r;
}
return $r;
}
static function member_add($uid,$name,$member,$gid = 0) {
if (! $gid) {
$gid = self::byname($uid,$name);
}
if (! ($gid && $uid && $member)) {
return false;
}
public static function member_add($uid, $name, $member, $gid = 0)
{
if (!$gid) {
$gid = self::byname($uid, $name);
}
if (!($gid && $uid && $member)) {
return false;
}
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
);
if ($r) {
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
}
else {
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
);
if ($r) {
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
} else {
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($uid),
intval($gid),
dbesc($member)
);
}
Libsync::build_sync_packet($uid,null,true);
return $r;
}
intval($uid),
intval($gid),
dbesc($member)
);
}
Libsync::build_sync_packet($uid, null, true);
return $r;
}
static function members($uid, $gid, $total = false, $start = 0, $records = 0) {
$ret = [];
if ($records) {
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($records), intval($start));
}
public static function members($uid, $gid, $total = false, $start = 0, $records = 0)
{
$ret = [];
if ($records) {
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($records), intval($start));
}
// process virtual groups
if (strpos($gid,':') === 0) {
$vg = substr($gid,1);
switch ($vg) {
case '1':
$sql_extra = EMPTY_STR;
break;
case '2':
$sql_extra = " and xchan_network = 'zot6' ";
break;
case '3':
$sql_extra = " and xchan_network = 'activitypub' ";
break;
default:
break;
}
if ($total) {
$r = q("SELECT count(*) FROM abook left join xchan on xchan_hash = abook_xchan WHERE abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 $sql_extra ORDER BY xchan_name ASC $pager_sql",
intval($uid)
);
return ($r) ? $r[0]['total'] : false;
}
// process virtual groups
if (strpos($gid, ':') === 0) {
$vg = substr($gid, 1);
switch ($vg) {
case '1':
$sql_extra = EMPTY_STR;
break;
case '2':
$sql_extra = " and xchan_network = 'zot6' ";
break;
case '3':
$sql_extra = " and xchan_network = 'activitypub' ";
break;
default:
break;
}
if ($total) {
$r = q("SELECT count(*) FROM abook left join xchan on xchan_hash = abook_xchan WHERE abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 $sql_extra ORDER BY xchan_name ASC $pager_sql",
intval($uid)
);
return ($r) ? $r[0]['total'] : false;
}
$r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan
$r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan
WHERE abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 $sql_extra ORDER BY xchan_name ASC $pager_sql",
intval($uid)
);
if ($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['xchan'] = $r[$x]['abook_xchan'];
}
}
return $r;
}
intval($uid)
);
if ($r) {
for ($x = 0; $x < count($r); $x++) {
$r[$x]['xchan'] = $r[$x]['abook_xchan'];
}
}
return $r;
}
if (intval($gid)) {
if ($total) {
$r = q("SELECT count(xchan) as total FROM pgrp_member
if (intval($gid)) {
if ($total) {
$r = q("SELECT count(xchan) as total FROM pgrp_member
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0
and abook_blocked = 0 and abook_pending = 0",
intval($gid),
intval($uid),
intval($uid)
);
if ($r) {
return $r[0]['total'];
}
}
intval($gid),
intval($uid),
intval($uid)
);
if ($r) {
return $r[0]['total'];
}
}
$r = q("SELECT * FROM pgrp_member
$r = q("SELECT * FROM pgrp_member
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC $pager_sql",
intval($gid),
intval($uid),
intval($uid)
);
if ($r) {
$ret = $r;
}
}
return $ret;
}
intval($gid),
intval($uid),
intval($uid)
);
if ($r) {
$ret = $r;
}
}
return $ret;
}
static function members_xchan($uid,$gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
intval($gid),
intval($uid)
);
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
return $ret;
}
public static function members_xchan($uid, $gid)
{
$ret = [];
if (intval($gid)) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
intval($gid),
intval($uid)
);
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
return $ret;
}
static function select($uid,$group = '') {
public static function select($uid, $group = '')
{
$grps = [];
$grps = [];
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = [ 'name' => '', 'hash' => '0', 'selected' => '' ];
if ($r) {
foreach ($r as $rr) {
$grps[] = [ 'name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '') ];
}
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = ['name' => '', 'hash' => '0', 'selected' => ''];
if ($r) {
foreach ($r as $rr) {
$grps[] = ['name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '')];
}
}
}
return replace_macros(get_markup_template('group_selection.tpl'), [
'$label' => t('Add new connections to this access list'),
'$groups' => $grps
]);
}
return replace_macros(get_markup_template('group_selection.tpl'), [
'$label' => t('Add new connections to this access list'),
'$groups' => $grps
]);
}
static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
public static function widget($every = "connections", $each = "lists", $edit = false, $group_id = 0, $cid = '', $mode = 1)
{
$o = '';
$o = '';
$groups = [];
$groups = [];
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = [];
if ($cid) {
$member_of = self::containing(local_channel(),$cid);
}
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = [];
if ($cid) {
$member_of = self::containing(local_channel(), $cid);
}
if ($r) {
foreach ($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($r) {
foreach ($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($edit) {
$groupedit = [ 'href' => "lists/".$rr['id'], 'title' => t('edit') ];
}
else {
$groupedit = null;
}
if ($edit) {
$groupedit = ['href' => "lists/" . $rr['id'], 'title' => t('edit')];
} else {
$groupedit = null;
}
$groups[] = [
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'],$member_of),
];
}
}
$groups[] = [
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each . '?f=&gid=' . $rr['id'] : $each . "/" . $rr['id']) . ((x($_GET, 'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET, 'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'], $member_of),
];
}
}
return replace_macros(get_markup_template('group_side.tpl'), [
'$title' => t('Lists'),
'$edittext' => t('Edit list'),
'$createtext' => t('Create new list'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''),
'$groups' => $groups,
'$add' => t('add'),
]);
return replace_macros(get_markup_template('group_side.tpl'), [
'$title' => t('Lists'),
'$edittext' => t('Edit list'),
'$createtext' => t('Create new list'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''),
'$groups' => $groups,
'$add' => t('add'),
]);
}
}
static function expand($g) {
if (! (is_array($g) && count($g))) {
return [];
}
public static function expand($g)
{
if (!(is_array($g) && count($g))) {
return [];
}
$ret = [];
$x = [];
$ret = [];
$x = [];
foreach ($g as $gv) {
foreach ($g as $gv) {
// virtual access lists
// connections:abc is all the connection sof the channel with channel_hash abc
// zot:abc is all of abc's zot6 connections
// activitypub:abc is all of abc's activitypub connections
// virtual access lists
// connections:abc is all the connection sof the channel with channel_hash abc
// zot:abc is all of abc's zot6 connections
// activitypub:abc is all of abc's activitypub connections
if (strpos($gv,'connections:') === 0 || strpos($gv,'zot:') === 0 || strpos($gv,'activitypub:') === 0) {
$sql_extra = EMPTY_STR;
$channel_hash = substr($gv,strpos($gv,':') + 1);
if (strpos($gv,'zot:') === 0) {
$sql_extra = " and xchan_network = 'zot6' ";
}
if (strpos($gv,'activitypub:') === 0) {
$sql_extra = " and xchan_network = 'activitypub' ";
}
$r = q("select channel_id from channel where channel_hash = '%s' ",
dbesc($channel_hash)
);
if ($r) {
foreach ($r as $rv) {
$y = q("select abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 $sql_extra",
intval($rv['channel_id'])
);
if ($y) {
foreach ($y as $yv) {
$ret[] = $yv['abook_xchan'];
}
}
}
}
}
else {
$x[] = $gv;
}
}
if (strpos($gv, 'connections:') === 0 || strpos($gv, 'zot:') === 0 || strpos($gv, 'activitypub:') === 0) {
$sql_extra = EMPTY_STR;
$channel_hash = substr($gv, strpos($gv, ':') + 1);
if (strpos($gv, 'zot:') === 0) {
$sql_extra = " and xchan_network = 'zot6' ";
}
if (strpos($gv, 'activitypub:') === 0) {
$sql_extra = " and xchan_network = 'activitypub' ";
}
$r = q("select channel_id from channel where channel_hash = '%s' ",
dbesc($channel_hash)
);
if ($r) {
foreach ($r as $rv) {
$y = q("select abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 $sql_extra",
intval($rv['channel_id'])
);
if ($y) {
foreach ($y as $yv) {
$ret[] = $yv['abook_xchan'];
}
}
}
}
} else {
$x[] = $gv;
}
}
if ($x) {
stringify_array_elms($x,true);
$groups = implode(',', $x);
if ($groups) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
if ($x) {
stringify_array_elms($x, true);
$groups = implode(',', $x);
if ($groups) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
}
return $ret;
}
}
}
return $ret;
}
static function member_of($c) {
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
public static function member_of($c)
{
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
dbesc($c)
);
dbesc($c)
);
return $r;
}
return $r;
}
static function containing($uid,$c) {
public static function containing($uid, $c)
{
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
intval($uid),
dbesc($c)
);
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
intval($uid),
dbesc($c)
);
$ret = [];
if ($r) {
foreach ($r as $rv)
$ret[] = $rv['gid'];
}
$ret = [];
if ($r) {
foreach ($r as $rv)
$ret[] = $rv['gid'];
}
return $ret;
}
return $ret;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,457 +10,466 @@ use Zotlabs\Web\HTTPSig;
*
* Parses an ActivityStream JSON string.
*/
class ActivityStreams
{
class ActivityStreams {
public $raw = null;
public $data = null;
public $hub = null;
public $valid = false;
public $deleted = false;
public $id = '';
public $parent_id = '';
public $type = '';
public $actor = null;
public $obj = null;
public $tgt = null;
public $replyto = null;
public $origin = null;
public $owner = null;
public $signer = null;
public $ldsig = null;
public $sigok = false;
public $recips = null;
public $raw_recips = null;
public $implied_create = false;
public $raw = null;
public $data = null;
public $hub = null;
public $valid = false;
public $deleted = false;
public $id = '';
public $parent_id = '';
public $type = '';
public $actor = null;
public $obj = null;
public $tgt = null;
public $replyto = null;
public $origin = null;
public $owner = null;
public $signer = null;
public $ldsig = null;
public $sigok = false;
public $recips = null;
public $raw_recips = null;
public $implied_create = false;
/**
* @brief Constructor for ActivityStreams.
*
* Takes a JSON string or previously decode activity array as parameter,
* decodes it and sets up this object/activity, fetching any required attributes
* which were only referenced by @id/URI.
*
* @param string $string
*/
public function __construct($string, $hub = null, $client = null)
{
/**
* @brief Constructor for ActivityStreams.
*
* Takes a JSON string or previously decode activity array as parameter,
* decodes it and sets up this object/activity, fetching any required attributes
* which were only referenced by @id/URI.
*
* @param string $string
*/
function __construct($string,$hub = null,$client = null) {
$this->raw = $string;
$this->hub = $hub;
$this->raw = $string;
$this->hub = $hub;
if (is_array($string)) {
$this->data = $string;
$this->raw = json_encode($string, JSON_UNESCAPED_SLASHES);
} else {
$this->data = json_decode($string, true);
}
if (is_array($string)) {
$this->data = $string;
$this->raw = json_encode($string,JSON_UNESCAPED_SLASHES);
}
else {
$this->data = json_decode($string, true);
}
if ($this->data) {
if ($this->data) {
// verify and unpack JSalmon signature if present
// This will only be the case for Zot6 packets
// verify and unpack JSalmon signature if present
// This will only be the case for Zot6 packets
if (is_array($this->data) && array_key_exists('signed', $this->data)) {
$ret = JSalmon::verify($this->data);
$tmp = JSalmon::unpack($this->data['data']);
if ($ret && $ret['success']) {
if ($ret['signer']) {
logger('Unpacked: ' . json_encode($tmp, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOGGER_DATA, LOG_DEBUG);
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
$this->data = $tmp;
$this->data['signer'] = $ret['signer'];
$this->data['signed_data'] = $saved;
if ($ret['hubloc']) {
$this->data['hubloc'] = $ret['hubloc'];
}
}
}
}
if (is_array($this->data) && array_key_exists('signed',$this->data)) {
$ret = JSalmon::verify($this->data);
$tmp = JSalmon::unpack($this->data['data']);
if ($ret && $ret['success']) {
if ($ret['signer']) {
logger('Unpacked: ' . json_encode($tmp,JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT),LOGGER_DATA,LOG_DEBUG);
$saved = json_encode($this->data,JSON_UNESCAPED_SLASHES);
$this->data = $tmp;
$this->data['signer'] = $ret['signer'];
$this->data['signed_data'] = $saved;
if ($ret['hubloc']) {
$this->data['hubloc'] = $ret['hubloc'];
}
}
}
}
// This indicates only that we have sucessfully decoded JSON.
$this->valid = true;
// This indicates only that we have sucessfully decoded JSON.
$this->valid = true;
// Special handling for Mastodon "delete actor" activities which will often fail to verify
// because the key cannot be fetched. We will catch this condition elsewhere.
// Special handling for Mastodon "delete actor" activities which will often fail to verify
// because the key cannot be fetched. We will catch this condition elsewhere.
if (array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
$this->deleted = $this->data['actor'];
$this->valid = false;
}
}
if (array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) {
if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
$this->deleted = $this->data['actor'];
$this->valid = false;
}
}
}
}
// Attempt to assemble an Activity from what we were given.
// Attempt to assemble an Activity from what we were given.
if ($this->is_valid()) {
$this->id = $this->get_property_obj('id');
$this->type = $this->get_primary_type();
$this->actor = $this->get_actor('actor', '', '');
$this->obj = $this->get_compound_property('object');
$this->tgt = $this->get_compound_property('target');
$this->origin = $this->get_compound_property('origin');
$this->recips = $this->collect_recips();
$this->replyto = $this->get_property_obj('replyTo');
if ($this->is_valid()) {
$this->id = $this->get_property_obj('id');
$this->type = $this->get_primary_type();
$this->actor = $this->get_actor('actor','','');
$this->obj = $this->get_compound_property('object');
$this->tgt = $this->get_compound_property('target');
$this->origin = $this->get_compound_property('origin');
$this->recips = $this->collect_recips();
$this->replyto = $this->get_property_obj('replyTo');
$this->ldsig = $this->get_compound_property('signature');
if ($this->ldsig) {
$this->signer = $this->get_compound_property('creator', $this->ldsig);
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer)
&& is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
}
}
$this->ldsig = $this->get_compound_property('signature');
if ($this->ldsig) {
$this->signer = $this->get_compound_property('creator',$this->ldsig);
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey',$this->signer)
&& is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
$this->sigok = LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
}
}
// Implied create activity required by C2S specification if no object is present
// Implied create activity required by C2S specification if no object is present
if (!$this->obj) {
if (!$client) {
$this->implied_create = true;
}
$this->obj = $this->data;
$this->type = 'Create';
if (!$this->actor) {
$this->actor = $this->get_actor('attributedTo', $this->obj);
}
}
if (! $this->obj) {
if (! $client) {
$this->implied_create = true;
}
$this->obj = $this->data;
$this->type = 'Create';
if (! $this->actor) {
$this->actor = $this->get_actor('attributedTo',$this->obj);
}
}
// fetch recursive or embedded activities
// fetch recursive or embedded activities
if ($this->obj && is_array($this->obj) && array_key_exists('object', $this->obj)) {
$this->obj['object'] = $this->get_compound_property($this->obj['object']);
}
if ($this->obj && is_array($this->obj) && array_key_exists('object',$this->obj)) {
$this->obj['object'] = $this->get_compound_property($this->obj['object']);
}
// Enumerate and store actors in referenced objects
// Enumerate and store actors in referenced objects
if ($this->obj && is_array($this->obj) && $this->obj['actor']) {
$this->obj['actor'] = $this->get_actor('actor', $this->obj);
}
if ($this->tgt && is_array($this->tgt) && $this->tgt['actor']) {
$this->tgt['actor'] = $this->get_actor('actor', $this->tgt);
}
if ($this->obj && is_array($this->obj) && $this->obj['actor']) {
$this->obj['actor'] = $this->get_actor('actor',$this->obj);
}
if ($this->tgt && is_array($this->tgt) && $this->tgt['actor']) {
$this->tgt['actor'] = $this->get_actor('actor',$this->tgt);
}
// Determine if this is a followup or response activity
// Determine if this is a followup or response activity
$this->parent_id = $this->get_property_obj('inReplyTo');
$this->parent_id = $this->get_property_obj('inReplyTo');
if ((!$this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['inReplyTo'];
}
if ((!$this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['id'];
}
}
}
if ((! $this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['inReplyTo'];
}
if ((! $this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['id'];
}
}
}
/**
* @brief Return if instantiated ActivityStream is valid.
*
* @return bool Return true if the JSON string could be decoded.
*/
/**
* @brief Return if instantiated ActivityStream is valid.
*
* @return boolean Return true if the JSON string could be decoded.
*/
public function is_valid()
{
return $this->valid;
}
function is_valid() {
return $this->valid;
}
public function set_recips($arr)
{
$this->saved_recips = $arr;
}
function set_recips($arr) {
$this->saved_recips = $arr;
}
/**
* @brief Collects all recipients.
*
* @param string $base
* @param string $namespace (optional) default empty
* @return array
*/
public function collect_recips($base = '', $namespace = '')
{
$x = [];
/**
* @brief Collects all recipients.
*
* @param string $base
* @param string $namespace (optional) default empty
* @return array
*/
function collect_recips($base = '', $namespace = '') {
$x = [];
$fields = [ 'to', 'cc', 'bto', 'bcc', 'audience'];
foreach ($fields as $f) {
// don't expand these yet
$y = $this->get_property_obj($f, $base, $namespace);
if ($y) {
if (! is_array($this->raw_recips)) {
$this->raw_recips = [];
}
if (! is_array($y)) {
$y = [ $y ];
}
$this->raw_recips[$f] = $y;
$x = array_merge($x, $y);
}
}
$fields = ['to', 'cc', 'bto', 'bcc', 'audience'];
foreach ($fields as $f) {
// don't expand these yet
$y = $this->get_property_obj($f, $base, $namespace);
if ($y) {
if (!is_array($this->raw_recips)) {
$this->raw_recips = [];
}
if (!is_array($y)) {
$y = [$y];
}
$this->raw_recips[$f] = $y;
$x = array_merge($x, $y);
}
}
// not yet ready for prime time
// $x = $this->expand($x,$base,$namespace);
return $x;
}
return $x;
}
function expand($arr,$base = '',$namespace = '') {
$ret = [];
public function expand($arr, $base = '', $namespace = '')
{
$ret = [];
// right now use a hardwired recursion depth of 5
// right now use a hardwired recursion depth of 5
for ($z = 0; $z < 5; $z ++) {
if (is_array($arr) && $arr) {
foreach ($arr as $a) {
if (is_array($a)) {
$ret[] = $a;
}
else {
$x = $this->get_compound_property($a,$base,$namespace);
if ($x) {
$ret = array_merge($ret,$x);
}
}
}
}
}
for ($z = 0; $z < 5; $z++) {
if (is_array($arr) && $arr) {
foreach ($arr as $a) {
if (is_array($a)) {
$ret[] = $a;
} else {
$x = $this->get_compound_property($a, $base, $namespace);
if ($x) {
$ret = array_merge($ret, $x);
}
}
}
}
}
/// @fixme de-duplicate
/// @fixme de-duplicate
return $ret;
}
return $ret;
}
/**
* @brief
*
* @param array $base
* @param string $namespace if not set return empty string
* @return string|NULL
*/
/**
* @brief
*
* @param array $base
* @param string $namespace if not set return empty string
* @return string|NULL
*/
function get_namespace($base, $namespace) {
public function get_namespace($base, $namespace)
{
if (! $namespace) {
return EMPTY_STR;
}
if (!$namespace) {
return EMPTY_STR;
}
$key = null;
$key = null;
foreach ( [ $this->data, $base ] as $b ) {
if (! $b) {
continue;
}
foreach ([$this->data, $base] as $b) {
if (!$b) {
continue;
}
if (array_key_exists('@context', $b)) {
if (is_array($b['@context'])) {
foreach ($b['@context'] as $ns) {
if (is_array($ns)) {
foreach ($ns as $k => $v) {
if ($namespace === $v) {
$key = $k;
}
}
}
else {
if ($namespace === $ns) {
$key = '';
}
}
}
}
else {
if ($namespace === $b['@context']) {
$key = '';
}
}
}
}
if (array_key_exists('@context', $b)) {
if (is_array($b['@context'])) {
foreach ($b['@context'] as $ns) {
if (is_array($ns)) {
foreach ($ns as $k => $v) {
if ($namespace === $v) {
$key = $k;
}
}
} else {
if ($namespace === $ns) {
$key = '';
}
}
}
} else {
if ($namespace === $b['@context']) {
$key = '';
}
}
}
}
return $key;
}
return $key;
}
/**
* @brief
*
* @param string $property
* @param array $base (optional)
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
/**
* @brief
*
* @param string $property
* @param array $base (optional)
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
function get_property_obj($property, $base = '', $namespace = '') {
$prefix = $this->get_namespace($base, $namespace);
if ($prefix === null) {
return null;
}
public function get_property_obj($property, $base = '', $namespace = '')
{
$prefix = $this->get_namespace($base, $namespace);
if ($prefix === null) {
return null;
}
$base = (($base) ? $base : $this->data);
$propname = (($prefix) ? $prefix . ':' : '') . $property;
$base = (($base) ? $base : $this->data);
$propname = (($prefix) ? $prefix . ':' : '') . $property;
if (! is_array($base)) {
btlogger('not an array: ' . print_r($base,true));
return null;
}
if (!is_array($base)) {
btlogger('not an array: ' . print_r($base, true));
return null;
}
return ((array_key_exists($propname, $base)) ? $base[$propname] : null);
}
return ((array_key_exists($propname, $base)) ? $base[$propname] : null);
}
/**
* @brief Fetches a property from an URL.
*
* @param string $url
* @param array $channel (signing channel, default system channel)
* @return NULL|mixed
*/
/**
* @brief Fetches a property from an URL.
*
* @param string $url
* @param array $channel (signing channel, default system channel)
* @return NULL|mixed
*/
function fetch_property($url,$channel = null,$hub = null) {
return Activity::fetch($url,$channel,$hub);
}
public function fetch_property($url, $channel = null, $hub = null)
{
return Activity::fetch($url, $channel, $hub);
}
static function is_an_actor($s) {
if (! $s) {
return false;
}
return (in_array($s,[ 'Application','Group','Organization','Person','Service' ]));
}
public static function is_an_actor($s)
{
if (!$s) {
return false;
}
return (in_array($s, ['Application', 'Group', 'Organization', 'Person', 'Service']));
}
static function is_response_activity($s) {
if (! $s) {
return false;
}
return (in_array($s, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ]));
}
public static function is_response_activity($s)
{
if (!$s) {
return false;
}
return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact']));
}
/**
* @brief
*
* @param string $property
* @param array $base
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
public function get_actor($property, $base = '', $namespace = '')
{
$x = $this->get_property_obj($property, $base, $namespace);
if (self::is_url($x)) {
$y = Activity::get_cached_actor($x);
if ($y) {
return $y;
}
}
$actor = $this->get_compound_property($property, $base, $namespace, true);
if (is_array($actor) && self::is_an_actor($actor['type'])) {
if (array_key_exists('id', $actor) && (!array_key_exists('inbox', $actor))) {
$actor = $this->fetch_property($actor['id']);
}
return $actor;
}
return null;
}
/**
* @brief
*
* @param string $property
* @param array $base
* @param string $namespace (optional) default empty
* @param bool $first (optional) default false, if true and result is a sequential array return only the first element
* @return NULL|mixed
*/
/**
* @brief
*
* @param string $property
* @param array $base
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
public function get_compound_property($property, $base = '', $namespace = '', $first = false)
{
$x = $this->get_property_obj($property, $base, $namespace);
if (self::is_url($x)) {
$y = $this->fetch_property($x);
if (is_array($y)) {
$x = $y;
}
}
function get_actor($property,$base='',$namespace = '') {
$x = $this->get_property_obj($property, $base, $namespace);
if (self::is_url($x)) {
$y = Activity::get_cached_actor($x);
if ($y) {
return $y;
}
}
// verify and unpack JSalmon signature if present
// This may be present in Zot6 packets
$actor = $this->get_compound_property($property,$base,$namespace,true);
if (is_array($actor) && self::is_an_actor($actor['type'])) {
if (array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) {
$actor = $this->fetch_property($actor['id']);
}
return $actor;
}
return null;
}
if (is_array($x) && array_key_exists('signed', $x)) {
$ret = JSalmon::verify($x);
$tmp = JSalmon::unpack($x['data']);
if ($ret && $ret['success']) {
if ($ret['signer']) {
logger('Unpacked: ' . json_encode($tmp, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOGGER_DATA, LOG_DEBUG);
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
$x = $tmp;
$x['signer'] = $ret['signer'];
$x['signed_data'] = $saved;
if ($ret['hubloc']) {
$x['hubloc'] = $ret['hubloc'];
}
}
}
}
if ($first && is_array($x) && array_key_exists(0, $x)) {
return $x[0];
}
return $x;
}
/**
* @brief Check if string starts with http.
*
* @param string $url
* @return bool
*/
public static function is_url($url)
{
if (($url) && (!is_array($url)) && ((strpos($url, 'http') === 0) || (strpos($url, 'x-zot') === 0) || (strpos($url, 'bear') === 0))) {
return true;
}
return false;
}
/**
* @brief Gets the type property.
*
* @param array $base
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
public function get_primary_type($base = '', $namespace = '')
{
if (!$base) {
$base = $this->data;
}
$x = $this->get_property_obj('type', $base, $namespace);
if (is_array($x)) {
foreach ($x as $y) {
if (strpos($y, ':') === false) {
return $y;
}
}
}
return $x;
}
public function debug()
{
$x = var_export($this, true);
return $x;
}
/**
* @brief
*
* @param string $property
* @param array $base
* @param string $namespace (optional) default empty
* @param boolean $first (optional) default false, if true and result is a sequential array return only the first element
* @return NULL|mixed
*/
public static function is_as_request()
{
function get_compound_property($property, $base = '', $namespace = '', $first = false) {
$x = $this->get_property_obj($property, $base, $namespace);
if (self::is_url($x)) {
$y = $this->fetch_property($x);
if (is_array($y)) {
$x = $y;
}
}
$x = getBestSupportedMimeType([
'application/ld+json;profile="https://www.w3.org/ns/activitystreams"',
'application/activity+json',
'application/ld+json;profile="http://www.w3.org/ns/activitystreams"',
'application/ld+json', // required for Friendica ~2021-09, can possibly be removed after next release of that project
'application/x-zot-activity+json'
]);
// verify and unpack JSalmon signature if present
// This may be present in Zot6 packets
if (is_array($x) && array_key_exists('signed',$x)) {
$ret = JSalmon::verify($x);
$tmp = JSalmon::unpack($x['data']);
if ($ret && $ret['success']) {
if ($ret['signer']) {
logger('Unpacked: ' . json_encode($tmp,JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT),LOGGER_DATA,LOG_DEBUG);
$saved = json_encode($x,JSON_UNESCAPED_SLASHES);
$x = $tmp;
$x['signer'] = $ret['signer'];
$x['signed_data'] = $saved;
if ($ret['hubloc']) {
$x['hubloc'] = $ret['hubloc'];
}
}
}
}
if ($first && is_array($x) && array_key_exists(0,$x)) {
return $x[0];
}
return $x;
}
/**
* @brief Check if string starts with http.
*
* @param string $url
* @return boolean
*/
static public function is_url($url) {
if (($url) && (! is_array($url)) && ((strpos($url, 'http') === 0) || (strpos($url,'x-zot') === 0) || (strpos($url,'bear') === 0))) {
return true;
}
return false;
}
/**
* @brief Gets the type property.
*
* @param array $base
* @param string $namespace (optional) default empty
* @return NULL|mixed
*/
function get_primary_type($base = '', $namespace = '') {
if (! $base) {
$base = $this->data;
}
$x = $this->get_property_obj('type', $base, $namespace);
if (is_array($x)) {
foreach ($x as $y) {
if (strpos($y, ':') === false) {
return $y;
}
}
}
return $x;
}
function debug() {
$x = var_export($this, true);
return $x;
}
static function is_as_request() {
$x = getBestSupportedMimeType([
'application/ld+json;profile="https://www.w3.org/ns/activitystreams"',
'application/activity+json',
'application/ld+json;profile="http://www.w3.org/ns/activitystreams"',
'application/ld+json', // required for Friendica ~2021-09, can possibly be removed after next release of that project
'application/x-zot-activity+json'
]);
return(($x) ? true : false);
}
return (($x) ? true : false);
}
}

View file

@ -3,30 +3,34 @@
namespace Zotlabs\Lib;
class Api_router {
class Api_router
{
static private $routes = [];
private static $routes = [];
static function register($path,$fn,$auth_required) {
self::$routes[$path] = [ 'func' => $fn, 'auth' => $auth_required ];
}
public static function register($path, $fn, $auth_required)
{
self::$routes[$path] = ['func' => $fn, 'auth' => $auth_required];
}
static function find($path) {
if (array_key_exists($path,self::$routes)) {
return self::$routes[$path];
}
public static function find($path)
{
if (array_key_exists($path, self::$routes)) {
return self::$routes[$path];
}
$with_params = dirname($path) . '/[id]';
$with_params = dirname($path) . '/[id]';
if (array_key_exists($with_params,self::$routes)) {
return self::$routes[$with_params];
}
if (array_key_exists($with_params, self::$routes)) {
return self::$routes[$with_params];
}
return null;
}
return null;
}
static function dbg() {
return self::$routes;
}
public static function dbg()
{
return self::$routes;
}
}

File diff suppressed because it is too large Load diff

View file

@ -6,272 +6,280 @@ use Zotlabs\Lib\Libsync;
/**
* @brief A class with chatroom related static methods.
*/
class Chatroom {
/**
* @brief Creates a chatroom.
*
* @param array $channel
* @param array $arr
* @return array An associative array containing:
* * \e boolean \b success - A boolean success status
* * \e string \b message - (optional) A string
*/
static public function create($channel, $arr) {
class Chatroom
{
/**
* @brief Creates a chatroom.
*
* @param array $channel
* @param array $arr
* @return array An associative array containing:
* * \e boolean \b success - A boolean success status
* * \e string \b message - (optional) A string
*/
public static function create($channel, $arr)
{
$ret = array('success' => false);
$ret = array('success' => false);
$name = trim($arr['name']);
if(! $name) {
$ret['message'] = t('Missing room name');
return $ret;
}
$name = trim($arr['name']);
if (!$name) {
$ret['message'] = t('Missing room name');
return $ret;
}
$r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1",
intval($channel['channel_id']),
dbesc($name)
);
if($r) {
$ret['message'] = t('Duplicate room name');
return $ret;
}
$r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1",
intval($channel['channel_id']),
dbesc($name)
);
if ($r) {
$ret['message'] = t('Duplicate room name');
return $ret;
}
$r = q("select count(cr_id) as total from chatroom where cr_aid = %d",
intval($channel['channel_account_id'])
);
if($r)
$limit = service_class_fetch($channel['channel_id'], 'chatrooms');
$r = q("select count(cr_id) as total from chatroom where cr_aid = %d",
intval($channel['channel_account_id'])
);
if ($r)
$limit = service_class_fetch($channel['channel_id'], 'chatrooms');
if(($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) {
$ret['message'] = upgrade_message();
return $ret;
}
if (($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) {
$ret['message'] = upgrade_message();
return $ret;
}
if(! array_key_exists('expire', $arr))
$arr['expire'] = 120; // minutes, e.g. 2 hours
if (!array_key_exists('expire', $arr))
$arr['expire'] = 120; // minutes, e.g. 2 hours
$created = datetime_convert();
$created = datetime_convert();
$x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid )
$x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid )
values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel['channel_id']),
dbesc($name),
dbesc($created),
dbesc($created),
intval($arr['expire']),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
dbesc($arr['deny_gid'])
);
intval($channel['channel_account_id']),
intval($channel['channel_id']),
dbesc($name),
dbesc($created),
dbesc($created),
intval($arr['expire']),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
dbesc($arr['deny_gid'])
);
if($x)
$ret['success'] = true;
if ($x)
$ret['success'] = true;
return $ret;
}
return $ret;
}
static public function destroy($channel,$arr) {
public static function destroy($channel, $arr)
{
$ret = array('success' => false);
$ret = array('success' => false);
if(intval($arr['cr_id']))
$sql_extra = " and cr_id = " . intval($arr['cr_id']) . " ";
elseif(trim($arr['cr_name']))
$sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' ";
else {
$ret['message'] = t('Invalid room specifier.');
return $ret;
}
if (intval($arr['cr_id']))
$sql_extra = " and cr_id = " . intval($arr['cr_id']) . " ";
elseif (trim($arr['cr_name']))
$sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' ";
else {
$ret['message'] = t('Invalid room specifier.');
return $ret;
}
$r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1",
intval($channel['channel_id'])
);
if(! $r) {
$ret['message'] = t('Invalid room specifier.');
return $ret;
}
$r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1",
intval($channel['channel_id'])
);
if (!$r) {
$ret['message'] = t('Invalid room specifier.');
return $ret;
}
Libsync::build_sync_packet($channel['channel_id'],array('chatroom' => $r));
Libsync::build_sync_packet($channel['channel_id'], array('chatroom' => $r));
q("delete from chatroom where cr_id = %d",
intval($r[0]['cr_id'])
);
if($r[0]['cr_id']) {
q("delete from chatpresence where cp_room = %d",
intval($r[0]['cr_id'])
);
q("delete from chat where chat_room = %d",
intval($r[0]['cr_id'])
);
}
q("delete from chatroom where cr_id = %d",
intval($r[0]['cr_id'])
);
if ($r[0]['cr_id']) {
q("delete from chatpresence where cp_room = %d",
intval($r[0]['cr_id'])
);
q("delete from chat where chat_room = %d",
intval($r[0]['cr_id'])
);
}
$ret['success'] = true;
return $ret;
}
$ret['success'] = true;
return $ret;
}
static public function enter($observer_xchan, $room_id, $status, $client) {
public static function enter($observer_xchan, $room_id, $status, $client)
{
if(! $room_id || ! $observer_xchan)
return;
if (!$room_id || !$observer_xchan)
return;
$r = q("select * from chatroom where cr_id = %d limit 1",
intval($room_id)
);
if(! $r) {
notice( t('Room not found.') . EOL);
return false;
}
require_once('include/security.php');
$sql_extra = permissions_sql($r[0]['cr_uid']);
$r = q("select * from chatroom where cr_id = %d limit 1",
intval($room_id)
);
if (!$r) {
notice(t('Room not found.') . EOL);
return false;
}
require_once('include/security.php');
$sql_extra = permissions_sql($r[0]['cr_uid']);
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
intval($room_id),
intval($r[0]['cr_uid'])
);
if(! $x) {
notice( t('Permission denied.') . EOL);
return false;
}
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
intval($room_id),
intval($r[0]['cr_uid'])
);
if (!$x) {
notice(t('Permission denied.') . EOL);
return false;
}
$limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom');
if($limit !== false) {
$y = q("select count(*) as total from chatpresence where cp_room = %d",
intval($room_id)
);
if($y && $y[0]['total'] > $limit) {
notice( t('Room is full') . EOL);
return false;
}
}
$limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom');
if ($limit !== false) {
$y = q("select count(*) as total from chatpresence where cp_room = %d",
intval($room_id)
);
if ($y && $y[0]['total'] > $limit) {
notice(t('Room is full') . EOL);
return false;
}
}
if(intval($x[0]['cr_expire'])) {
$r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d",
db_utcnow(),
db_quoteinterval( intval($x[0]['cr_expire']) . ' MINUTE' ),
intval($x[0]['cr_id'])
);
}
if (intval($x[0]['cr_expire'])) {
$r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d",
db_utcnow(),
db_quoteinterval(intval($x[0]['cr_expire']) . ' MINUTE'),
intval($x[0]['cr_id'])
);
}
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1",
dbesc($observer_xchan),
intval($room_id)
);
if($r) {
q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'",
dbesc(datetime_convert()),
intval($r[0]['cp_id']),
dbesc($client)
);
return true;
}
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1",
dbesc($observer_xchan),
intval($room_id)
);
if ($r) {
q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'",
dbesc(datetime_convert()),
intval($r[0]['cp_id']),
dbesc($client)
);
return true;
}
$r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client )
$r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client )
values ( %d, '%s', '%s', '%s', '%s' )",
intval($room_id),
dbesc($observer_xchan),
dbesc(datetime_convert()),
dbesc($status),
dbesc($client)
);
intval($room_id),
dbesc($observer_xchan),
dbesc(datetime_convert()),
dbesc($status),
dbesc($client)
);
return $r;
}
return $r;
}
function leave($observer_xchan, $room_id, $client) {
if(! $room_id || ! $observer_xchan)
return;
public function leave($observer_xchan, $room_id, $client)
{
if (!$room_id || !$observer_xchan)
return;
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
dbesc($observer_xchan),
intval($room_id),
dbesc($client)
);
if($r) {
q("delete from chatpresence where cp_id = %d",
intval($r[0]['cp_id'])
);
}
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
dbesc($observer_xchan),
intval($room_id),
dbesc($client)
);
if ($r) {
q("delete from chatpresence where cp_id = %d",
intval($r[0]['cp_id'])
);
}
return true;
}
return true;
}
static public function roomlist($uid) {
require_once('include/security.php');
$sql_extra = permissions_sql($uid);
public static function roomlist($uid)
{
require_once('include/security.php');
$sql_extra = permissions_sql($uid);
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
intval($uid)
);
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
intval($uid)
);
return $r;
}
return $r;
}
static public function list_count($uid) {
require_once('include/security.php');
$sql_extra = permissions_sql($uid);
public static function list_count($uid)
{
require_once('include/security.php');
$sql_extra = permissions_sql($uid);
$r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra",
intval($uid)
);
$r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra",
intval($uid)
);
return $r[0]['total'];
}
return $r[0]['total'];
}
/**
* @brief Create a chat message via API.
*
* It is the caller's responsibility to enter the room.
*
* @param int $uid
* @param int $room_id
* @param string $xchan
* @param string $text
* @return array
*/
static public function message($uid, $room_id, $xchan, $text) {
/**
* @brief Create a chat message via API.
*
* It is the caller's responsibility to enter the room.
*
* @param int $uid
* @param int $room_id
* @param string $xchan
* @param string $text
* @return array
*/
public static function message($uid, $room_id, $xchan, $text)
{
$ret = array('success' => false);
$ret = array('success' => false);
if(! $text)
return;
if (!$text)
return;
$sql_extra = permissions_sql($uid);
$sql_extra = permissions_sql($uid);
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
intval($uid),
intval($room_id)
);
if(! $r)
return $ret;
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
intval($uid),
intval($room_id)
);
if (!$r)
return $ret;
$arr = [
'chat_room' => $room_id,
'chat_xchan' => $xchan,
'chat_text' => $text
];
/**
* @hooks chat_message
* Called to create a chat message.
* * \e int \b chat_room
* * \e string \b chat_xchan
* * \e string \b chat_text
*/
call_hooks('chat_message', $arr);
$arr = [
'chat_room' => $room_id,
'chat_xchan' => $xchan,
'chat_text' => $text
];
/**
* @hooks chat_message
* Called to create a chat message.
* * \e int \b chat_room
* * \e string \b chat_xchan
* * \e string \b chat_text
*/
call_hooks('chat_message', $arr);
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
values( %d, '%s', '%s', '%s' )",
intval($room_id),
dbesc($xchan),
dbesc(datetime_convert()),
dbesc(str_rot47(base64url_encode($arr['chat_text'])))
);
intval($room_id),
dbesc($xchan),
dbesc(datetime_convert()),
dbesc(str_rot47(base64url_encode($arr['chat_text'])))
);
$ret['success'] = true;
return $ret;
}
$ret['success'] = true;
return $ret;
}
}

View file

@ -16,7 +16,7 @@ class Config {
* @param string $family
* The category of the configuration value
*/
static public function Load($family) {
public static function Load($family) {
if(! array_key_exists($family, App::$config))
App::$config[$family] = [];
@ -48,7 +48,7 @@ class Config {
* @return mixed
* Return the set value, or false if the database update failed
*/
static public function Set($family, $key, $value) {
public static function Set($family, $key, $value) {
// manage array value
$dbvalue = ((is_array($value)) ? serialise($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
@ -98,7 +98,7 @@ class Config {
* @param string $default (optional) default false
* @return mixed Return value or false on error or if not set
*/
static public function Get($family, $key, $default = false) {
public static function Get($family, $key, $default = false) {
if((! array_key_exists($family, App::$config)) || (! array_key_exists('config_loaded', App::$config[$family])))
self::Load($family);
@ -124,7 +124,7 @@ class Config {
* The configuration key to delete
* @return mixed
*/
static public function Delete($family, $key) {
public static function Delete($family, $key) {
$ret = false;
@ -152,7 +152,7 @@ class Config {
* The configuration key to query
* @return mixed
*/
static private function get_from_storage($family,$key) {
private static function get_from_storage($family, $key) {
$ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
dbesc($family),
dbesc($key)

View file

@ -7,302 +7,302 @@ use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Run;
class Connect
{
class Connect {
/**
* Takes a $channel and a $url/handle and adds a new connection
*
* Returns array
* $return['success'] boolean true if successful
* $return['abook'] Address book entry joined with xchan if successful
* $return['message'] error text if success is false.
*
* This function does NOT send sync packets to clones. The caller is responsible for doing this
*/
/**
* Takes a $channel and a $url/handle and adds a new connection
*
* Returns array
* $return['success'] boolean true if successful
* $return['abook'] Address book entry joined with xchan if successful
* $return['message'] error text if success is false.
*
* This function does NOT send sync packets to clones. The caller is responsible for doing this
*/
public static function connect($channel, $url, $sub_channel = false)
{
static function connect($channel, $url, $sub_channel = false) {
$uid = $channel['channel_id'];
$uid = $channel['channel_id'];
if (strpos($url, '@') === false && strpos($url, '/') === false) {
$url = $url . '@' . App::get_hostname();
}
if (strpos($url,'@') === false && strpos($url,'/') === false) {
$url = $url . '@' . App::get_hostname();
}
$result = ['success' => false, 'message' => ''];
$result = [ 'success' => false, 'message' => '' ];
$my_perms = false;
$protocol = '';
$my_perms = false;
$protocol = '';
$ap_allowed = get_config('system', 'activitypub', ACTIVITYPUB_ENABLED) && get_pconfig($uid, 'system', 'activitypub', ACTIVITYPUB_ENABLED);
$ap_allowed = get_config('system','activitypub', ACTIVITYPUB_ENABLED) && get_pconfig($uid,'system','activitypub', ACTIVITYPUB_ENABLED);
if (substr($url, 0, 1) === '[') {
$x = strpos($url, ']');
if ($x) {
$protocol = substr($url, 1, $x - 1);
$url = substr($url, $x + 1);
}
}
if (substr($url,0,1) === '[') {
$x = strpos($url,']');
if ($x) {
$protocol = substr($url,1,$x-1);
$url = substr($url,$x+1);
}
}
if (!check_siteallowed($url)) {
$result['message'] = t('Channel is blocked on this site.');
return $result;
}
if (! check_siteallowed($url)) {
$result['message'] = t('Channel is blocked on this site.');
return $result;
}
if (!$url) {
$result['message'] = t('Channel location missing.');
return $result;
}
if (! $url) {
$result['message'] = t('Channel location missing.');
return $result;
}
// check service class limits
// check service class limits
$r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ",
intval($uid)
);
if ($r) {
$total_channels = $r[0]['total'];
}
$r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ",
intval($uid)
);
if ($r) {
$total_channels = $r[0]['total'];
}
if (!service_class_allows($uid, 'total_channels', $total_channels)) {
$result['message'] = upgrade_message();
return $result;
}
if (! service_class_allows($uid,'total_channels',$total_channels)) {
$result['message'] = upgrade_message();
return $result;
}
$xchan_hash = '';
$sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : '');
$xchan_hash = '';
$sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : '');
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s') $sql_options ",
dbesc($url),
dbesc($url),
dbesc($url)
);
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s') $sql_options ",
dbesc($url),
dbesc($url),
dbesc($url)
);
if ($r) {
if ($r) {
// reset results to the best record or the first if we don't have the best
// note: this returns a single record and not an array of records
// reset results to the best record or the first if we don't have the best
// note: this returns a single record and not an array of records
$r = Libzot::zot_record_preferred($r, 'xchan_network');
$r = Libzot::zot_record_preferred($r,'xchan_network');
// ensure there's a valid hubloc for this xchan before proceeding - you cannot connect without it
// ensure there's a valid hubloc for this xchan before proceeding - you cannot connect without it
if (in_array($r['xchan_network'], ['zot6', 'activitypub'])) {
$h = q("select * from hubloc where hubloc_hash = '%s'",
dbesc($r['xchan_hash'])
);
if (!$h) {
$r = null;
}
}
if (in_array($r['xchan_network'], [ 'zot6','activitypub' ])) {
$h = q("select * from hubloc where hubloc_hash = '%s'",
dbesc($r['xchan_hash'])
);
if (! $h) {
$r = null;
}
}
// we may have nulled out this record so check again
// we may have nulled out this record so check again
if ($r) {
if ($r) {
// Check the site table to see if we should have a zot6 hubloc,
// If so, clear the xchan and start fresh
// Check the site table to see if we should have a zot6 hubloc,
// If so, clear the xchan and start fresh
if ($r['xchan_network'] === 'activitypub') {
$m = parse_url($r['xchan_hash']);
unset($m['path']);
$h = unparse_url($m);
$s = q("select * from site where site_url = '%s'",
dbesc($h)
);
if (intval($s['site_type']) === SITE_TYPE_ZOT) {
logger('got zot - ignore activitypub entry');
$r = null;
}
}
}
}
if ($r['xchan_network'] === 'activitypub') {
$m = parse_url($r['xchan_hash']);
unset($m['path']);
$h = unparse_url($m);
$s = q("select * from site where site_url = '%s'",
dbesc($h)
);
if (intval($s['site_type']) === SITE_TYPE_ZOT) {
logger('got zot - ignore activitypub entry');
$r = null;
}
}
}
}
$singleton = false;
$singleton = false;
if (! $r) {
if (!$r) {
// not in cache - try discovery
// not in cache - try discovery
$wf = discover_by_webbie($url,$protocol,false);
$wf = discover_by_webbie($url, $protocol, false);
if (! $wf) {
$result['message'] = t('Remote channel or protocol unavailable.');
return $result;
}
}
if (!$wf) {
$result['message'] = t('Remote channel or protocol unavailable.');
return $result;
}
}
if ($wf) {
if ($wf) {
// something was discovered - find the record which was just created.
// something was discovered - find the record which was just created.
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s' ) $sql_options",
dbesc(($wf) ? $wf : $url),
dbesc($url),
dbesc($url)
);
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s' ) $sql_options",
dbesc(($wf) ? $wf : $url),
dbesc($url),
dbesc($url)
);
// convert to a single record (once again preferring a zot solution in the case of multiples)
// convert to a single record (once again preferring a zot solution in the case of multiples)
if ($r) {
$r = Libzot::zot_record_preferred($r,'xchan_network');
}
}
if ($r) {
$r = Libzot::zot_record_preferred($r, 'xchan_network');
}
}
// if discovery was a success or the channel was already cached we should have an xchan record in $r
// if discovery was a success or the channel was already cached we should have an xchan record in $r
if ($r) {
$xchan = $r;
$xchan_hash = $r['xchan_hash'];
$their_perms = EMPTY_STR;
}
if ($r) {
$xchan = $r;
$xchan_hash = $r['xchan_hash'];
$their_perms = EMPTY_STR;
}
// failure case
// failure case
if (! $xchan_hash) {
$result['message'] = t('Channel discovery failed.');
logger('follow: ' . $result['message']);
return $result;
}
if (!$xchan_hash) {
$result['message'] = t('Channel discovery failed.');
logger('follow: ' . $result['message']);
return $result;
}
if (! check_channelallowed($xchan_hash)) {
$result['message'] = t('Channel is blocked on this site.');
logger('follow: ' . $result['message']);
return $result;
if (!check_channelallowed($xchan_hash)) {
$result['message'] = t('Channel is blocked on this site.');
logger('follow: ' . $result['message']);
return $result;
}
}
if ($r['xchan_network'] === 'activitypub') {
if (! $ap_allowed) {
$result['message'] = t('Protocol not supported');
return $result;
}
$singleton = true;
}
if ($r['xchan_network'] === 'activitypub') {
if (!$ap_allowed) {
$result['message'] = t('Protocol not supported');
return $result;
}
$singleton = true;
}
// Now start processing the new connection
// Now start processing the new connection
$aid = $channel['channel_account_id'];
$hash = $channel['channel_hash'];
$default_group = $channel['channel_default_group'];
$aid = $channel['channel_account_id'];
$hash = $channel['channel_hash'];
$default_group = $channel['channel_default_group'];
if ($hash === $xchan_hash) {
$result['message'] = t('Cannot connect to yourself.');
return $result;
}
if ($hash === $xchan_hash) {
$result['message'] = t('Cannot connect to yourself.');
return $result;
}
$p = Permissions::connect_perms($uid);
$p = Permissions::connect_perms($uid);
// parent channels have unencumbered write permission
// parent channels have unencumbered write permission
if ($sub_channel) {
$p['perms']['post_wall'] = 1;
$p['perms']['post_comments'] = 1;
$p['perms']['write_storage'] = 1;
$p['perms']['post_like'] = 1;
$p['perms']['delegate'] = 0;
$p['perms']['moderated'] = 0;
}
if ($sub_channel) {
$p['perms']['post_wall'] = 1;
$p['perms']['post_comments'] = 1;
$p['perms']['write_storage'] = 1;
$p['perms']['post_like'] = 1;
$p['perms']['delegate'] = 0;
$p['perms']['moderated'] = 0;
}
$my_perms = Permissions::serialise($p['perms']);
$my_perms = Permissions::serialise($p['perms']);
$profile_assign = get_pconfig($uid,'system','profile_assign','');
$profile_assign = get_pconfig($uid, 'system', 'profile_assign', '');
// See if we are already connected by virtue of having an abook record
// See if we are already connected by virtue of having an abook record
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
dbesc($xchan_hash),
intval($uid)
);
if ($r) {
if ($r) {
$abook_instance = $r[0]['abook_instance'];
$abook_instance = $r[0]['abook_instance'];
// If they are on a non-nomadic network, add them to this location
// If they are on a non-nomadic network, add them to this location
if (($singleton) && strpos($abook_instance,z_root()) === false) {
if ($abook_instance) {
$abook_instance .= ',';
}
$abook_instance .= z_root();
if (($singleton) && strpos($abook_instance, z_root()) === false) {
if ($abook_instance) {
$abook_instance .= ',';
}
$abook_instance .= z_root();
$x = q("update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
);
}
$x = q("update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
);
}
// if they have a pending connection, we just followed them so approve the connection request
// if they have a pending connection, we just followed them so approve the connection request
if (intval($r[0]['abook_pending'])) {
$x = q("update abook set abook_pending = 0 where abook_id = %d",
intval($r[0]['abook_id'])
);
}
}
else {
if (intval($r[0]['abook_pending'])) {
$x = q("update abook set abook_pending = 0 where abook_id = %d",
intval($r[0]['abook_id'])
);
}
} else {
// create a new abook record
// create a new abook record
$closeness = get_pconfig($uid,'system','new_abook_closeness',80);
$closeness = get_pconfig($uid, 'system', 'new_abook_closeness', 80);
$r = abook_store_lowlevel(
[
'abook_account' => intval($aid),
'abook_channel' => intval($uid),
'abook_closeness' => intval($closeness),
'abook_xchan' => $xchan_hash,
'abook_profile' => $profile_assign,
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_instance' => (($singleton) ? z_root() : '')
]
);
}
$r = abook_store_lowlevel(
[
'abook_account' => intval($aid),
'abook_channel' => intval($uid),
'abook_closeness' => intval($closeness),
'abook_xchan' => $xchan_hash,
'abook_profile' => $profile_assign,
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_instance' => (($singleton) ? z_root() : '')
]
);
}
if (! $r) {
logger('abook creation failed');
$result['message'] = t('error saving data');
return $result;
}
if (!$r) {
logger('abook creation failed');
$result['message'] = t('error saving data');
return $result;
}
// Set suitable permissions to the connection
// Set suitable permissions to the connection
if ($my_perms) {
set_abconfig($uid,$xchan_hash,'system','my_perms',$my_perms);
}
if ($my_perms) {
set_abconfig($uid, $xchan_hash, 'system', 'my_perms', $my_perms);
}
// fetch the entire record
// fetch the entire record
$r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
$r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
dbesc($xchan_hash),
intval($uid)
);
if ($r) {
$result['abook'] = array_shift($r);
Run::Summon([ 'Notifier', 'permissions_create', $result['abook']['abook_id'] ]);
}
if ($r) {
$result['abook'] = array_shift($r);
Run::Summon(['Notifier', 'permissions_create', $result['abook']['abook_id']]);
}
$arr = [ 'channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook'] ];
$arr = ['channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook']];
call_hooks('follow', $arr);
call_hooks('follow', $arr);
/** If there is a default group for this channel, add this connection to it */
/** If there is a default group for this channel, add this connection to it */
if ($default_group) {
$g = AccessList::rec_byhash($uid,$default_group);
if ($g) {
AccessList::member_add($uid,'',$xchan_hash,$g['id']);
}
}
if ($default_group) {
$g = AccessList::rec_byhash($uid, $default_group);
if ($g) {
AccessList::member_add($uid, '', $xchan_hash, $g['id']);
}
}
$result['success'] = true;
return $result;
}
$result['success'] = true;
return $result;
}
}

View file

@ -5,7 +5,7 @@ use Exception;
class Crypto {
static public $openssl_algorithms = [
public static $openssl_algorithms = [
// zot6 nickname, opensslname, keylength, ivlength
@ -16,7 +16,7 @@ class Crypto {
];
static public function methods() {
public static function methods() {
$ret = [];
foreach(self::$openssl_algorithms as $ossl) {
@ -28,7 +28,7 @@ class Crypto {
}
static public function signing_methods() {
public static function signing_methods() {
$ret = [ 'sha256' ];
call_hooks('signing_methods',$ret);
@ -37,7 +37,7 @@ class Crypto {
}
static public function new_keypair($bits) {
public static function new_keypair($bits) {
$openssl_options = [
'digest_alg' => 'sha1',
@ -72,7 +72,7 @@ class Crypto {
}
static public function sign($data,$key,$alg = 'sha256') {
public static function sign($data, $key, $alg = 'sha256') {
if (! $key) {
return false;
@ -84,7 +84,7 @@ class Crypto {
}
static public function verify($data,$sig,$key,$alg = 'sha256') {
public static function verify($data, $sig, $key, $alg = 'sha256') {
if (! $key) {
return false;
@ -107,7 +107,7 @@ class Crypto {
return (($verify > 0) ? true : false);
}
static public function encapsulate($data,$pubkey,$alg) {
public static function encapsulate($data, $pubkey, $alg) {
if (! ($alg && $pubkey)) {
return $data;
@ -164,7 +164,7 @@ class Crypto {
}
}
static public function unencapsulate($data,$prvkey) {
public static function unencapsulate($data, $prvkey) {
if (! (is_array($data) && array_key_exists('encrypted',$data) && array_key_exists('alg',$data) && $data['alg'])) {
logger('not encrypted');

View file

@ -5,112 +5,112 @@ namespace Zotlabs\Lib;
use App;
class DB_Upgrade {
class DB_Upgrade
{
public $config_name = '';
public $func_prefix = '';
public $config_name = '';
public $func_prefix = '';
function __construct($db_revision) {
public function __construct($db_revision)
{
$this->config_name = 'db_version';
$this->func_prefix = '_';
$this->config_name = 'db_version';
$this->func_prefix = '_';
$build = get_config('system', 'db_version', 0);
if(! intval($build))
$build = set_config('system', 'db_version', $db_revision);
$build = get_config('system', 'db_version', 0);
if (!intval($build))
$build = set_config('system', 'db_version', $db_revision);
if($build == $db_revision) {
// Nothing to be done.
return;
}
else {
$stored = intval($build);
if(! $stored) {
logger('Critical: check_config unable to determine database schema version');
return;
}
if ($build == $db_revision) {
// Nothing to be done.
return;
} else {
$stored = intval($build);
if (!$stored) {
logger('Critical: check_config unable to determine database schema version');
return;
}
$current = intval($db_revision);
$current = intval($db_revision);
if($stored < $current) {
if ($stored < $current) {
// The last update we performed was $stored.
// Start at $stored + 1 and continue until we have completed $current
// The last update we performed was $stored.
// Start at $stored + 1 and continue until we have completed $current
for($x = $stored + 1; $x <= $current; $x ++) {
$s = '_' . $x;
$cls = '\\Zotlabs\Update\\' . $s ;
if(! class_exists($cls)) {
return;
}
for ($x = $stored + 1; $x <= $current; $x++) {
$s = '_' . $x;
$cls = '\\Zotlabs\Update\\' . $s;
if (!class_exists($cls)) {
return;
}
// There could be a lot of processes running or about to run.
// We want exactly one process to run the update command.
// So store the fact that we're taking responsibility
// after first checking to see if somebody else already has.
// There could be a lot of processes running or about to run.
// We want exactly one process to run the update command.
// So store the fact that we're taking responsibility
// after first checking to see if somebody else already has.
// If the update fails or times-out completely you may need to
// delete the config entry to try again.
// If the update fails or times-out completely you may need to
// delete the config entry to try again.
Config::Load('database');
Config::Load('database');
if(get_config('database', $s))
break;
set_config('database',$s, '1');
if (get_config('database', $s))
break;
set_config('database', $s, '1');
$c = new $cls();
$c = new $cls();
$retval = $c->run();
$retval = $c->run();
if($retval != UPDATE_SUCCESS) {
if ($retval != UPDATE_SUCCESS) {
$source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php');
$source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php');
// Prevent sending hundreds of thousands of emails by creating
// a lockfile.
// Prevent sending hundreds of thousands of emails by creating
// a lockfile.
$lockfile = 'cache/mailsent';
$lockfile = 'cache/mailsent';
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400)))
return;
@unlink($lockfile);
//send the administrator an e-mail
file_put_contents($lockfile, $x);
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400)))
return;
@unlink($lockfile);
//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');
z_mail(
[
'toEmail' => App::$config['system']['admin_email'],
'messageSubject' => sprintf( t('Update Error at %s'), z_root()),
'textVersion' => replace_macros(get_intltext_template('update_fail_eml.tpl'),
[
'$sitename' => App::$config['system']['sitename'],
'$siteurl' => z_root(),
'$update' => $x,
'$error' => sprintf( t('Update %s failed. See error logs.'), $x),
'$baseurl' => z_root(),
'$source' => $source
]
)
]
);
$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');
z_mail(
[
'toEmail' => App::$config['system']['admin_email'],
'messageSubject' => sprintf(t('Update Error at %s'), z_root()),
'textVersion' => replace_macros(get_intltext_template('update_fail_eml.tpl'),
[
'$sitename' => App::$config['system']['sitename'],
'$siteurl' => z_root(),
'$update' => $x,
'$error' => sprintf(t('Update %s failed. See error logs.'), $x),
'$baseurl' => z_root(),
'$source' => $source
]
)
]
);
//try the logger
logger('CRITICAL: Update Failed: ' . $x);
pop_lang();
}
else {
set_config('database',$s, 'success');
}
}
}
set_config('system', 'db_version', $db_revision);
}
}
//try the logger
logger('CRITICAL: Update Failed: ' . $x);
pop_lang();
} else {
set_config('database', $s, 'success');
}
}
}
set_config('system', 'db_version', $db_revision);
}
}
}

View file

@ -1,135 +1,143 @@
<?php
namespace Zotlabs\Lib;
class DReport {
class DReport
{
private $location;
private $sender;
private $recipient;
private $message_id;
private $status;
private $date;
private $location;
private $sender;
private $recipient;
private $message_id;
private $status;
private $date;
function __construct($location,$sender,$recipient,$message_id,$status = 'deliver') {
$this->location = $location;
$this->sender = $sender;
$this->recipient = $recipient;
$this->name = EMPTY_STR;
$this->message_id = $message_id;
$this->status = $status;
$this->date = datetime_convert();
}
public function __construct($location, $sender, $recipient, $message_id, $status = 'deliver')
{
$this->location = $location;
$this->sender = $sender;
$this->recipient = $recipient;
$this->name = EMPTY_STR;
$this->message_id = $message_id;
$this->status = $status;
$this->date = datetime_convert();
}
function update($status) {
$this->status = $status;
$this->date = datetime_convert();
}
public function update($status)
{
$this->status = $status;
$this->date = datetime_convert();
}
function set_name($name) {
$this->name = $name;
}
public function set_name($name)
{
$this->name = $name;
}
function addto_update($status) {
$this->status = $this->status . ' ' . $status;
}
public function addto_update($status)
{
$this->status = $this->status . ' ' . $status;
}
function set($arr) {
$this->location = $arr['location'];
$this->sender = $arr['sender'];
$this->recipient = $arr['recipient'];
$this->name = $arr['name'];
$this->message_id = $arr['message_id'];
$this->status = $arr['status'];
$this->date = $arr['date'];
}
public function set($arr)
{
$this->location = $arr['location'];
$this->sender = $arr['sender'];
$this->recipient = $arr['recipient'];
$this->name = $arr['name'];
$this->message_id = $arr['message_id'];
$this->status = $arr['status'];
$this->date = $arr['date'];
}
function get() {
return array(
'location' => $this->location,
'sender' => $this->sender,
'recipient' => $this->recipient,
'name' => $this->name,
'message_id' => $this->message_id,
'status' => $this->status,
'date' => $this->date
);
}
public function get()
{
return array(
'location' => $this->location,
'sender' => $this->sender,
'recipient' => $this->recipient,
'name' => $this->name,
'message_id' => $this->message_id,
'status' => $this->status,
'date' => $this->date
);
}
/**
* @brief decide whether to store a returned delivery report
*
* @param array $dr
* @return boolean
*/
/**
* @brief decide whether to store a returned delivery report
*
* @param array $dr
* @return bool
*/
static function is_storable($dr) {
public static function is_storable($dr)
{
if(get_config('system', 'disable_dreport'))
return false;
if (get_config('system', 'disable_dreport'))
return false;
/**
* @hooks dreport_is_storable
* Called before storing a dreport record to determine whether to store it.
* * \e array
*/
/**
* @hooks dreport_is_storable
* Called before storing a dreport record to determine whether to store it.
* * \e array
*/
call_hooks('dreport_is_storable', $dr);
call_hooks('dreport_is_storable', $dr);
// let plugins accept or reject - if neither, continue on
if(array_key_exists('accept',$dr) && intval($dr['accept']))
return true;
if(array_key_exists('reject',$dr) && intval($dr['reject']))
return false;
// let plugins accept or reject - if neither, continue on
if (array_key_exists('accept', $dr) && intval($dr['accept']))
return true;
if (array_key_exists('reject', $dr) && intval($dr['reject']))
return false;
if(! ($dr['sender']))
return false;
if (!($dr['sender']))
return false;
// Is the sender one of our channels?
// Is the sender one of our channels?
$c = q("select channel_id from channel where channel_hash = '%s' limit 1",
dbesc($dr['sender'])
);
if(! $c)
return false;
$c = q("select channel_id from channel where channel_hash = '%s' limit 1",
dbesc($dr['sender'])
);
if (!$c)
return false;
// is the recipient one of our connections, or do we want to store every report?
// is the recipient one of our connections, or do we want to store every report?
$rxchan = $dr['recipient'];
$pcf = get_pconfig($c[0]['channel_id'],'system','dreport_store_all');
if($pcf)
return true;
$rxchan = $dr['recipient'];
$pcf = get_pconfig($c[0]['channel_id'], 'system', 'dreport_store_all');
if ($pcf)
return true;
// We always add ourself as a recipient to private and relayed posts
// So if a remote site says they can't find us, that's no big surprise
// and just creates a lot of extra report noise
// We always add ourself as a recipient to private and relayed posts
// So if a remote site says they can't find us, that's no big surprise
// and just creates a lot of extra report noise
if(($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient not found'))
return false;
if (($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient not found'))
return false;
// If you have a private post with a recipient list, every single site is going to report
// back a failed delivery for anybody on that list that isn't local to them. We're only
// concerned about this if we have a local hubloc record which says we expected them to
// have a channel on that site.
// If you have a private post with a recipient list, every single site is going to report
// back a failed delivery for anybody on that list that isn't local to them. We're only
// concerned about this if we have a local hubloc record which says we expected them to
// have a channel on that site.
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'",
dbesc($rxchan),
dbesc($dr['location'])
);
if((! $r) && ($dr['status'] === 'recipient not found'))
return false;
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'",
dbesc($rxchan),
dbesc($dr['location'])
);
if ((!$r) && ($dr['status'] === 'recipient not found'))
return false;
$r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($rxchan),
intval($c[0]['channel_id'])
);
if($r)
return true;
$r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($rxchan),
intval($c[0]['channel_id'])
);
if ($r)
return true;
return false;
}
return false;
}
}

View file

@ -29,7 +29,7 @@ class Enotify {
*/
static public function submit($params) {
public static function submit($params) {
logger('notification: entry', LOGGER_DEBUG);
@ -807,7 +807,7 @@ class Enotify {
* * \e string \b textVersion text only version of the message
* * \e string \b additionalMailHeader additions to the smtp mail header
*/
static public function send($params) {
public static function send($params) {
$params['sent'] = false;
$params['result'] = false;
@ -862,7 +862,7 @@ class Enotify {
return $res;
}
static public function format($item) {
public static function format($item) {
$ret = '';

View file

@ -28,29 +28,30 @@ namespace Zotlabs\Lib;
*
*/
class Hashpath {
class Hashpath
{
static function path($url, $prefix = '.', $depth = 1, $mkdir = true) {
$hash = hash('sha256', $url);
$start = 0;
$slice = 2;
if ($depth < 1) {
$depth = 1;
}
$sluglen = $depth * $slice;
public static function path($url, $prefix = '.', $depth = 1, $mkdir = true)
{
$hash = hash('sha256', $url);
$start = 0;
$slice = 2;
if ($depth < 1) {
$depth = 1;
}
$sluglen = $depth * $slice;
do {
$slug = substr($hash,$start,$slice);
$prefix .= '/' . $slug;
$start += $slice;
$sluglen -= $slice;
}
while ($sluglen);
do {
$slug = substr($hash, $start, $slice);
$prefix .= '/' . $slug;
$start += $slice;
$sluglen -= $slice;
} while ($sluglen);
if ($mkdir) {
os_mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
}
if ($mkdir) {
os_mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
}
return $prefix . '/' . $hash;
}
return $prefix . '/' . $hash;
}
}

View file

@ -6,11 +6,11 @@ namespace Zotlabs\Lib;
class IConfig {
static public function Load(&$item) {
public static function Load(&$item) {
return;
}
static public function Get(&$item, $family, $key, $default = false) {
public static function Get(&$item, $family, $key, $default = false) {
$is_item = false;
@ -76,7 +76,7 @@ class IConfig {
*/
static public function Set(&$item, $family, $key, $value, $sharing = false) {
public static function Set(&$item, $family, $key, $value, $sharing = false) {
$dbvalue = ((is_array($value)) ? serialise($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
@ -137,7 +137,7 @@ class IConfig {
static public function Delete(&$item, $family, $key) {
public static function Delete(&$item, $family, $key) {
$is_item = false;

View file

@ -4,78 +4,81 @@ namespace Zotlabs\Lib;
use Zotlabs\Lib\Hashpath;
use Zotlabs\Daemon\Run;
class Img_cache {
class Img_cache
{
static $cache_life = 18600 * 7;
static public $cache_life = 18600 * 7;
static function get_filename($url, $prefix = '.') {
return Hashpath::path($url,$prefix);
}
public static function get_filename($url, $prefix = '.')
{
return Hashpath::path($url, $prefix);
}
// Check to see if we have this url in our cache
// If we have it return true.
// If we do not, or the cache file is empty or expired, return false
// but attempt to fetch the entry in the background
// Check to see if we have this url in our cache
// If we have it return true.
// If we do not, or the cache file is empty or expired, return false
// but attempt to fetch the entry in the background
static function check($url, $prefix = '.') {
public static function check($url, $prefix = '.')
{
if (strpos($url,z_root()) !== false) {
return false;
}
if (strpos($url, z_root()) !== false) {
return false;
}
$path = self::get_filename($url,$prefix);
if (file_exists($path)) {
$t = filemtime($path);
if ($t && time() - $t >= self::$cache_life) {
Run::Summon( [ 'Cache_image', $url, $path ] );
return false;
}
else {
return ((filesize($path)) ? true : false);
}
}
$path = self::get_filename($url, $prefix);
if (file_exists($path)) {
$t = filemtime($path);
if ($t && time() - $t >= self::$cache_life) {
Run::Summon(['Cache_image', $url, $path]);
return false;
} else {
return ((filesize($path)) ? true : false);
}
}
// Cache_image invokes url_to_cache() as a background task
// Cache_image invokes url_to_cache() as a background task
Run::Summon( [ 'Cache_image', $url, $path ] );
return false;
}
Run::Summon(['Cache_image', $url, $path]);
return false;
}
static function url_to_cache($url,$file) {
public static function url_to_cache($url, $file)
{
$fp = fopen($file,'wb');
$fp = fopen($file, 'wb');
if (! $fp) {
logger('failed to open storage file: ' . $file,LOGGER_NORMAL,LOG_ERR);
return false;
}
if (!$fp) {
logger('failed to open storage file: ' . $file, LOGGER_NORMAL, LOG_ERR);
return false;
}
// don't check certs, and since we're running in the background,
// allow a two-minute timeout rather than the default one minute.
// This is a compromise. We want to cache all the slow sites we can,
// but don't want to rack up too many processes doing so.
// don't check certs, and since we're running in the background,
// allow a two-minute timeout rather than the default one minute.
// This is a compromise. We want to cache all the slow sites we can,
// but don't want to rack up too many processes doing so.
$redirects = 0;
$x = z_fetch_url($url,true,$redirects,[ 'filep' => $fp, 'novalidate' => true, 'timeout' => 120 ]);
$redirects = 0;
$x = z_fetch_url($url, true, $redirects, ['filep' => $fp, 'novalidate' => true, 'timeout' => 120]);
fclose($fp);
fclose($fp);
if ($x['success'] && file_exists($file)) {
$i = @getimagesize($file);
if ($i && $i[2]) { // looking for non-zero imagetype
Run::Summon( [ 'CacheThumb' , basename($file) ] );
return true;
}
}
if ($x['success'] && file_exists($file)) {
$i = @getimagesize($file);
if ($i && $i[2]) { // looking for non-zero imagetype
Run::Summon(['CacheThumb', basename($file)]);
return true;
}
}
// We could not cache the image for some reason. Leave an empty file here
// to provide a record of the attempt. We'll use this as a flag to avoid
// doing it again repeatedly.
// We could not cache the image for some reason. Leave an empty file here
// to provide a record of the attempt. We'll use this as a flag to avoid
// doing it again repeatedly.
file_put_contents($file, EMPTY_STR);
logger('cache failed from ' . $url);
return false;
}
file_put_contents($file, EMPTY_STR);
logger('cache failed from ' . $url);
return false;
}
}

View file

@ -2,50 +2,54 @@
namespace Zotlabs\Lib;
class Img_filesize {
class Img_filesize
{
private $url;
private $url;
function __construct($url) {
$this->url = $url;
}
public function __construct($url)
{
$this->url = $url;
}
function getSize() {
$size = null;
public function getSize()
{
$size = null;
if(stripos($this->url,z_root() . '/photo') !== false) {
$size = self::getLocalFileSize($this->url);
}
if(! $size) {
$size = getRemoteFileSize($this->url);
}
if (stripos($this->url, z_root() . '/photo') !== false) {
$size = self::getLocalFileSize($this->url);
}
if (!$size) {
$size = getRemoteFileSize($this->url);
}
return $size;
}
return $size;
}
static function getLocalFileSize($url) {
public static function getLocalFileSize($url)
{
$fname = basename($url);
$resolution = 0;
$fname = basename($url);
$resolution = 0;
if(strpos($fname,'.') !== false)
$fname = substr($fname,0,strpos($fname,'.'));
if (strpos($fname, '.') !== false)
$fname = substr($fname, 0, strpos($fname, '.'));
if(substr($fname,-2,1) == '-') {
$resolution = intval(substr($fname,-1,1));
$fname = substr($fname,0,-2);
}
if (substr($fname, -2, 1) == '-') {
$resolution = intval(substr($fname, -1, 1));
$fname = substr($fname, 0, -2);
}
$r = q("SELECT filesize FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($fname),
intval($resolution)
);
if($r) {
return $r[0]['filesize'];
}
return null;
}
$r = q("SELECT filesize FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($fname),
intval($resolution)
);
if ($r) {
return $r[0]['filesize'];
}
return null;
}
}

View file

@ -4,69 +4,73 @@ namespace Zotlabs\Lib;
use Zotlabs\Web\HTTPSig;
class JSalmon {
class JSalmon
{
static function sign($data,$key_id,$key,$data_type = 'application/x-zot+json') {
public static function sign($data, $key_id, $key, $data_type = 'application/x-zot+json')
{
$data = base64url_encode(json_encode($data,true),true); // strip padding
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$data = base64url_encode(json_encode($data, true), true); // strip padding
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$data = preg_replace('/\s+/','',$data);
$data = preg_replace('/\s+/', '', $data);
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
$precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
$precomputed = '.' . base64url_encode($data_type, true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
$signature = base64url_encode(Crypto::sign($data . $precomputed, $key), true);
$signature = base64url_encode(Crypto::sign($data . $precomputed, $key), true);
return ([
'signed' => true,
'data' => $data,
'data_type' => $data_type,
'encoding' => $encoding,
'alg' => $algorithm,
'sigs' => [
'value' => $signature,
'key_id' => base64url_encode($key_id, true)
]
]);
return ([
'signed' => true,
'data' => $data,
'data_type' => $data_type,
'encoding' => $encoding,
'alg' => $algorithm,
'sigs' => [
'value' => $signature,
'key_id' => base64url_encode($key_id, true)
]
]);
}
}
static function verify($x) {
public static function verify($x)
{
logger('verify');
$ret = [ 'results' => [] ];
logger('verify');
$ret = ['results' => []];
if(! is_array($x)) {
return false;
}
if(! ( array_key_exists('signed',$x) && $x['signed'])) {
return false;
}
if (!is_array($x)) {
return false;
}
if (!(array_key_exists('signed', $x) && $x['signed'])) {
return false;
}
$signed_data = preg_replace('/\s+/','',$x['data']) . '.'
. base64url_encode($x['data_type'],true) . '.'
. base64url_encode($x['encoding'],true) . '.'
. base64url_encode($x['alg'],true);
$signed_data = preg_replace('/\s+/', '', $x['data']) . '.'
. base64url_encode($x['data_type'], true) . '.'
. base64url_encode($x['encoding'], true) . '.'
. base64url_encode($x['alg'], true);
$key = HTTPSig::get_key(EMPTY_STR,'zot6',base64url_decode($x['sigs']['key_id']));
logger('key: ' . print_r($key,true));
if($key['portable_id'] && $key['public_key']) {
if(Crypto::verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
logger('verified');
$ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ];
}
}
$key = HTTPSig::get_key(EMPTY_STR, 'zot6', base64url_decode($x['sigs']['key_id']));
logger('key: ' . print_r($key, true));
if ($key['portable_id'] && $key['public_key']) {
if (Crypto::verify($signed_data, base64url_decode($x['sigs']['value']), $key['public_key'])) {
logger('verified');
$ret = ['success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc']];
}
}
return $ret;
return $ret;
}
}
static function unpack($data) {
return json_decode(base64url_decode($data),true);
}
public static function unpack($data)
{
return json_decode(base64url_decode($data), true);
}
}

View file

@ -7,127 +7,134 @@ use Zotlabs\Lib\Activity;
require_once('library/jsonld/jsonld.php');
class LDSignatures {
class LDSignatures
{
static function verify($data,$pubkey) {
public static function verify($data, $pubkey)
{
$ohash = self::hash(self::signable_options($data['signature']));
$dhash = self::hash(self::signable_data($data));
$ohash = self::hash(self::signable_options($data['signature']));
$dhash = self::hash(self::signable_data($data));
$x = Crypto::verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
logger('LD-verify: ' . intval($x));
$x = Crypto::verify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
logger('LD-verify: ' . intval($x));
return $x;
}
return $x;
}
static function dopplesign(&$data,$channel) {
// remove for the time being - performance issues
// $data['magicEnv'] = self::salmon_sign($data,$channel);
return self::sign($data,$channel);
}
public static function dopplesign(&$data, $channel)
{
// remove for the time being - performance issues
// $data['magicEnv'] = self::salmon_sign($data,$channel);
return self::sign($data, $channel);
}
static function sign($data,$channel) {
public static function sign($data, $channel)
{
$options = [
'type' => 'RsaSignature2017',
'nonce' => random_string(64),
'creator' => channel_url($channel),
'created' => datetime_convert('UTC','UTC', 'now', 'Y-m-d\TH:i:s\Z')
];
$options = [
'type' => 'RsaSignature2017',
'nonce' => random_string(64),
'creator' => channel_url($channel),
'created' => datetime_convert('UTC', 'UTC', 'now', 'Y-m-d\TH:i:s\Z')
];
$ohash = self::hash(self::signable_options($options));
$dhash = self::hash(self::signable_data($data));
$options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash,$channel['channel_prvkey']));
$ohash = self::hash(self::signable_options($options));
$dhash = self::hash(self::signable_data($data));
$options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash, $channel['channel_prvkey']));
return $options;
}
return $options;
}
static function signable_data($data) {
public static function signable_data($data)
{
$newdata = [];
if($data) {
foreach($data as $k => $v) {
if(! in_array($k,[ 'signature' ])) {
$newdata[$k] = $v;
}
}
}
return json_encode($newdata,JSON_UNESCAPED_SLASHES);
}
$newdata = [];
if ($data) {
foreach ($data as $k => $v) {
if (!in_array($k, ['signature'])) {
$newdata[$k] = $v;
}
}
}
return json_encode($newdata, JSON_UNESCAPED_SLASHES);
}
static function signable_options($options) {
public static function signable_options($options)
{
$newopts = [ '@context' => 'https://w3id.org/identity/v1' ];
if($options) {
foreach($options as $k => $v) {
if(! in_array($k,[ 'type','id','signatureValue' ])) {
$newopts[$k] = $v;
}
}
}
return json_encode($newopts,JSON_UNESCAPED_SLASHES);
}
$newopts = ['@context' => 'https://w3id.org/identity/v1'];
if ($options) {
foreach ($options as $k => $v) {
if (!in_array($k, ['type', 'id', 'signatureValue'])) {
$newopts[$k] = $v;
}
}
}
return json_encode($newopts, JSON_UNESCAPED_SLASHES);
}
static function hash($obj) {
public static function hash($obj)
{
return hash('sha256',self::normalise($obj));
}
return hash('sha256', self::normalise($obj));
}
static function normalise($data) {
if(is_string($data)) {
$data = json_decode($data);
}
public static function normalise($data)
{
if (is_string($data)) {
$data = json_decode($data);
}
if(! is_object($data))
return '';
if (!is_object($data))
return '';
jsonld_set_document_loader('jsonld_document_loader');
jsonld_set_document_loader('jsonld_document_loader');
try {
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
}
catch (Exception $e) {
// Don't log the exception - this can exhaust memory
// logger('normalise error:' . print_r($e,true));
logger('normalise error: ' . print_r($data,true));
}
try {
$d = jsonld_normalize($data, ['algorithm' => 'URDNA2015', 'format' => 'application/nquads']);
} catch (Exception $e) {
// Don't log the exception - this can exhaust memory
// logger('normalise error:' . print_r($e,true));
logger('normalise error: ' . print_r($data, true));
}
return $d;
}
return $d;
}
static function salmon_sign($data,$channel) {
public static function salmon_sign($data, $channel)
{
$arr = $data;
$data = json_encode($data,JSON_UNESCAPED_SLASHES);
$data = base64url_encode($data, false); // do not strip padding
$data_type = 'application/activity+json';
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$keyhash = base64url_encode(channel_url($channel));
$arr = $data;
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
$data = base64url_encode($data, false); // do not strip padding
$data_type = 'application/activity+json';
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$keyhash = base64url_encode(channel_url($channel));
$data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$data);
$data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $data);
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
$precomputed = '.' . base64url_encode($data_type, false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
$signature = base64url_encode(Crypto::sign($data . $precomputed,$channel['channel_prvkey']));
$signature = base64url_encode(Crypto::sign($data . $precomputed, $channel['channel_prvkey']));
return ([
'id' => $arr['id'],
'meData' => $data,
'meDataType' => $data_type,
'meEncoding' => $encoding,
'meAlgorithm' => $algorithm,
'meCreator' => channel_url($channel),
'meSignatureValue' => $signature
]);
}
return ([
'id' => $arr['id'],
'meData' => $data,
'meDataType' => $data_type,
'meEncoding' => $encoding,
'meAlgorithm' => $algorithm,
'meCreator' => channel_url($channel),
'meSignatureValue' => $signature
]);
}
}

View file

@ -3,108 +3,114 @@
namespace Zotlabs\Lib;
class LibBlock {
class LibBlock
{
static $cache = [];
static $empty = [];
static public $cache = [];
static public $empty = [];
// This limits the number of DB queries for fetch_by_entity to once per page load.
// This limits the number of DB queries for fetch_by_entity to once per page load.
static function fetch_from_cache($channel_id,$entity) {
if (! isset(self::$cache[$channel_id])) {
if (! isset(self::$empty[$channel_id])) {
self::$cache[$channel_id] = self::fetch($channel_id);
if (! self::$cache[$channel_id]) {
self::$empty[$channel_id] = true;
}
}
}
if (isset(self::$cache[$channel_id]) && self::$cache[$channel_id] && is_array(self::$cache[$channel_id])) {
foreach (self::$cache[$channel_id] as $entry) {
if (is_array($entry) && strcasecmp($entry['block_entity'],$entity) === 0) {
return $entry;
}
}
}
return false;
}
public static function fetch_from_cache($channel_id, $entity)
{
if (!isset(self::$cache[$channel_id])) {
if (!isset(self::$empty[$channel_id])) {
self::$cache[$channel_id] = self::fetch($channel_id);
if (!self::$cache[$channel_id]) {
self::$empty[$channel_id] = true;
}
}
}
if (isset(self::$cache[$channel_id]) && self::$cache[$channel_id] && is_array(self::$cache[$channel_id])) {
foreach (self::$cache[$channel_id] as $entry) {
if (is_array($entry) && strcasecmp($entry['block_entity'], $entity) === 0) {
return $entry;
}
}
}
return false;
}
static function store($arr) {
public static function store($arr)
{
$arr['block_entity'] = trim($arr['block_entity']);
$arr['block_entity'] = trim($arr['block_entity']);
if (! $arr['block_entity']) {
return false;
}
if (!$arr['block_entity']) {
return false;
}
$arr['block_channel_id'] = ((array_key_exists('block_channel_id',$arr)) ? intval($arr['block_channel_id']) : 0);
$arr['block_type'] = ((array_key_exists('block_type',$arr)) ? intval($arr['block_type']) : BLOCKTYPE_CHANNEL );
$arr['block_comment'] = ((array_key_exists('block_comment',$arr)) ? escape_tags(trim($arr['block_comment'])) : EMPTY_STR);
$arr['block_channel_id'] = ((array_key_exists('block_channel_id', $arr)) ? intval($arr['block_channel_id']) : 0);
$arr['block_type'] = ((array_key_exists('block_type', $arr)) ? intval($arr['block_type']) : BLOCKTYPE_CHANNEL);
$arr['block_comment'] = ((array_key_exists('block_comment', $arr)) ? escape_tags(trim($arr['block_comment'])) : EMPTY_STR);
if (! intval($arr['block_id'])) {
$r = q("select * from block where block_channel_id = %d and block_entity = '%s' and block_type = %d limit 1",
intval($arr['block_channel_id']),
dbesc($arr['block_entity']),
intval($arr['block_type'])
);
if ($r) {
$arr['block_id'] = $r[0]['block_id'];
}
}
if (!intval($arr['block_id'])) {
$r = q("select * from block where block_channel_id = %d and block_entity = '%s' and block_type = %d limit 1",
intval($arr['block_channel_id']),
dbesc($arr['block_entity']),
intval($arr['block_type'])
);
if ($r) {
$arr['block_id'] = $r[0]['block_id'];
}
}
if (intval($arr['block_id'])) {
return q("UPDATE block set block_channel_id = %d, block_entity = '%s', block_type = %d, block_comment = '%s' where block_id = %d",
intval($arr['block_channel_id']),
dbesc($arr['block_entity']),
intval($arr['block_type']),
dbesc($arr['block_comment']),
intval($arr['block_id'])
);
}
else {
return create_table_from_array('block',$arr);
}
}
if (intval($arr['block_id'])) {
return q("UPDATE block set block_channel_id = %d, block_entity = '%s', block_type = %d, block_comment = '%s' where block_id = %d",
intval($arr['block_channel_id']),
dbesc($arr['block_entity']),
intval($arr['block_type']),
dbesc($arr['block_comment']),
intval($arr['block_id'])
);
} else {
return create_table_from_array('block', $arr);
}
}
static function remove($channel_id,$entity) {
return q("delete from block where block_channel_id = %d and block_entity = '%s'",
intval($channel_id),
dbesc($entity)
);
}
public static function remove($channel_id, $entity)
{
return q("delete from block where block_channel_id = %d and block_entity = '%s'",
intval($channel_id),
dbesc($entity)
);
}
static function fetch_by_id($channel_id,$id) {
if (! intval($channel_id)) {
return false;
}
$r = q("select * from block where block_channel_id = %d and block_id = %d ",
intval($channel_id)
);
return (($r) ? array_shift($r) : $r);
}
public static function fetch_by_id($channel_id, $id)
{
if (!intval($channel_id)) {
return false;
}
$r = q("select * from block where block_channel_id = %d and block_id = %d ",
intval($channel_id)
);
return (($r) ? array_shift($r) : $r);
}
static function fetch_by_entity($channel_id,$entity) {
if (! intval($channel_id)) {
return false;
}
public static function fetch_by_entity($channel_id, $entity)
{
if (!intval($channel_id)) {
return false;
}
return self::fetch_from_cache($channel_id,$entity);
return self::fetch_from_cache($channel_id, $entity);
}
}
static function fetch($channel_id,$type = false) {
if (! intval($channel_id)) {
return [];
}
public static function fetch($channel_id, $type = false)
{
if (!intval($channel_id)) {
return [];
}
$sql_extra = (($type === false) ? EMPTY_STR : " and block_type = " . intval($type));
$sql_extra = (($type === false) ? EMPTY_STR : " and block_type = " . intval($type));
$r = q("select * from block where block_channel_id = %d $sql_extra",
intval($channel_id)
);
return $r;
}
$r = q("select * from block where block_channel_id = %d $sql_extra",
intval($channel_id)
);
return $r;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,332 +10,336 @@ use Zotlabs\Lib\Zotfinger;
require_once('include/permissions.php');
class Libzotdir {
class Libzotdir
{
/**
* Directories may come and go over time. We will need to check that our
* directory server is still valid occasionally, and reset to something that
* is if our directory has gone offline for any reason
*/
/**
* Directories may come and go over time. We will need to check that our
* directory server is still valid occasionally, and reset to something that
* is if our directory has gone offline for any reason
*/
static function check_upstream_directory() {
public static function check_upstream_directory()
{
$directory = get_config('system', 'directory_server');
$directory = get_config('system', 'directory_server');
// it's possible there is no directory server configured and the local hub is being used.
// If so, default to preserving the absence of a specific server setting.
// it's possible there is no directory server configured and the local hub is being used.
// If so, default to preserving the absence of a specific server setting.
$isadir = true;
$isadir = true;
if ($directory) {
$j = Zotfinger::exec($directory);
if (array_path_exists('data/directory_mode',$j)) {
if ($j['data']['directory_mode'] === 'normal') {
$isadir = false;
}
}
}
if ($directory) {
$j = Zotfinger::exec($directory);
if (array_path_exists('data/directory_mode', $j)) {
if ($j['data']['directory_mode'] === 'normal') {
$isadir = false;
}
}
}
if (! $isadir)
set_config('system', 'directory_server', '');
}
if (!$isadir)
set_config('system', 'directory_server', '');
}
static function get_directory_setting($observer, $setting) {
public static function get_directory_setting($observer, $setting)
{
if ($observer)
$ret = get_xconfig($observer, 'directory', $setting);
else
$ret = ((array_key_exists($setting,$_SESSION)) ? intval($_SESSION[$setting]) : false);
if ($observer)
$ret = get_xconfig($observer, 'directory', $setting);
else
$ret = ((array_key_exists($setting, $_SESSION)) ? intval($_SESSION[$setting]) : false);
if($ret === false) {
$ret = get_config('directory', $setting);
if($ret === false) {
$ret = (in_array($setting,[ 'globaldir','safemode', 'activedir' ]) ? 1 : 0);
}
}
if ($ret === false) {
$ret = get_config('directory', $setting);
if ($ret === false) {
$ret = (in_array($setting, ['globaldir', 'safemode', 'activedir']) ? 1 : 0);
}
}
if($setting === 'globaldir' && intval(get_config('system','localdir_hide')))
$ret = 1;
if ($setting === 'globaldir' && intval(get_config('system', 'localdir_hide')))
$ret = 1;
return $ret;
}
return $ret;
}
/**
* @brief Called by the directory_sort widget.
*/
static function dir_sort_links() {
/**
* @brief Called by the directory_sort widget.
*/
public static function dir_sort_links()
{
$safe_mode = 1;
$safe_mode = 1;
$observer = get_observer_hash();
$observer = get_observer_hash();
$safe_mode = self::get_directory_setting($observer, 'safemode');
$globaldir = self::get_directory_setting($observer, 'globaldir');
$pubforums = self::get_directory_setting($observer, 'chantype');
$activedir = self::get_directory_setting($observer, 'activedir');
$safe_mode = self::get_directory_setting($observer, 'safemode');
$globaldir = self::get_directory_setting($observer, 'globaldir');
$pubforums = self::get_directory_setting($observer, 'chantype');
$activedir = self::get_directory_setting($observer, 'activedir');
$hide_local = intval(get_config('system','localdir_hide'));
if ($hide_local) {
$globaldir = 1;
}
$hide_local = intval(get_config('system', 'localdir_hide'));
if ($hide_local) {
$globaldir = 1;
}
// Build urls without order and pubforums so it's easy to tack on the changed value
// Probably there's an easier way to do this
// Build urls without order and pubforums so it's easy to tack on the changed value
// Probably there's an easier way to do this
$directory_sort_order = get_config('system','directory_sort_order');
if (! $directory_sort_order) {
$directory_sort_order = 'date';
}
$directory_sort_order = get_config('system', 'directory_sort_order');
if (!$directory_sort_order) {
$directory_sort_order = 'date';
}
$current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : $directory_sort_order);
$suggest = (($_REQUEST['suggest']) ? '&suggest=' . $_REQUEST['suggest'] : '');
$current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : $directory_sort_order);
$suggest = (($_REQUEST['suggest']) ? '&suggest=' . $_REQUEST['suggest'] : '');
$url = 'directory?f=';
$url = 'directory?f=';
$tmp = array_merge($_GET,$_POST);
unset($tmp['suggest']);
unset($tmp['pubforums']);
unset($tmp['type']);
unset($tmp['global']);
unset($tmp['safe']);
unset($tmp['active']);
unset($tmp['req']);
unset($tmp['f']);
$q = http_build_query($tmp);
$forumsurl = $url . (($q) ? '&' . $q : '') . $suggest;
$tmp = array_merge($_GET, $_POST);
unset($tmp['suggest']);
unset($tmp['pubforums']);
unset($tmp['type']);
unset($tmp['global']);
unset($tmp['safe']);
unset($tmp['active']);
unset($tmp['req']);
unset($tmp['f']);
$q = http_build_query($tmp);
$forumsurl = $url . (($q) ? '&' . $q : '') . $suggest;
$o = replace_macros(get_markup_template('dir_sort_links.tpl'), [
'$header' => t('Directory Options'),
'$forumsurl' => $forumsurl,
'$safemode' => array('safemode', t('Safe Mode'),$safe_mode,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''),
'$pubforums' => array('pubforums', t('Groups Only'),(($pubforums == 1) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 1 : 0)\''),
$o = replace_macros(get_markup_template('dir_sort_links.tpl'), [
'$header' => t('Directory Options'),
'$forumsurl' => $forumsurl,
'$safemode' => array('safemode', t('Safe Mode'), $safe_mode, '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''),
'$pubforums' => array('pubforums', t('Groups Only'), (($pubforums == 1) ? true : false), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 1 : 0)\''),
// '$collections' => array('collections', t('Collections Only'),(($pubforums == 2) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 2 : 0)\''),
'$hide_local' => $hide_local,
'$globaldir' => array('globaldir', t('This Website Only'), 1-intval($globaldir),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''),
'$activedir' => array('activedir', t('Recently Updated'), intval($activedir),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&active="+(this.checked ? 1 : 0)\''),
]);
'$hide_local' => $hide_local,
'$globaldir' => array('globaldir', t('This Website Only'), 1 - intval($globaldir), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''),
'$activedir' => array('activedir', t('Recently Updated'), intval($activedir), '', array(t('No'), t('Yes')), ' onchange=\'window.location.href="' . $forumsurl . '&active="+(this.checked ? 1 : 0)\''),
]);
return $o;
}
return $o;
}
/**
* @brief
*
* Given an update record, probe the channel, grab a zot-info packet and refresh/sync the data.
*
* Ignore updating records marked as deleted.
*
* If successful, sets ud_last in the DB to the current datetime for this
* reddress/webbie.
*
* @param array $ud Entry from update table
*/
/**
* @brief
*
* Given an update record, probe the channel, grab a zot-info packet and refresh/sync the data.
*
* Ignore updating records marked as deleted.
*
* If successful, sets ud_last in the DB to the current datetime for this
* reddress/webbie.
*
* @param array $ud Entry from update table
*/
static function update_directory_entry($ud) {
public static function update_directory_entry($ud)
{
logger('update_directory_entry: ' . print_r($ud,true), LOGGER_DATA);
logger('update_directory_entry: ' . print_r($ud, true), LOGGER_DATA);
if ($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) {
$success = false;
if ($ud['ud_addr'] && (!($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) {
$success = false;
$href = Webfinger::zot_url(punify($ud['ud_addr']));
if($href) {
$zf = Zotfinger::exec($href);
}
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
}
else {
q("update updates set ud_last = '%s' where ud_addr = '%s'",
dbesc(datetime_convert()),
dbesc($ud['ud_addr'])
);
}
}
}
$href = Webfinger::zot_url(punify($ud['ud_addr']));
if ($href) {
$zf = Zotfinger::exec($href);
}
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
} else {
q("update updates set ud_last = '%s' where ud_addr = '%s'",
dbesc(datetime_convert()),
dbesc($ud['ud_addr'])
);
}
}
}
/**
* @brief Push local channel updates to a local directory server.
*
* This is called from Zotlabs/Daemon/Directory.php if a profile is to be pushed to the
* directory and the local hub in this case is any kind of directory server.
*
* @param int $uid
* @param boolean $force
*/
/**
* @brief Push local channel updates to a local directory server.
*
* This is called from Zotlabs/Daemon/Directory.php if a profile is to be pushed to the
* directory and the local hub in this case is any kind of directory server.
*
* @param int $uid
* @param bool $force
*/
static function local_dir_update($uid, $force) {
public static function local_dir_update($uid, $force)
{
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
$p = q("select channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
intval($uid)
);
$p = q("select channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
intval($uid)
);
$profile = [];
$profile['encoding'] = 'zot';
$profile = [];
$profile['encoding'] = 'zot';
if ($p) {
$hash = $p[0]['channel_hash'];
if ($p) {
$hash = $p[0]['channel_hash'];
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
$profile['age'] = $age;
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if ($age = age($p[0]['dob'], $p[0]['channel_timezone'], ''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
$profile['sexual'] = $p[0]['sexual'];
$profile['locale'] = $p[0]['locality'];
$profile['region'] = $p[0]['region'];
$profile['postcode'] = $p[0]['postal_code'];
$profile['country'] = $p[0]['country_name'];
$profile['about'] = $p[0]['about'];
$profile['homepage'] = $p[0]['homepage'];
$profile['hometown'] = $p[0]['hometown'];
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
$profile['sexual'] = $p[0]['sexual'];
$profile['locale'] = $p[0]['locality'];
$profile['region'] = $p[0]['region'];
$profile['postcode'] = $p[0]['postal_code'];
$profile['country'] = $p[0]['country_name'];
$profile['about'] = $p[0]['about'];
$profile['homepage'] = $p[0]['homepage'];
$profile['hometown'] = $p[0]['hometown'];
if ($p[0]['keywords']) {
$tags = [];
$k = explode(' ', $p[0]['keywords']);
if ($k)
foreach ($k as $kk)
if (trim($kk))
$tags[] = trim($kk);
if ($p[0]['keywords']) {
$tags = [];
$k = explode(' ', $p[0]['keywords']);
if ($k)
foreach ($k as $kk)
if (trim($kk))
$tags[] = trim($kk);
if ($tags)
$profile['keywords'] = $tags;
}
if ($tags)
$profile['keywords'] = $tags;
}
$hidden = (1 - intval($p[0]['publish']));
$hidden = (1 - intval($p[0]['publish']));
// logger('hidden: ' . $hidden);
// logger('hidden: ' . $hidden);
$r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1",
dbesc($p[0]['channel_hash'])
);
$r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1",
dbesc($p[0]['channel_hash'])
);
if(intval($r[0]['xchan_hidden']) != $hidden) {
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
intval($hidden),
dbesc($p[0]['channel_hash'])
);
}
if (intval($r[0]['xchan_hidden']) != $hidden) {
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
intval($hidden),
dbesc($p[0]['channel_hash'])
);
}
$arr = [ 'channel_id' => $uid, 'hash' => $hash, 'profile' => $profile ];
call_hooks('local_dir_update', $arr);
$arr = ['channel_id' => $uid, 'hash' => $hash, 'profile' => $profile];
call_hooks('local_dir_update', $arr);
$address = channel_reddress($p[0]);
$address = channel_reddress($p[0]);
if (perm_is_allowed($uid, '', 'view_profile')) {
self::import_directory_profile($hash, $arr['profile'], $address, 0);
}
else {
// they may have made it private
$r = q("delete from xprof where xprof_hash = '%s'",
dbesc($hash)
);
$r = q("delete from xtag where xtag_hash = '%s'",
dbesc($hash)
);
}
if (perm_is_allowed($uid, '', 'view_profile')) {
self::import_directory_profile($hash, $arr['profile'], $address, 0);
} else {
// they may have made it private
$r = q("delete from xprof where xprof_hash = '%s'",
dbesc($hash)
);
$r = q("delete from xtag where xtag_hash = '%s'",
dbesc($hash)
);
}
}
}
$ud_hash = random_string() . '@' . App::get_hostname();
self::update_modtime($hash, $ud_hash, channel_reddress($p[0]),(($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
}
$ud_hash = random_string() . '@' . App::get_hostname();
self::update_modtime($hash, $ud_hash, channel_reddress($p[0]), (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
}
/**
* @brief Imports a directory profile.
*
* @param string $hash
* @param array $profile
* @param string $addr
* @param number $ud_flags (optional) UPDATE_FLAGS_UPDATED
* @param number $suppress_update (optional) default 0
* @return bool $updated if something changed
*/
/**
* @brief Imports a directory profile.
*
* @param string $hash
* @param array $profile
* @param string $addr
* @param number $ud_flags (optional) UPDATE_FLAGS_UPDATED
* @param number $suppress_update (optional) default 0
* @return boolean $updated if something changed
*/
public static function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0)
{
static function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0) {
logger('import_directory_profile', LOGGER_DEBUG);
if (! $hash)
return false;
logger('import_directory_profile', LOGGER_DEBUG);
if (!$hash)
return false;
$maxlen = get_max_import_size();
$maxlen = get_max_import_size();
if($maxlen && mb_strlen($profile['about']) > $maxlen) {
$profile['about'] = mb_substr($profile['about'],0,$maxlen,'UTF-8');
}
if ($maxlen && mb_strlen($profile['about']) > $maxlen) {
$profile['about'] = mb_substr($profile['about'], 0, $maxlen, 'UTF-8');
}
$arr = [];
$arr = [];
$arr['xprof_hash'] = $hash;
$arr['xprof_dob'] = ((isset($profile['birthday']) && $profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('','',$profile['birthday'],'Y-m-d')); // !!!! check this for 0000 year
$arr['xprof_age'] = (isset($profile['age']) ? intval($profile['age']) : 0);
$arr['xprof_desc'] = ((isset($profile['description']) && $profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_gender'] = ((isset($profile['gender']) && $profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_marital'] = ((isset($profile['marital']) && $profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_sexual'] = ((isset($profile['sexual']) && $profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_locale'] = ((isset($profile['locale']) && $profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_region'] = ((isset($profile['region']) && $profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_postcode'] = ((isset($profile['postcode']) && $profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_country'] = ((isset($profile['country']) && $profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_about'] = ((isset($profile['about']) && $profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_pronouns'] = ((isset($profile['pronouns']) && $profile['pronouns']) ? htmlspecialchars($profile['pronouns'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_homepage'] = ((isset($profile['homepage']) && $profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_hometown'] = ((isset($profile['hometown']) && $profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_hash'] = $hash;
$arr['xprof_dob'] = ((isset($profile['birthday']) && $profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('', '', $profile['birthday'], 'Y-m-d')); // !!!! check this for 0000 year
$arr['xprof_age'] = (isset($profile['age']) ? intval($profile['age']) : 0);
$arr['xprof_desc'] = ((isset($profile['description']) && $profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_gender'] = ((isset($profile['gender']) && $profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_marital'] = ((isset($profile['marital']) && $profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_sexual'] = ((isset($profile['sexual']) && $profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_locale'] = ((isset($profile['locale']) && $profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_region'] = ((isset($profile['region']) && $profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_postcode'] = ((isset($profile['postcode']) && $profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_country'] = ((isset($profile['country']) && $profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_about'] = ((isset($profile['about']) && $profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_pronouns'] = ((isset($profile['pronouns']) && $profile['pronouns']) ? htmlspecialchars($profile['pronouns'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_homepage'] = ((isset($profile['homepage']) && $profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_hometown'] = ((isset($profile['hometown']) && $profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT, 'UTF-8', false) : '');
$clean = [];
if (array_key_exists('keywords', $profile) and is_array($profile['keywords'])) {
self::import_directory_keywords($hash,$profile['keywords']);
foreach ($profile['keywords'] as $kw) {
$kw = trim(htmlspecialchars($kw,ENT_COMPAT, 'UTF-8', false));
$kw = trim($kw, ',');
$clean[] = $kw;
}
}
$clean = [];
if (array_key_exists('keywords', $profile) and is_array($profile['keywords'])) {
self::import_directory_keywords($hash, $profile['keywords']);
foreach ($profile['keywords'] as $kw) {
$kw = trim(htmlspecialchars($kw, ENT_COMPAT, 'UTF-8', false));
$kw = trim($kw, ',');
$clean[] = $kw;
}
}
$arr['xprof_keywords'] = implode(' ',$clean);
$arr['xprof_keywords'] = implode(' ', $clean);
// Self censored, make it so
// These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult".
// Self censored, make it so
// These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult".
if(in_arrayi('nsfw',$clean) || in_arrayi('adult',$clean)) {
q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'",
dbesc($hash)
);
}
if (in_arrayi('nsfw', $clean) || in_arrayi('adult', $clean)) {
q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'",
dbesc($hash)
);
}
$r = q("select * from xprof where xprof_hash = '%s' limit 1",
dbesc($hash)
);
$r = q("select * from xprof where xprof_hash = '%s' limit 1",
dbesc($hash)
);
if ($arr['xprof_age'] > 150)
$arr['xprof_age'] = 150;
if ($arr['xprof_age'] < 0)
$arr['xprof_age'] = 0;
if ($arr['xprof_age'] > 150)
$arr['xprof_age'] = 150;
if ($arr['xprof_age'] < 0)
$arr['xprof_age'] = 0;
if ($r) {
$update = false;
foreach ($r[0] as $k => $v) {
if ((array_key_exists($k,$arr)) && ($arr[$k] != $v)) {
logger('import_directory_profile: update ' . $k . ' => ' . $arr[$k]);
$update = true;
break;
}
}
if ($update) {
q("update xprof set
if ($r) {
$update = false;
foreach ($r[0] as $k => $v) {
if ((array_key_exists($k, $arr)) && ($arr[$k] != $v)) {
logger('import_directory_profile: update ' . $k . ' => ' . $arr[$k]);
$update = true;
break;
}
}
if ($update) {
q("update xprof set
xprof_desc = '%s',
xprof_dob = '%s',
xprof_age = %d,
@ -352,156 +356,153 @@ class Libzotdir {
xprof_keywords = '%s',
xprof_pronouns = '%s'
where xprof_hash = '%s'",
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),
dbesc($arr['xprof_locale']),
dbesc($arr['xprof_region']),
dbesc($arr['xprof_postcode']),
dbesc($arr['xprof_country']),
dbesc($arr['xprof_about']),
dbesc($arr['xprof_homepage']),
dbesc($arr['xprof_hometown']),
dbesc($arr['xprof_keywords']),
dbesc($arr['xprof_pronouns']),
dbesc($arr['xprof_hash'])
);
}
} else {
$update = true;
logger('New profile');
q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_about, xprof_homepage, xprof_hometown, xprof_keywords, xprof_pronouns) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($arr['xprof_hash']),
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),
dbesc($arr['xprof_locale']),
dbesc($arr['xprof_region']),
dbesc($arr['xprof_postcode']),
dbesc($arr['xprof_country']),
dbesc($arr['xprof_about']),
dbesc($arr['xprof_homepage']),
dbesc($arr['xprof_hometown']),
dbesc($arr['xprof_keywords']),
dbesc($arr['xprof_pronouns'])
);
}
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),
dbesc($arr['xprof_locale']),
dbesc($arr['xprof_region']),
dbesc($arr['xprof_postcode']),
dbesc($arr['xprof_country']),
dbesc($arr['xprof_about']),
dbesc($arr['xprof_homepage']),
dbesc($arr['xprof_hometown']),
dbesc($arr['xprof_keywords']),
dbesc($arr['xprof_pronouns']),
dbesc($arr['xprof_hash'])
);
}
} else {
$update = true;
logger('New profile');
q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_about, xprof_homepage, xprof_hometown, xprof_keywords, xprof_pronouns) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($arr['xprof_hash']),
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),
dbesc($arr['xprof_locale']),
dbesc($arr['xprof_region']),
dbesc($arr['xprof_postcode']),
dbesc($arr['xprof_country']),
dbesc($arr['xprof_about']),
dbesc($arr['xprof_homepage']),
dbesc($arr['xprof_hometown']),
dbesc($arr['xprof_keywords']),
dbesc($arr['xprof_pronouns'])
);
}
$d = [
'xprof' => $arr,
'profile' => $profile,
'update' => $update
];
$d = [
'xprof' => $arr,
'profile' => $profile,
'update' => $update
];
/**
* @hooks import_directory_profile
* Called when processing delivery of a profile structure from an external source (usually for directory storage).
* * \e array \b xprof
* * \e array \b profile
* * \e boolean \b update
*/
/**
* @hooks import_directory_profile
* Called when processing delivery of a profile structure from an external source (usually for directory storage).
* * \e array \b xprof
* * \e array \b profile
* * \e boolean \b update
*/
call_hooks('import_directory_profile', $d);
call_hooks('import_directory_profile', $d);
if (($d['update']) && (! $suppress_update)) {
self::update_modtime($arr['xprof_hash'], new_uuid(), $addr, $ud_flags);
}
if (($d['update']) && (!$suppress_update)) {
self::update_modtime($arr['xprof_hash'], new_uuid(), $addr, $ud_flags);
}
q("update xchan set xchan_updated = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($arr['xprof_hash'])
);
q("update xchan set xchan_updated = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($arr['xprof_hash'])
);
return $d['update'];
}
return $d['update'];
}
/**
* @brief
*
* @param string $hash An xtag_hash
* @param array $keywords
*/
/**
* @brief
*
* @param string $hash An xtag_hash
* @param array $keywords
*/
static function import_directory_keywords($hash, $keywords) {
public static function import_directory_keywords($hash, $keywords)
{
$existing = [];
$r = q("select * from xtag where xtag_hash = '%s' and xtag_flags = 0",
dbesc($hash)
);
$existing = [];
$r = q("select * from xtag where xtag_hash = '%s' and xtag_flags = 0",
dbesc($hash)
);
if($r) {
foreach($r as $rr)
$existing[] = $rr['xtag_term'];
}
if ($r) {
foreach ($r as $rr)
$existing[] = $rr['xtag_term'];
}
$clean = [];
foreach($keywords as $kw) {
$kw = trim(htmlspecialchars($kw,ENT_COMPAT, 'UTF-8', false));
$kw = trim($kw, ',');
$clean[] = $kw;
}
$clean = [];
foreach ($keywords as $kw) {
$kw = trim(htmlspecialchars($kw, ENT_COMPAT, 'UTF-8', false));
$kw = trim($kw, ',');
$clean[] = $kw;
}
foreach($existing as $x) {
if(! in_array($x, $clean))
$r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0",
dbesc($hash),
dbesc($x)
);
}
foreach($clean as $x) {
if(! in_array($x, $existing)) {
$r = q("insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )",
dbesc($hash),
dbesc($x)
);
}
}
}
foreach ($existing as $x) {
if (!in_array($x, $clean))
$r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0",
dbesc($hash),
dbesc($x)
);
}
foreach ($clean as $x) {
if (!in_array($x, $existing)) {
$r = q("insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )",
dbesc($hash),
dbesc($x)
);
}
}
}
/**
* @brief
*
* @param string $hash
* @param string $guid
* @param string $addr
* @param int $flags (optional) default 0
*/
static function update_modtime($hash, $guid, $addr, $flags = 0) {
$dirmode = intval(get_config('system', 'directory_mode'));
if($dirmode == DIRECTORY_MODE_NORMAL)
return;
if($flags) {
q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )",
dbesc($hash),
dbesc($guid),
dbesc(datetime_convert()),
intval($flags),
dbesc($addr)
);
}
else {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and (ud_flags & %d) = 0 ",
intval(UPDATE_FLAGS_UPDATED),
dbesc($addr),
intval(UPDATE_FLAGS_UPDATED)
);
}
}
/**
* @brief
*
* @param string $hash
* @param string $guid
* @param string $addr
* @param int $flags (optional) default 0
*/
public static function update_modtime($hash, $guid, $addr, $flags = 0)
{
$dirmode = intval(get_config('system', 'directory_mode'));
if ($dirmode == DIRECTORY_MODE_NORMAL)
return;
if ($flags) {
q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )",
dbesc($hash),
dbesc($guid),
dbesc(datetime_convert()),
intval($flags),
dbesc($addr)
);
} else {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and (ud_flags & %d) = 0 ",
intval(UPDATE_FLAGS_UPDATED),
dbesc($addr),
intval(UPDATE_FLAGS_UPDATED)
);
}
}
}

View file

@ -18,308 +18,314 @@ require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
class Markdown {
/**
* @brief Convert Markdown to bbcode.
*
* We don't want to support a bbcode specific markdown interpreter
* and the markdown library we have is pretty good, but provides HTML output.
* So we'll use that to convert to HTML, then convert the HTML back to bbcode,
* and then clean up a few Diaspora specific constructs.
*
* @param string $s The message as Markdown
* @param boolean $use_zrl default false
* @param array $options default empty
* @return string The message converted to bbcode
*/
static public function to_bbcode($s, $use_zrl = false, $options = []) {
if(is_array($s)) {
btlogger('markdown_to_bb called with array. ' . print_r($s, true), LOGGER_NORMAL, LOG_WARNING);
return '';
}
$s = str_replace("&#xD;","\r",$s);
$s = str_replace("&#xD;\n&gt;","",$s);
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
// if empty link text replace with the url
$s = preg_replace("/\[\]\((.*?)\)/ism",'[$1]($1)',$s);
$x = [
'text' => $s,
'zrl' => $use_zrl,
'options' => $options
];
/**
* @hooks markdown_to_bb_init
* * \e string \b text - The message as Markdown and what will get returned
* * \e boolean \b zrl
* * \e array \b options
*/
call_hooks('markdown_to_bb_init', $x);
$s = $x['text'];
// Escaping the hash tags
$s = preg_replace('/\#([^\s\#])/','&#35;$1',$s);
$s = MarkdownExtra::defaultTransform($s);
if($options && $options['preserve_lf']) {
$s = str_replace(["\r","\n"],["",'<br>'],$s);
}
else {
$s = str_replace("\r","",$s);
}
$s = str_replace('&#35;','#',$s);
$s = html2bbcode($s);
// Convert everything that looks like a link to a link
if($use_zrl) {
if (strpos($s,'[/img]') !== false) {
$s = preg_replace_callback("/\[img\](.*?)\[\/img\]/ism", [ '\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_img'], $s);
$s = preg_replace_callback("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", [ '\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_img_x' ], $s);
}
$s = preg_replace_callback("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", [ '\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_link'] ,$s);
}
else {
$s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s);
}
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s);
/**
* @hooks markdown_to_bb
* * \e string - The already converted message as bbcode
*/
call_hooks('markdown_to_bb', $s);
return $s;
}
static function use_zrl_cb_link($match) {
$res = '';
$is_zid = is_matrix_url(trim($match[0]));
if($is_zid)
$res = $match[1] . '[zrl=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/zrl]';
else
$res = $match[1] . '[url=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/url]';
return $res;
}
static function use_zrl_cb_img($match) {
$res = '';
$is_zid = is_matrix_url(trim($match[1]));
if($is_zid)
$res = '[zmg]' . $match[1] . '[/zmg]';
else
$res = $match[0];
return $res;
}
class Markdown
{
/**
* @brief Convert Markdown to bbcode.
*
* We don't want to support a bbcode specific markdown interpreter
* and the markdown library we have is pretty good, but provides HTML output.
* So we'll use that to convert to HTML, then convert the HTML back to bbcode,
* and then clean up a few Diaspora specific constructs.
*
* @param string $s The message as Markdown
* @param bool $use_zrl default false
* @param array $options default empty
* @return string The message converted to bbcode
*/
public static function to_bbcode($s, $use_zrl = false, $options = [])
{
if (is_array($s)) {
btlogger('markdown_to_bb called with array. ' . print_r($s, true), LOGGER_NORMAL, LOG_WARNING);
return '';
}
$s = str_replace("&#xD;", "\r", $s);
$s = str_replace("&#xD;\n&gt;", "", $s);
$s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
// if empty link text replace with the url
$s = preg_replace("/\[\]\((.*?)\)/ism", '[$1]($1)', $s);
$x = [
'text' => $s,
'zrl' => $use_zrl,
'options' => $options
];
/**
* @hooks markdown_to_bb_init
* * \e string \b text - The message as Markdown and what will get returned
* * \e boolean \b zrl
* * \e array \b options
*/
call_hooks('markdown_to_bb_init', $x);
$s = $x['text'];
// Escaping the hash tags
$s = preg_replace('/\#([^\s\#])/', '&#35;$1', $s);
$s = MarkdownExtra::defaultTransform($s);
if ($options && $options['preserve_lf']) {
$s = str_replace(["\r", "\n"], ["", '<br>'], $s);
} else {
$s = str_replace("\r", "", $s);
}
$s = str_replace('&#35;', '#', $s);
$s = html2bbcode($s);
// Convert everything that looks like a link to a link
if ($use_zrl) {
if (strpos($s, '[/img]') !== false) {
$s = preg_replace_callback("/\[img\](.*?)\[\/img\]/ism", ['\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_img'], $s);
$s = preg_replace_callback("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", ['\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_img_x'], $s);
}
$s = preg_replace_callback("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", ['\\Zotlabs\\Lib\\Markdown', 'use_zrl_cb_link'], $s);
} else {
$s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]', $s);
}
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism", "[code]$2[/code]", $s);
/**
* @hooks markdown_to_bb
* * \e string - The already converted message as bbcode
*/
call_hooks('markdown_to_bb', $s);
return $s;
}
public static function use_zrl_cb_link($match)
{
$res = '';
$is_zid = is_matrix_url(trim($match[0]));
if ($is_zid)
$res = $match[1] . '[zrl=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/zrl]';
else
$res = $match[1] . '[url=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/url]';
return $res;
}
public static function use_zrl_cb_img($match)
{
$res = '';
$is_zid = is_matrix_url(trim($match[1]));
if ($is_zid)
$res = '[zmg]' . $match[1] . '[/zmg]';
else
$res = $match[0];
return $res;
}
public static function use_zrl_cb_img_x($match)
{
$res = '';
$is_zid = is_matrix_url(trim($match[3]));
static function use_zrl_cb_img_x($match) {
$res = '';
$is_zid = is_matrix_url(trim($match[3]));
if ($is_zid)
$res = '[zmg=' . $match[1] . 'x' . $match[2] . ']' . $match[3] . '[/zmg]';
else
$res = $match[0];
if($is_zid)
$res = '[zmg=' . $match[1] . 'x' . $match[2] . ']' . $match[3] . '[/zmg]';
else
$res = $match[0];
return $res;
}
return $res;
}
/**
* @brief
*
* @param array $match
* @return string
*/
/**
* @brief
*
* @param array $match
* @return string
*/
public static function from_bbcode_share($match)
{
static public function from_bbcode_share($match) {
$matches = [];
$attributes = $match[1];
$matches = [];
$attributes = $match[1];
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = urldecode($matches[1]);
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = urldecode($matches[1]);
$link = "";
preg_match("/link='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
$link = "";
preg_match("/link='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$posted = "";
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
$posted = "";
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
// message_id is never used, do we still need it?
$message_id = "";
preg_match("/message_id='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$message_id = $matches[1];
// message_id is never used, do we still need it?
$message_id = "";
preg_match("/message_id='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$message_id = $matches[1];
if (!$message_id) {
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$message_id = $matches[1];
}
if(! $message_id) {
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$message_id = $matches[1];
}
$reldate = datetime_convert('UTC', date_default_timezone_get(), $posted, 'r');
$reldate = datetime_convert('UTC', date_default_timezone_get(), $posted, 'r');
$headline = '';
$headline = '';
if ($avatar != "")
$headline .= '[url=' . zid($profile) . '][img]' . $avatar . '[/img][/url]';
if ($avatar != "")
$headline .= '[url=' . zid($profile) . '][img]' . $avatar . '[/img][/url]';
// Bob Smith wrote the following post 2 hours ago
// Bob Smith wrote the following post 2 hours ago
$fmt = sprintf(t('%1$s wrote the following %2$s %3$s'),
'[url=' . zid($profile) . ']' . $author . '[/url]',
'[url=' . zid($link) . ']' . t('post') . '[/url]',
$reldate
);
$fmt = sprintf( t('%1$s wrote the following %2$s %3$s'),
'[url=' . zid($profile) . ']' . $author . '[/url]',
'[url=' . zid($link) . ']' . t('post') . '[/url]',
$reldate
);
$headline .= $fmt . "\n\n";
$headline .= $fmt . "\n\n";
$text = $headline . trim($match[2]);
$text = $headline . trim($match[2]);
return $text;
}
return $text;
}
/**
* @brief Convert bbcode to Markdown.
*
* @param string $Text The message as bbcode
* @param array $options default empty
* @return string The message converted to Markdown
*/
/**
* @brief Convert bbcode to Markdown.
*
* @param string $Text The message as bbcode
* @param array $options default empty
* @return string The message converted to Markdown
*/
public static function from_bbcode($Text, $options = [])
{
static public function from_bbcode($Text, $options = []) {
/*
* Transform #tags, strip off the [url] and replace spaces with underscore
*/
/*
* Transform #tags, strip off the [url] and replace spaces with underscore
*/
$Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i',
create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $Text);
$Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i',
create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $Text);
$Text = preg_replace('/#\^\[([zu])rl\=(.*?)\](.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
$Text = preg_replace('/#\^\[([zu])rl\=(.*?)\](.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", ['\\Zotlabs\\Lib\\Markdown', 'from_bbcode_share'], $Text);
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", [ '\\Zotlabs\\Lib\\Markdown', 'from_bbcode_share'], $Text);
$x = ['bbcode' => $Text, 'options' => $options];
$x = [ 'bbcode' => $Text, 'options' => $options ];
/**
* @hooks bb_to_markdown_bb
* * \e string \b bbcode - The message as bbcode and what will get returned
* * \e array \b options
*/
call_hooks('bb_to_markdown_bb', $x);
/**
* @hooks bb_to_markdown_bb
* * \e string \b bbcode - The message as bbcode and what will get returned
* * \e array \b options
*/
call_hooks('bb_to_markdown_bb', $x);
$Text = $x['bbcode'];
$Text = $x['bbcode'];
// Convert it to HTML - don't try oembed
$Text = bbcode($Text, ['tryoembed' => false]);
// Convert it to HTML - don't try oembed
$Text = bbcode($Text, [ 'tryoembed' => false ]);
// Now convert HTML to Markdown
// Now convert HTML to Markdown
$Text = self::from_html($Text);
$Text = self::from_html($Text);
//html2markdown adds backslashes infront of hashes after a new line. remove them
$Text = str_replace("\n\#", "\n#", $Text);
//html2markdown adds backslashes infront of hashes after a new line. remove them
$Text = str_replace("\n\#", "\n#", $Text);
// If the text going into bbcode() has a plain URL in it, i.e.
// with no [url] tags around it, it will come out of parseString()
// looking like: <http://url.com>, which gets removed by strip_tags().
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
// If the text going into bbcode() has a plain URL in it, i.e.
// with no [url] tags around it, it will come out of parseString()
// looking like: <http://url.com>, which gets removed by strip_tags().
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
// Remove empty zrl links
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
// Remove empty zrl links
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
$Text = trim($Text);
$Text = trim($Text);
/**
* @hooks bb_to_markdown
* * \e string - The already converted message as bbcode and what will get returned
*/
call_hooks('bb_to_markdown', $Text);
/**
* @hooks bb_to_markdown
* * \e string - The already converted message as bbcode and what will get returned
*/
call_hooks('bb_to_markdown', $Text);
return $Text;
}
return $Text;
}
/**
* @brief Convert a HTML text into Markdown.
*
* This function uses the library league/html-to-markdown for this task.
*
* If the HTML text can not get parsed it will return an empty string.
*
* @param string $html The HTML code to convert
* @return string Markdown representation of the given HTML text, empty on error
*/
/**
* @brief Convert a HTML text into Markdown.
*
* This function uses the library league/html-to-markdown for this task.
*
* If the HTML text can not get parsed it will return an empty string.
*
* @param string $html The HTML code to convert
* @return string Markdown representation of the given HTML text, empty on error
*/
public static function from_html($html, $options = [])
{
$markdown = '';
static public function from_html($html,$options = []) {
$markdown = '';
if (!$options) {
$options = [
'header_style' => 'setext', // Set to 'atx' to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // DEPRECATED: Set to '__' if you prefer the underlined style
'italic_style' => '*', // DEPRECATED: Set to '_' if you prefer the underlined style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: 'meta style script'
'hard_break' => false, // Set to true to turn <br> into `\n` instead of ` \n`
'list_item_style' => '-', // Set the default character for each <li> in a <ul>. Can be '-', '*', or '+'
];
}
if(! $options) {
$options = [
'header_style' => 'setext', // Set to 'atx' to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // DEPRECATED: Set to '__' if you prefer the underlined style
'italic_style' => '*', // DEPRECATED: Set to '_' if you prefer the underlined style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: 'meta style script'
'hard_break' => false, // Set to true to turn <br> into `\n` instead of ` \n`
'list_item_style' => '-', // Set the default character for each <li> in a <ul>. Can be '-', '*', or '+'
];
}
$environment = Environment::createDefaultEnvironment($options);
$environment->addConverter(new TableConverter());
$converter = new HtmlConverter($environment);
$environment = Environment::createDefaultEnvironment($options);
$environment->addConverter(new TableConverter());
$converter = new HtmlConverter($environment);
try {
$markdown = $converter->convert($html);
} catch (InvalidArgumentException $e) {
logger("Invalid HTML. HTMLToMarkdown library threw an exception.");
}
try {
$markdown = $converter->convert($html);
} catch (InvalidArgumentException $e) {
logger("Invalid HTML. HTMLToMarkdown library threw an exception.");
}
return $markdown;
}
return $markdown;
}
}
// Tables are not an official part of the markdown specification.

View file

@ -22,111 +22,123 @@ namespace Zotlabs\Lib;
* $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
* @endcode
*/
class MarkdownSoap {
class MarkdownSoap
{
/**
* @var string
*/
private $str;
/**
* @var string
*/
private $token;
/**
* @var string
*/
private $str;
/**
* @var string
*/
private $token;
function __construct($s) {
$this->str = $s;
$this->token = random_string(20);
}
public function __construct($s)
{
$this->str = $s;
$this->token = random_string(20);
}
function clean() {
public function clean()
{
$x = $this->extract_code($this->str);
$x = $this->extract_code($this->str);
$x = $this->purify($x);
$x = $this->purify($x);
$x = $this->putback_code($x);
$x = $this->putback_code($x);
$x = $this->escape($x);
$x = $this->escape($x);
return $x;
}
return $x;
}
/**
* @brief Extracts code blocks and privately escapes them from processing.
*
* @see encode_code()
* @see putback_code()
*
* @param string $s
* @return string
*/
function extract_code($s) {
/**
* @brief Extracts code blocks and privately escapes them from processing.
*
* @param string $s
* @return string
* @see encode_code()
* @see putback_code()
*
*/
public function extract_code($s)
{
$text = preg_replace_callback('{
$text = preg_replace_callback('{
(?:\n\n|\A\n?)
( # $1 = the code block -- one or more lines, starting with a space/tab
(?>
[ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
[ ]{' . '4' . '} # Lines must start with a tab or a tab-width of spaces
.*\n+
)+
)
((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
((?=^[ ]{0,' . '4' . '}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
}xm',
[ $this , 'encode_code' ], $s);
[$this, 'encode_code'], $s);
return $text;
}
return $text;
}
function encode_code($matches) {
return $this->token . ';' . base64_encode($matches[0]) . ';' ;
}
public function encode_code($matches)
{
return $this->token . ';' . base64_encode($matches[0]) . ';';
}
function decode_code($matches) {
return base64_decode($matches[1]);
}
public function decode_code($matches)
{
return base64_decode($matches[1]);
}
/**
* @brief Put back the code blocks.
*
* @see extract_code()
* @see decode_code()
*
* @param string $s
* @return string
*/
function putback_code($s) {
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm', [ $this, 'decode_code' ], $s);
return $text;
}
/**
* @brief Put back the code blocks.
*
* @param string $s
* @return string
* @see extract_code()
* @see decode_code()
*
*/
public function putback_code($s)
{
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm', [$this, 'decode_code'], $s);
return $text;
}
function purify($s) {
$s = $this->protect_autolinks($s);
$s = purify_html($s);
$s = $this->unprotect_autolinks($s);
return $s;
}
public function purify($s)
{
$s = $this->protect_autolinks($s);
$s = purify_html($s);
$s = $this->unprotect_autolinks($s);
return $s;
}
function protect_autolinks($s) {
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/', '[$1$2]($1$2)', $s);
return $s;
}
public function protect_autolinks($s)
{
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/', '[$1$2]($1$2)', $s);
return $s;
}
function unprotect_autolinks($s) {
return $s;
}
public function unprotect_autolinks($s)
{
return $s;
}
function escape($s) {
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
}
public function escape($s)
{
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
}
/**
* @brief Converts special HTML entities back to characters.
*
* @param string $s
* @return string
*/
static public function unescape($s) {
return htmlspecialchars_decode($s, ENT_QUOTES);
}
/**
* @brief Converts special HTML entities back to characters.
*
* @param string $s
* @return string
*/
public static function unescape($s)
{
return htmlspecialchars_decode($s, ENT_QUOTES);
}
}

View file

@ -6,16 +6,18 @@ use App;
use Zotlabs\Lib\PConfig;
class MastAPI {
class MastAPI
{
static function format_channel($channel) {
$p = q("select * from profile where uid = %d and is_default = 1",
intval($channel['channel_id'])
);
public static function format_channel($channel)
{
$p = q("select * from profile where uid = %d and is_default = 1",
intval($channel['channel_id'])
);
$a = q("select * from account where account_id = %d",
intval($channel['channel_account_id'])
);
$a = q("select * from account where account_id = %d",
intval($channel['channel_account_id'])
);
$followers = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'their_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0 ",
intval($channel['channel_id']),
@ -23,13 +25,13 @@ class MastAPI {
dbesc($channel['channel_hash'])
);
$following = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'my_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0",
intval($channel['channel_id']),
intval($channel['channel_id']),
dbesc($channel['channel_hash'])
);
$following = q("select count(xchan_hash) as total from xchan left join abconfig on abconfig.xchan = xchan_hash left join abook on abook_xchan = xchan_hash where abook_channel = %d and abconfig.chan = %d and abconfig.cat = 'system' and abconfig.k = 'my_perms' and abconfig.v like '%%send_stream%%' and xchan_hash != '%s' and xchan_orphan = 0 and xchan_deleted = 0 and abook_hidden = 0 and abook_pending = 0 and abook_self = 0",
intval($channel['channel_id']),
intval($channel['channel_id']),
dbesc($channel['channel_hash'])
);
$cover_photo = get_cover_photo($channel['channel_id'],'array');
$cover_photo = get_cover_photo($channel['channel_id'], 'array');
$item_normal = item_normal();
@ -38,66 +40,67 @@ class MastAPI {
WHERE uid = %d
AND author_xchan = '%s' $item_normal ",
intval($channel['channel_id']),
dbesc($channel['channel_hash'])
dbesc($channel['channel_hash'])
);
$ret = [];
$ret['id'] = (string) $channel['channel_id'];
$ret['username'] = $channel['channel_address'];
$ret['acct'] = $channel['channel_address'];
$ret['display_name'] = $channel['channel_name'];
$ret['locked'] = ((intval(PConfig::Get($channel['channel_id'],'system','autoperms'))) ? false : true );
$ret['discoverable'] = ((1 - intval($channel['xchan_hidden'])) ? true : false);
$ret['created_at'] = datetime_convert('UTC','UTC', $a[0]['account_created'], ATOM_TIME);
$ret['note'] = bbcode($p[0]['about'], [ 'export' => true ]);
$ret['url'] = channel_url($channel);
$ret['avatar'] = $channel['xchan_photo_l'];
$ret['avatar_static'] = $channel['xchan_photo_l'];
if ($cover_photo) {
$ret['header'] = $cover_photo['url'];
$ret['header_static'] = $cover_photo['url'];
}
$ret['followers_count'] = intval($followers[0]['total']);
$ret['following_count'] = intval($following[0]['total']);
$ret['statuses_count'] = intval($statuses[0]['total']);
$ret['last_status_at'] = datetime_convert('UTC','UTC', $channel['lastpost'], ATOM_TIME);
$ret = [];
$ret['id'] = (string)$channel['channel_id'];
$ret['username'] = $channel['channel_address'];
$ret['acct'] = $channel['channel_address'];
$ret['display_name'] = $channel['channel_name'];
$ret['locked'] = ((intval(PConfig::Get($channel['channel_id'], 'system', 'autoperms'))) ? false : true);
$ret['discoverable'] = ((1 - intval($channel['xchan_hidden'])) ? true : false);
$ret['created_at'] = datetime_convert('UTC', 'UTC', $a[0]['account_created'], ATOM_TIME);
$ret['note'] = bbcode($p[0]['about'], ['export' => true]);
$ret['url'] = channel_url($channel);
$ret['avatar'] = $channel['xchan_photo_l'];
$ret['avatar_static'] = $channel['xchan_photo_l'];
if ($cover_photo) {
$ret['header'] = $cover_photo['url'];
$ret['header_static'] = $cover_photo['url'];
}
$ret['followers_count'] = intval($followers[0]['total']);
$ret['following_count'] = intval($following[0]['total']);
$ret['statuses_count'] = intval($statuses[0]['total']);
$ret['last_status_at'] = datetime_convert('UTC', 'UTC', $channel['lastpost'], ATOM_TIME);
return $ret;
}
return $ret;
}
static function format_site() {
public static function format_site()
{
$register = intval(get_config('system','register_policy'));
$register = intval(get_config('system', 'register_policy'));
$u = q("select count(channel_id) as total from channel where channel_removed = 0");
$i = q("select count(id) as total from item where item_origin = 1");
$s = q("select count(site_url) as total from site");
$u = q("select count(channel_id) as total from channel where channel_removed = 0");
$i = q("select count(id) as total from item where item_origin = 1");
$s = q("select count(site_url) as total from site");
$admins = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 ) > 0 and account_default_channel = channel_id");
$adminsx = channelx_by_n($admins[0]['channel_id']);
$admins = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 ) > 0 and account_default_channel = channel_id");
$adminsx = channelx_by_n($admins[0]['channel_id']);
$ret = [];
$ret['uri'] = z_root();
$ret['title'] = System::get_site_name();
$ret['description'] = bbcode(get_config('system','siteinfo',''), [ 'export' => true ] );
$ret['email'] = get_config('system','admin_email');
$ret['version'] = System::get_project_version();
$ret['registrations'] = (($register) ? true : false);
$ret['approval_required'] = (($register === REGISTER_APPROVE) ? true : false);
$ret['invites_enabled'] = false;
$ret['urls'] = [];
$ret['stats'] = [
'user_count' => intval($u[0]['total']),
'status_count' => intval($i[0]['total']),
'domain_count' => intval($s[0]['total']),
];
$ret = [];
$ret['uri'] = z_root();
$ret['title'] = System::get_site_name();
$ret['description'] = bbcode(get_config('system', 'siteinfo', ''), ['export' => true]);
$ret['email'] = get_config('system', 'admin_email');
$ret['version'] = System::get_project_version();
$ret['registrations'] = (($register) ? true : false);
$ret['approval_required'] = (($register === REGISTER_APPROVE) ? true : false);
$ret['invites_enabled'] = false;
$ret['urls'] = [];
$ret['stats'] = [
'user_count' => intval($u[0]['total']),
'status_count' => intval($i[0]['total']),
'domain_count' => intval($s[0]['total']),
];
$ret['contact_account'] = self::format_channel($adminsx);
$ret['contact_account'] = self::format_channel($adminsx);
return $ret;
return $ret;
}
}
}

View file

@ -7,7 +7,7 @@ namespace Zotlabs\Lib;
class MessageFilter {
static public function evaluate($item,$incl,$excl) {
public static function evaluate($item, $incl, $excl) {
require_once('include/html2plain.php');

View file

@ -6,7 +6,7 @@ namespace Zotlabs\Lib;
class Nodeinfo {
static public function fetch($url) {
public static function fetch($url) {
$href = EMPTY_STR;
$m = parse_url($url);
if ($m['scheme'] && $m['host']) {

View file

@ -30,7 +30,7 @@ class PConfig {
* The channel_id
* @return void|false Nothing or false if $uid is null or false
*/
static public function Load($uid) {
public static function Load($uid) {
if(is_null($uid) || $uid === false)
return false;
@ -82,7 +82,7 @@ class PConfig {
* Default value to return if key does not exist
* @return mixed Stored value or false if it does not exist
*/
static public function Get($uid, $family, $key, $default = false) {
public static function Get($uid, $family, $key, $default = false) {
if(is_null($uid) || $uid === false)
return $default;
@ -112,7 +112,7 @@ class PConfig {
* The value to store
* @return mixed Stored $value or false
*/
static public function Set($uid, $family, $key, $value) {
public static 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)
@ -185,7 +185,7 @@ class PConfig {
* The configuration key to delete
* @return mixed
*/
static public function Delete($uid, $family, $key) {
public static function Delete($uid, $family, $key) {
if(is_null($uid) || $uid === false)
return false;

View file

@ -157,7 +157,7 @@ class Permcat {
return $permcats;
}
static public function find_permcat($arr, $name) {
public static function find_permcat($arr, $name) {
if((! $arr) || (! $name))
return false;
@ -166,11 +166,11 @@ class Permcat {
return $p['value'];
}
static public function update($channel_id, $name, $permarr) {
public static function update($channel_id, $name, $permarr) {
PConfig::Set($channel_id, 'permcat', $name, $permarr);
}
static public function delete($channel_id, $name) {
public static function delete($channel_id, $name) {
PConfig::Delete($channel_id, 'permcat', $name);
}

View file

@ -55,7 +55,7 @@ class PermissionDescription {
* default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC,
* PERMS_NETWORK etc.
*
* @param integer $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc.
* @param int $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc.
* @return a new instance of PermissionDescription
*/
public static function fromStandalonePermission($perm) {

View file

@ -9,485 +9,480 @@ use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Zot6\Receiver;
use Zotlabs\Zot6\Zot6Handler;
class Queue {
class Queue
{
static function update($id, $add_priority = 0) {
public static function update($id, $add_priority = 0)
{
logger('queue: requeue item ' . $id,LOGGER_DEBUG);
logger('queue: requeue item ' . $id, LOGGER_DEBUG);
// This queue item failed. Perhaps it was rejected. Perhaps the site is dead.
// Since we don't really know, check and see if we've got something else destined
// for that server and give it priority. At a minimum it will keep the queue from
// getting stuck on a particular message when another one with different content
// might actually succeed.
// This queue item failed. Perhaps it was rejected. Perhaps the site is dead.
// Since we don't really know, check and see if we've got something else destined
// for that server and give it priority. At a minimum it will keep the queue from
// getting stuck on a particular message when another one with different content
// might actually succeed.
$x = q("select outq_created, outq_hash, outq_posturl from outq where outq_hash = '%s' limit 1",
dbesc($id)
);
if (! $x) {
return;
}
$x = q("select outq_created, outq_hash, outq_posturl from outq where outq_hash = '%s' limit 1",
dbesc($id)
);
if (!$x) {
return;
}
$g = q("select outq_created, outq_hash, outq_posturl from outq where outq_posturl = '%s' and outq_hash != '%s' limit 1",
dbesc($x[0]['outq_posturl']),
dbesc($id)
);
$g = q("select outq_created, outq_hash, outq_posturl from outq where outq_posturl = '%s' and outq_hash != '%s' limit 1",
dbesc($x[0]['outq_posturl']),
dbesc($id)
);
// swap them
// swap them
if ($g) {
$x = $g;
}
if ($g) {
$x = $g;
}
$y = q("select min(outq_created) as earliest from outq where outq_posturl = '%s'",
dbesc($x[0]['outq_posturl'])
);
$y = q("select min(outq_created) as earliest from outq where outq_posturl = '%s'",
dbesc($x[0]['outq_posturl'])
);
// look for the oldest queue entry with this destination URL. If it's older than a couple of days,
// the destination is considered to be down and only scheduled once an hour, regardless of the
// age of the current queue item.
// look for the oldest queue entry with this destination URL. If it's older than a couple of days,
// the destination is considered to be down and only scheduled once an hour, regardless of the
// age of the current queue item.
$might_be_down = false;
$might_be_down = false;
if($y)
$might_be_down = ((datetime_convert('UTC','UTC',$y[0]['earliest']) < datetime_convert('UTC','UTC','now - 2 days')) ? true : false);
if ($y)
$might_be_down = ((datetime_convert('UTC', 'UTC', $y[0]['earliest']) < datetime_convert('UTC', 'UTC', 'now - 2 days')) ? true : false);
// Set all other records for this destination way into the future.
// The queue delivers by destination. We'll keep one queue item for
// this destination (this one) with a shorter delivery. If we succeed
// once, we'll try to deliver everything for that destination.
// The delivery will be set to at most once per hour, and if the
// queue item is less than 12 hours old, we'll schedule for fifteen
// minutes.
// Set all other records for this destination way into the future.
// The queue delivers by destination. We'll keep one queue item for
// this destination (this one) with a shorter delivery. If we succeed
// once, we'll try to deliver everything for that destination.
// The delivery will be set to at most once per hour, and if the
// queue item is less than 12 hours old, we'll schedule for fifteen
// minutes.
$r = q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
dbesc($x[0]['outq_posturl'])
);
$r = q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
dbesc(datetime_convert('UTC', 'UTC', 'now + 5 days')),
dbesc($x[0]['outq_posturl'])
);
$since = datetime_convert('UTC','UTC',$y[0]['earliest']);
$since = datetime_convert('UTC', 'UTC', $y[0]['earliest']);
if(($might_be_down) || ($since < datetime_convert('UTC','UTC','now - 12 hour'))) {
$next = datetime_convert('UTC','UTC','now + 1 hour');
}
else {
$next = datetime_convert('UTC','UTC','now + ' . intval($add_priority) . ' minutes');
}
if (($might_be_down) || ($since < datetime_convert('UTC', 'UTC', 'now - 12 hour'))) {
$next = datetime_convert('UTC', 'UTC', 'now + 1 hour');
} else {
$next = datetime_convert('UTC', 'UTC', 'now + ' . intval($add_priority) . ' minutes');
}
q("UPDATE outq SET outq_updated = '%s',
q("UPDATE outq SET outq_updated = '%s',
outq_priority = outq_priority + %d,
outq_scheduled = '%s'
WHERE outq_hash = '%s'",
dbesc(datetime_convert()),
intval($add_priority),
dbesc($next),
dbesc($x[0]['outq_hash'])
);
}
dbesc(datetime_convert()),
intval($add_priority),
dbesc($next),
dbesc($x[0]['outq_hash'])
);
}
static function remove($id,$channel_id = 0) {
logger('queue: remove queue item ' . $id,LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
public static function remove($id, $channel_id = 0)
{
logger('queue: remove queue item ' . $id, LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
dbesc($id)
);
}
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
dbesc($id)
);
}
static function remove_by_posturl($posturl) {
logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
public static function remove_by_posturl($posturl)
{
logger('queue: remove queue posturl ' . $posturl, LOGGER_DEBUG);
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
dbesc($posturl)
);
}
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
dbesc($posturl)
);
}
public static function set_delivered($id, $channel = 0)
{
logger('queue: set delivered ' . $id, LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
static function set_delivered($id,$channel = 0) {
logger('queue: set delivered ' . $id,LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
// Set the next scheduled run date so far in the future that it will be expired
// long before it ever makes it back into the delivery chain.
// Set the next scheduled run date so far in the future that it will be expired
// long before it ever makes it back into the delivery chain.
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
dbesc(datetime_convert()),
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
dbesc($id)
);
}
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
dbesc(datetime_convert()),
dbesc(datetime_convert('UTC', 'UTC', 'now + 5 days')),
dbesc($id)
);
}
public static function insert($arr)
{
static function insert($arr) {
logger('insert: ' . print_r($arr, true), LOGGER_DATA);
logger('insert: ' . print_r($arr,true), LOGGER_DATA);
// do not queue anything with no destination
// do not queue anything with no destination
if (! (array_key_exists('posturl',$arr) && trim($arr['posturl']))) {
logger('no destination');
return false;
}
if (!(array_key_exists('posturl', $arr) && trim($arr['posturl']))) {
logger('no destination');
return false;
}
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
dbesc($arr['hash']),
intval($arr['account_id']),
intval($arr['channel_id']),
dbesc((isset($arr['driver']) && $arr['driver']) ? $arr['driver'] : 'zot6'),
dbesc($arr['posturl']),
intval(1),
intval((isset($arr['priority'])) ? $arr['priority'] : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc((isset($arr['scheduled'])) ? $arr['scheduled'] : datetime_convert()),
dbesc($arr['notify']),
dbesc(($arr['msg']) ? $arr['msg'] : '')
);
return $x;
dbesc($arr['hash']),
intval($arr['account_id']),
intval($arr['channel_id']),
dbesc((isset($arr['driver']) && $arr['driver']) ? $arr['driver'] : 'zot6'),
dbesc($arr['posturl']),
intval(1),
intval((isset($arr['priority'])) ? $arr['priority'] : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc((isset($arr['scheduled'])) ? $arr['scheduled'] : datetime_convert()),
dbesc($arr['notify']),
dbesc(($arr['msg']) ? $arr['msg'] : '')
);
return $x;
}
}
public static function deliver($outq, $immediate = false)
{
static function deliver($outq, $immediate = false) {
$base = null;
$h = parse_url($outq['outq_posturl']);
if ($h !== false) {
$base = $h['scheme'] . '://' . $h['host'] . ((isset($h['port']) && intval($h['port'])) ? ':' . $h['port'] : '');
}
$base = null;
$h = parse_url($outq['outq_posturl']);
if ($h !== false) {
$base = $h['scheme'] . '://' . $h['host'] . ((isset($h['port']) && intval($h['port'])) ? ':' . $h['port'] : '');
}
if (($base) && ($base !== z_root()) && ($immediate)) {
$y = q("select site_update, site_dead from site where site_url = '%s' ",
dbesc($base)
);
if ($y) {
if (intval($y[0]['site_dead'])) {
q("update dreport set dreport_result = '%s' where dreport_queue = '%s'",
dbesc('site dead'),
dbesc($outq['outq_hash'])
);
if (($base) && ($base !== z_root()) && ($immediate)) {
$y = q("select site_update, site_dead from site where site_url = '%s' ",
dbesc($base)
);
if ($y) {
if (intval($y[0]['site_dead'])) {
q("update dreport set dreport_result = '%s' where dreport_queue = '%s'",
dbesc('site dead'),
dbesc($outq['outq_hash'])
);
self::remove_by_posturl($outq['outq_posturl']);
logger('dead site ignored ' . $base);
return;
}
if ($y[0]['site_update'] < datetime_convert('UTC', 'UTC', 'now - 1 month')) {
q("update dreport set dreport_log = '%s' where dreport_queue = '%s'",
dbesc('site deferred'),
dbesc($outq['outq_hash'])
);
self::update($outq['outq_hash'], 10);
logger('immediate delivery deferred for site ' . $base);
return;
}
} else {
self::remove_by_posturl($outq['outq_posturl']);
logger('dead site ignored ' . $base);
return;
}
if ($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
q("update dreport set dreport_log = '%s' where dreport_queue = '%s'",
dbesc('site deferred'),
dbesc($outq['outq_hash'])
);
self::update($outq['outq_hash'],10);
logger('immediate delivery deferred for site ' . $base);
return;
}
}
else {
// zot sites should all have a site record, unless they've been dead for as long as
// your site has existed. Since we don't know for sure what these sites are,
// call them unknown
// zot sites should all have a site record, unless they've been dead for as long as
// your site has existed. Since we don't know for sure what these sites are,
// call them unknown
site_store_lowlevel(
[
'site_url' => $base,
'site_update' => datetime_convert(),
'site_dead' => 0,
'site_type' => ((in_array($outq['outq_driver'], ['post', 'activitypub'])) ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
'site_crypto' => ''
]
);
}
}
site_store_lowlevel(
[
'site_url' => $base,
'site_update' => datetime_convert(),
'site_dead' => 0,
'site_type' => ((in_array($outq['outq_driver'], [ 'post', 'activitypub' ])) ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
'site_crypto' => ''
]
);
}
}
$arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate);
call_hooks('queue_deliver', $arr);
if ($arr['handled'])
return;
$arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate);
call_hooks('queue_deliver',$arr);
if($arr['handled'])
return;
// "post" queue driver - used for diaspora and friendica-over-diaspora communications.
// "post" queue driver - used for diaspora and friendica-over-diaspora communications.
if ($outq['outq_driver'] === 'post') {
$result = z_post_url($outq['outq_posturl'], $outq['outq_msg']);
if ($result['success'] && $result['return_code'] < 300) {
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
if ($base) {
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
dbesc(datetime_convert()),
dbesc($base)
);
}
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
self::remove($outq['outq_hash']);
if($outq['outq_driver'] === 'post') {
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg']);
if($result['success'] && $result['return_code'] < 300) {
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($base) {
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
dbesc(datetime_convert()),
dbesc($base)
);
}
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
self::remove($outq['outq_hash']);
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
if (!$immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
if(! $immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
$piled_up = [];
if ($x) {
foreach ($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if ($piled_up) {
// call do_delivery() with the force flag
do_delivery($piled_up, true);
}
}
} else {
logger('deliver: queue post returned ' . $result['return_code']
. ' from ' . $outq['outq_posturl'], LOGGER_DEBUG);
self::update($outq['outq_hash'], 10);
}
return;
}
$piled_up = [];
if($x) {
foreach($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if($piled_up) {
// call do_delivery() with the force flag
do_delivery($piled_up, true);
}
}
}
else {
logger('deliver: queue post returned ' . $result['return_code']
. ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
self::update($outq['outq_hash'],10);
}
return;
}
if ($outq['outq_driver'] === 'asfetch') {
if ($outq['outq_driver'] === 'asfetch') {
$channel = channelx_by_n($outq['outq_channel']);
if (!$channel) {
logger('missing channel: ' . $outq['outq_channel']);
return;
}
$channel = channelx_by_n($outq['outq_channel']);
if (! $channel) {
logger('missing channel: ' . $outq['outq_channel']);
return;
}
if (!ActivityStreams::is_url($outq['outq_posturl'])) {
logger('fetch item is not url: ' . $outq['outq_posturl']);
self::remove($outq['outq_hash']);
return;
}
if (! ActivityStreams::is_url($outq['outq_posturl'])) {
logger('fetch item is not url: ' . $outq['outq_posturl']);
self::remove($outq['outq_hash']);
return;
}
$j = Activity::fetch($outq['outq_posturl'], $channel);
if ($j) {
$AS = new ActivityStreams($j, null, true);
if ($AS->is_valid() && isset($AS->data['type'])) {
if (ActivityStreams::is_an_actor($AS->data['type'])) {
Activity::actor_store($AS->data['id'], $AS->data);
}
if (strpos($AS->data['type'], 'Collection') !== false) {
// we are probably fetching a collection already - and do not support collection recursion at this time
self::remove($outq['outq_hash']);
return;
}
$item = Activity::decode_note($AS, true);
if ($item) {
Activity::store($channel, $channel['channnel_hash'], $AS, $item, true, true);
}
}
logger('deliver: queue fetch success from ' . $outq['outq_posturl'], LOGGER_DEBUG);
self::remove($outq['outq_hash']);
$j = Activity::fetch($outq['outq_posturl'],$channel);
if ($j) {
$AS = new ActivityStreams($j, null, true);
if ($AS->is_valid() && isset($AS->data['type'])) {
if (ActivityStreams::is_an_actor($AS->data['type'])) {
Activity::actor_store($AS->data['id'],$AS->data);
}
if (strpos($AS->data['type'],'Collection') !== false) {
// we are probably fetching a collection already - and do not support collection recursion at this time
self::remove($outq['outq_hash']);
return;
}
$item = Activity::decode_note($AS,true);
if ($item) {
Activity::store($channel,$channel['channnel_hash'],$AS,$item,true,true);
}
}
logger('deliver: queue fetch success from ' . $outq['outq_posturl'], LOGGER_DEBUG);
self::remove($outq['outq_hash']);
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
if (!$immediate) {
$x = q("select outq_hash from outq where outq_driver = 'asfetch' and outq_channel = %d and outq_delivered = 0",
dbesc($outq['outq_channel'])
);
if (! $immediate) {
$x = q("select outq_hash from outq where outq_driver = 'asfetch' and outq_channel = %d and outq_delivered = 0",
dbesc($outq['outq_channel'])
);
$piled_up = [];
if ($x) {
foreach ($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if ($piled_up) {
do_delivery($piled_up, true);
}
}
} else {
logger('deliver: queue fetch failed' . ' from ' . $outq['outq_posturl'], LOGGER_DEBUG);
self::update($outq['outq_hash'], 10);
}
return;
}
$piled_up = [];
if ($x) {
foreach ($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if ($piled_up) {
do_delivery($piled_up,true);
}
}
}
else {
logger('deliver: queue fetch failed' . ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
self::update($outq['outq_hash'],10);
}
return;
}
if ($outq['outq_driver'] === 'activitypub') {
if($outq['outq_driver'] === 'activitypub') {
$channel = channelx_by_n($outq['outq_channel']);
if (! $channel) {
logger('missing channel: ' . $outq['outq_channel']);
return;
}
$channel = channelx_by_n($outq['outq_channel']);
if (!$channel) {
logger('missing channel: ' . $outq['outq_channel']);
return;
}
$retries = 0;
$m = parse_url($outq['outq_posturl']);
$retries = 0;
$m = parse_url($outq['outq_posturl']);
$headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
$ret = $outq['outq_msg'];
logger('ActivityPub send: ' . jindent($ret), LOGGER_DATA);
$headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['Host'] = $m['host'];
$headers['(request-target)'] = 'post ' . get_request_string($outq['outq_posturl']);
$headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
$ret = $outq['outq_msg'];
logger('ActivityPub send: ' . jindent($ret), LOGGER_DATA);
$headers['Date'] = datetime_convert('UTC', 'UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['Host'] = $m['host'];
$headers['(request-target)'] = 'post ' . get_request_string($outq['outq_posturl']);
$xhead = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
if(strpos($outq['outq_posturl'],'http') !== 0) {
logger('bad url: ' . $outq['outq_posturl']);
self::remove($outq['outq_hash']);
}
$xhead = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel));
if (strpos($outq['outq_posturl'], 'http') !== 0) {
logger('bad url: ' . $outq['outq_posturl']);
self::remove($outq['outq_hash']);
}
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg'],$retries,[ 'headers' => $xhead ]);
$result = z_post_url($outq['outq_posturl'], $outq['outq_msg'], $retries, ['headers' => $xhead]);
if($result['success'] && $result['return_code'] < 300) {
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($base) {
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
dbesc(datetime_convert()),
dbesc($base)
);
}
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
self::remove($outq['outq_hash']);
if ($result['success'] && $result['return_code'] < 300) {
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
if ($base) {
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
dbesc(datetime_convert()),
dbesc($base)
);
}
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
self::remove($outq['outq_hash']);
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
if(! $immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
if (!$immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
$piled_up = [];
if($x) {
foreach($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if($piled_up) {
do_delivery($piled_up,true);
}
}
}
else {
if ($result['return_code'] >= 300) {
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('delivery rejected' . ' ' . $result['return_code']),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
}
else {
$dr = q("select * from dreport where dreport_queue = '%s'",
dbesc($outq['outq_hash'])
);
if ($dr) {
// update every queue entry going to this site with the most recent communication error
q("update dreport set dreport_log = '%s' where dreport_site = '%s'",
dbesc(z_curl_error($result)),
dbesc($dr[0]['dreport_site'])
);
}
}
logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
self::update($outq['outq_hash'],10);
}
return;
}
$piled_up = [];
if ($x) {
foreach ($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if ($piled_up) {
do_delivery($piled_up, true);
}
}
} else {
if ($result['return_code'] >= 300) {
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('delivery rejected' . ' ' . $result['return_code']),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
} else {
$dr = q("select * from dreport where dreport_queue = '%s'",
dbesc($outq['outq_hash'])
);
if ($dr) {
// update every queue entry going to this site with the most recent communication error
q("update dreport set dreport_log = '%s' where dreport_site = '%s'",
dbesc(z_curl_error($result)),
dbesc($dr[0]['dreport_site'])
);
}
}
logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $outq['outq_posturl'], LOGGER_DEBUG);
self::update($outq['outq_hash'], 10);
}
return;
}
// normal zot delivery
// normal zot delivery
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($outq['outq_posturl'] === z_root() . '/zot') {
// local delivery
$zot = new Receiver(new Zot6Handler(),$outq['outq_notify']);
$result = $zot->run();
logger('returned_json: ' . json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA);
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'],[ 'success' => true, 'body' => json_encode($result) ], $outq);
if ($outq['outq_posturl'] === z_root() . '/zot') {
// local delivery
$zot = new Receiver(new Zot6Handler(), $outq['outq_notify']);
$result = $zot->run();
logger('returned_json: ' . json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOGGER_DATA);
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'], ['success' => true, 'body' => json_encode($result)], $outq);
if(! $immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
if (!$immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
$piled_up = [];
if($x) {
foreach($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if($piled_up) {
do_delivery($piled_up,true);
}
}
}
else {
logger('remote');
$channel = null;
$piled_up = [];
if ($x) {
foreach ($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if ($piled_up) {
do_delivery($piled_up, true);
}
}
} else {
logger('remote');
$channel = null;
if($outq['outq_channel']) {
$channel = channelx_by_n($outq['outq_channel'],true);
}
if ($outq['outq_channel']) {
$channel = channelx_by_n($outq['outq_channel'], true);
}
$host_crypto = null;
$host_crypto = null;
if($channel && $base) {
$h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
dbesc($base)
);
if($h) {
$host_crypto = $h[0];
}
}
if ($channel && $base) {
$h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
dbesc($base)
);
if ($h) {
$host_crypto = $h[0];
}
}
$msg = $outq['outq_notify'];
$msg = $outq['outq_notify'];
$result = Libzot::zot($outq['outq_posturl'],$msg,$channel,$host_crypto);
$result = Libzot::zot($outq['outq_posturl'], $msg, $channel, $host_crypto);
if($result['success']) {
logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'],$result, $outq);
}
else {
$dr = q("select * from dreport where dreport_queue = '%s'",
dbesc($outq['outq_hash'])
);
if ($result['success']) {
logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'], $result, $outq);
} else {
$dr = q("select * from dreport where dreport_queue = '%s'",
dbesc($outq['outq_hash'])
);
// update every queue entry going to this site with the most recent communication error
q("update dreport set dreport_log = '%s' where dreport_site = '%s'",
dbesc(z_curl_error($result)),
dbesc($dr[0]['dreport_site'])
);
// update every queue entry going to this site with the most recent communication error
q("update dreport set dreport_log = '%s' where dreport_site = '%s'",
dbesc(z_curl_error($result)),
dbesc($dr[0]['dreport_site'])
);
logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
self::update($outq['outq_hash'],10);
}
}
return;
}
logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
logger('deliver: remote zot delivery fail data: ' . print_r($result, true), LOGGER_DATA);
self::update($outq['outq_hash'], 10);
}
}
return;
}
}

View file

@ -10,19 +10,19 @@ namespace Zotlabs\Lib;
class SConfig {
static public function Load($server_id) {
public static function Load($server_id) {
return XConfig::Load('s_' . $server_id);
}
static public function Get($server_id,$family,$key,$default = false) {
public static function Get($server_id, $family, $key, $default = false) {
return XConfig::Get('s_' . $server_id,$family,$key, $default);
}
static public function Set($server_id,$family,$key,$value) {
public static function Set($server_id, $family, $key, $value) {
return XConfig::Set('s_' . $server_id,$family,$key,$value);
}
static public function Delete($server_id,$family,$key) {
public static function Delete($server_id, $family, $key) {
return XConfig::Delete('s_' . $server_id,$family,$key);
}

View file

@ -16,141 +16,141 @@ use Zotlabs\Lib\Config;
* @license http://opensource.org/licenses/mit-license.php The MIT License
* @package svgsanitizer
*/
class SvgSanitizer
{
class SvgSanitizer {
private $xmlDoc; // PHP XML DOMDocument
private $xmlDoc; // PHP XML DOMDocument
private $removedattrs = [];
private $removedattrs = [];
private static $allowed_functions = ['matrix', 'url', 'translate', 'rgb'];
private static $allowed_functions = [ 'matrix', 'url', 'translate', 'rgb' ];
// defines the allowlist of elements and attributes allowed.
private static $allowlist = [
'a' => ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'href', 'xlink:href', 'xlink:title'],
'circle' => ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
'clipPath' => ['class', 'clipPathUnits', 'id'],
'defs' => [],
'style' => ['type'],
'desc' => [],
'ellipse' => ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
'feGaussianBlur' => ['class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation'],
'filter' => ['class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y'],
'foreignObject' => ['class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y'],
'g' => ['class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor'],
'image' => ['class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y'],
'line' => ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2'],
'linearGradient' => ['class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2'],
'marker' => ['id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox'],
'mask' => ['class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y'],
'metadata' => ['class', 'id'],
'path' => ['class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
'pattern' => ['class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y'],
'polygon' => ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
'polyline' => ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
'radialGradient' => ['class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href'],
'rect' => ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y'],
'stop' => ['class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage'],
'svg' => ['class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y'],
'switch' => ['class', 'id', 'requiredFeatures', 'systemLanguage'],
'symbol' => ['class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox'],
'text' => ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y'],
'textPath' => ['class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href'],
'title' => [],
'tspan' => ['class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y'],
'use' => ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y'],
];
// defines the allowlist of elements and attributes allowed.
private static $allowlist = [
'a' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'href', 'xlink:href', 'xlink:title' ],
'circle' => [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
'clipPath' => [ 'class', 'clipPathUnits', 'id' ],
'defs' => [ ],
'style' => [ 'type' ],
'desc' => [ ],
'ellipse' => [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
'feGaussianBlur' => [ 'class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation' ],
'filter' => [ 'class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y' ],
'foreignObject' => [ 'class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y' ],
'g' => [ 'class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ],
'image' => [ 'class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ],
'line' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2' ],
'linearGradient' => [ 'class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2' ],
'marker' => [ 'id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox' ],
'mask' => [ 'class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y' ],
'metadata' => [ 'class', 'id' ],
'path' => [ 'class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
'pattern' => [ 'class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y' ],
'polygon' => [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
'polyline' => [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
'radialGradient' => [ 'class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ],
'rect' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y' ],
'stop' => [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage' ],
'svg' => [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y' ],
'switch' => [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ],
'symbol' => [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox' ],
'text' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ],
'textPath' => [ 'class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href' ],
'title' => [ ],
'tspan' => [ 'class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y' ],
'use' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y' ],
];
public function __construct()
{
$this->xmlDoc = new DOMDocument('1.0', 'UTF-8');
$this->xmlDoc->preserveWhiteSpace = false;
libxml_use_internal_errors(true);
}
function __construct() {
$this->xmlDoc = new DOMDocument('1.0','UTF-8');
$this->xmlDoc->preserveWhiteSpace = false;
libxml_use_internal_errors(true);
}
// load XML SVG
public function load($file)
{
$this->xmlDoc->load($file);
}
// load XML SVG
function load($file) {
$this->xmlDoc->load($file);
}
public function loadXML($str)
{
if (!$str) {
logger('loadxml: empty input', LOGGER_DEBUG);
return false;
}
if (!$this->xmlDoc->loadXML($str)) {
logger('loadxml: ' . print_r(array_slice(libxml_get_errors(), 0, Config::Get('system', 'svg_backtrace_limit', 3)), true), LOGGER_DEBUG);
return false;
}
return true;
}
function loadXML($str) {
if (! $str) {
logger('loadxml: empty input', LOGGER_DEBUG);
return false;
}
if (! $this->xmlDoc->loadXML($str)) {
logger('loadxml: ' . print_r(array_slice(libxml_get_errors(),0,Config::Get('system','svg_backtrace_limit',3)),true), LOGGER_DEBUG);
return false;
}
return true;
}
public function sanitize()
{
// all elements in xml doc
$allElements = $this->xmlDoc->getElementsByTagName('*');
function sanitize()
{
// all elements in xml doc
$allElements = $this->xmlDoc->getElementsByTagName('*');
// loop through all elements
for ($i = 0; $i < $allElements->length; $i++) {
$this->removedattrs = [];
// loop through all elements
for($i = 0; $i < $allElements->length; $i++)
{
$this->removedattrs = [];
$currentNode = $allElements->item($i);
$currentNode = $allElements->item($i);
// logger('current_node: ' . print_r($currentNode,true));
// logger('current_node: ' . print_r($currentNode,true));
// array of allowed attributes in specific element
$allowlist_attr_arr = self::$allowlist[$currentNode->tagName];
// array of allowed attributes in specific element
$allowlist_attr_arr = self::$allowlist[$currentNode->tagName];
// does element exist in allowlist?
if (isset($allowlist_attr_arr)) {
$total = $currentNode->attributes->length;
// does element exist in allowlist?
if(isset($allowlist_attr_arr)) {
$total = $currentNode->attributes->length;
for ($x = 0; $x < $total; $x++) {
for($x = 0; $x < $total; $x++) {
// get attributes name
$attrName = $currentNode->attributes->item($x)->nodeName;
// get attributes name
$attrName = $currentNode->attributes->item($x)->nodeName;
// logger('checking: ' . print_r($currentNode->attributes->item($x),true));
$matches = false;
// logger('checking: ' . print_r($currentNode->attributes->item($x),true));
$matches = false;
// check if attribute isn't in allowlist
if (!in_array($attrName, $allowlist_attr_arr)) {
$this->removedattrs[] = $attrName;
} // check for disallowed functions
elseif (preg_match_all('/([a-zA-Z0-9]+)[\s]*\(/',
$currentNode->attributes->item($x)->textContent, $matches, PREG_SET_ORDER)) {
if ($attrName === 'text') {
continue;
}
foreach ($matches as $match) {
if (!in_array($match[1], self::$allowed_functions)) {
logger('queue_remove_function: ' . $match[1], LOGGER_DEBUG);
$this->removedattrs[] = $attrName;
}
}
}
}
if ($this->removedattrs) {
foreach ($this->removedattrs as $attr) {
$currentNode->removeAttribute($attr);
logger('removed: ' . $attr, LOGGER_DEBUG);
}
}
// check if attribute isn't in allowlist
if(! in_array($attrName, $allowlist_attr_arr)) {
$this->removedattrs[] = $attrName;
}
// check for disallowed functions
elseif (preg_match_all('/([a-zA-Z0-9]+)[\s]*\(/',
$currentNode->attributes->item($x)->textContent,$matches,PREG_SET_ORDER)) {
if ($attrName === 'text') {
continue;
}
foreach ($matches as $match) {
if(! in_array($match[1],self::$allowed_functions)) {
logger('queue_remove_function: ' . $match[1],LOGGER_DEBUG);
$this->removedattrs[] = $attrName;
}
}
}
}
if ($this->removedattrs) {
foreach ($this->removedattrs as $attr) {
$currentNode->removeAttribute($attr);
logger('removed: ' . $attr, LOGGER_DEBUG);
}
}
} // else remove element
else {
logger('remove_node: ' . print_r($currentNode, true));
$currentNode->parentNode->removeChild($currentNode);
}
}
return true;
}
}
// else remove element
else {
logger('remove_node: ' . print_r($currentNode,true));
$currentNode->parentNode->removeChild($currentNode);
}
}
return true;
}
function saveSVG() {
$this->xmlDoc->formatOutput = true;
return($this->xmlDoc->saveXML());
}
public function saveSVG()
{
$this->xmlDoc->formatOutput = true;
return ($this->xmlDoc->saveXML());
}
}

View file

@ -6,19 +6,19 @@ use App;
class System {
static public function get_platform_name() {
public static function get_platform_name() {
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('platform_name',App::$config['system']))
return App::$config['system']['platform_name'];
return PLATFORM_NAME;
}
static public function get_site_name() {
public static function get_site_name() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['sitename'])
return App::$config['system']['sitename'];
return '';
}
static public function get_banner() {
public static function get_banner() {
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('banner',App::$config['system']) && App::$config['system']['banner']) {
return App::$config['system']['banner'];
@ -26,14 +26,14 @@ class System {
return self::get_site_name();
}
static public function get_project_icon() {
public static function get_project_icon() {
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('icon',App::$config['system'])) {
return App::$config['system']['icon'];
}
return z_root() . '/images/' . PLATFORM_NAME . '-64.png';
}
static public function get_project_favicon() {
public static function get_project_favicon() {
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('favicon',App::$config['system'])) {
return App::$config['system']['favicon'];
}
@ -41,7 +41,7 @@ class System {
}
static public function get_project_version() {
public static function get_project_version() {
if(array_path_exists('system/hide_version', App::$config) && intval(App::$config['system']['hide_version']))
return '';
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('std_version',App::$config['system']))
@ -50,63 +50,63 @@ class System {
return self::get_std_version();
}
static public function get_update_version() {
public static function get_update_version() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['hide_version'])
return EMPTY_STR;
return DB_UPDATE_VERSION;
}
static public function get_notify_icon() {
public static function get_notify_icon() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['email_notify_icon_url'])
return App::$config['system']['email_notify_icon_url'];
return self::get_project_icon();
}
static public function get_site_icon() {
public static function get_site_icon() {
if(is_array(App::$config) && is_array(App::$config['system']) && isset(App::$config['system']['site_icon_url']) && App::$config['system']['site_icon_url'])
return App::$config['system']['site_icon_url'];
return self::get_project_icon();
}
static public function get_site_favicon() {
public static function get_site_favicon() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['site_favicon_url'])
return App::$config['system']['site_favicon_url'];
return self::get_project_favicon();
}
static public function get_project_link() {
public static function get_project_link() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_link'])
return App::$config['system']['project_link'];
return 'https://zotlabs.com/' . PLATFORM_NAME;
}
static public function get_project_srclink() {
public static function get_project_srclink() {
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['project_srclink'])
return App::$config['system']['project_srclink'];
return 'https://codeberg.org/zot/' . PLATFORM_NAME;
}
static public function ebs() {
public static function ebs() {
if(defined('EBSSTATE')) {
return EBSSTATE;
}
return 'armed';
}
static public function get_zot_revision() {
public static function get_zot_revision() {
$x = [ 'revision' => ZOT_REVISION ];
call_hooks('zot_revision',$x);
return $x['revision'];
}
static public function get_std_version() {
public static function get_std_version() {
if(defined('STD_VERSION'))
return STD_VERSION;
return '0.0.0';
}
static public function compatible_project($p) {
public static function compatible_project($p) {
if (in_array(strtolower($p),['hubzilla', 'zap', 'red', 'misty', 'mistpark', 'redmatrix', 'osada', 'roadhouse'])) {
return true;

View file

@ -4,7 +4,7 @@ namespace Zotlabs\Lib;
class ThreadListener {
static public function store($target_id,$portable_id,$ltype = 0) {
public static function store($target_id, $portable_id, $ltype = 0) {
$x = self::fetch($target_id,$portable_id,$ltype = 0);
if(! $x) {
$r = q("insert into listeners ( target_id, portable_id, ltype ) values ( '%s', '%s' , %d ) ",
@ -15,7 +15,7 @@ class ThreadListener {
}
}
static public function fetch($target_id,$portable_id,$ltype = 0) {
public static function fetch($target_id, $portable_id, $ltype = 0) {
$x = q("select * from listeners where target_id = '%s' and portable_id = '%s' and ltype = %d limit 1",
dbesc($target_id),
dbesc($portable_id),
@ -27,7 +27,7 @@ class ThreadListener {
return false;
}
static public function fetch_by_target($target_id,$ltype = 0) {
public static function fetch_by_target($target_id, $ltype = 0) {
$x = q("select * from listeners where target_id = '%s' and ltype = %d",
dbesc($target_id),
intval($ltype)
@ -36,14 +36,14 @@ class ThreadListener {
return $x;
}
static public function delete_by_target($target_id, $ltype = 0) {
public static function delete_by_target($target_id, $ltype = 0) {
return q("delete from listeners where target_id = '%s' and ltype = %d",
dbesc($target_id),
intval($ltype)
);
}
static public function delete_by_pid($portable_id, $ltype = 0) {
public static function delete_by_pid($portable_id, $ltype = 0) {
return q("delete from listeners where portable_id = '%s' and ltype = %d",
dbesc($portable_id),
intval($ltype)

View file

@ -3,61 +3,66 @@
namespace Zotlabs\Lib;
class Verify {
class Verify
{
static function create($type,$channel_id,$token,$meta) {
return q("insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta),
dbesc(datetime_convert())
);
}
public static function create($type, $channel_id, $token, $meta)
{
return q("insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta),
dbesc(datetime_convert())
);
}
static function match($type,$channel_id,$token,$meta) {
$r = q("select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta)
);
if($r) {
q("delete from verify where id = %d",
intval($r[0]['id'])
);
return true;
}
return false;
}
public static function match($type, $channel_id, $token, $meta)
{
$r = q("select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta)
);
if ($r) {
q("delete from verify where id = %d",
intval($r[0]['id'])
);
return true;
}
return false;
}
static function get_meta($type,$channel_id,$token) {
$r = q("select id, meta from verify where vtype = '%s' and channel = %d and token = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token)
);
if($r) {
q("delete from verify where id = %d",
intval($r[0]['id'])
);
return $r[0]['meta'];
}
return false;
}
public static function get_meta($type, $channel_id, $token)
{
$r = q("select id, meta from verify where vtype = '%s' and channel = %d and token = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token)
);
if ($r) {
q("delete from verify where id = %d",
intval($r[0]['id'])
);
return $r[0]['meta'];
}
return false;
}
/**
* @brief Purge entries of a verify-type older than interval.
*
* @param string $type Verify type
* @param string $interval SQL compatible time interval
*/
static function purge($type, $interval) {
q("delete from verify where vtype = '%s' and created < ( %s - INTERVAL %s )",
dbesc($type),
db_utcnow(),
db_quoteinterval($interval)
);
}
/**
* @brief Purge entries of a verify-type older than interval.
*
* @param string $type Verify type
* @param string $interval SQL compatible time interval
*/
public static function purge($type, $interval)
{
q("delete from verify where vtype = '%s' and created < ( %s - INTERVAL %s )",
dbesc($type),
db_utcnow(),
db_quoteinterval($interval)
);
}
}

View file

@ -6,104 +6,103 @@ namespace Zotlabs\Lib;
* @brief Fetch and return a webfinger for a resource
*
* @param string $resource - The resource
* @return boolean|string false or associative array from result JSON
* @return bool|string false or associative array from result JSON
*/
class Webfinger
{
class Webfinger {
private static $server = EMPTY_STR;
private static $resource = EMPTY_STR;
static private $server = EMPTY_STR;
static private $resource = EMPTY_STR;
public static function exec($resource)
{
static function exec($resource) {
if (!$resource) {
return false;
}
if (! $resource) {
return false;
}
self::parse_resource($resource);
self::parse_resource($resource);
if (!(self::$server && self::$resource)) {
return false;
}
if (! ( self::$server && self::$resource)) {
return false;
}
if (!check_siteallowed(self::$server)) {
logger('denied: ' . self::$server);
return false;
}
if (! check_siteallowed(self::$server)) {
logger('denied: ' . self::$server);
return false;
}
logger('fetching resource: ' . self::$resource . ' from ' . self::$server, LOGGER_DEBUG, LOG_INFO);
logger('fetching resource: ' . self::$resource . ' from ' . self::$server, LOGGER_DEBUG, LOG_INFO);
$url = 'https://' . self::$server . '/.well-known/webfinger?f=&resource=' . self::$resource;
$url = 'https://' . self::$server . '/.well-known/webfinger?f=&resource=' . self::$resource ;
$counter = 0;
$s = z_fetch_url($url, false, $counter, ['headers' => ['Accept: application/jrd+json, */*']]);
$counter = 0;
$s = z_fetch_url($url, false, $counter, [ 'headers' => [ 'Accept: application/jrd+json, */*' ] ]);
if ($s['success']) {
$j = json_decode($s['body'], true);
return ($j);
}
if ($s['success']) {
$j = json_decode($s['body'], true);
return($j);
}
return false;
}
return false;
}
public static function parse_resource($resource)
{
static function parse_resource($resource) {
self::$resource = urlencode($resource);
self::$resource = urlencode($resource);
if (strpos($resource, 'http') === 0) {
$m = parse_url($resource);
if ($m) {
if ($m['scheme'] !== 'https') {
return false;
}
self::$server = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
} else {
return false;
}
} elseif (strpos($resource, 'tag:') === 0) {
$arr = explode(':', $resource); // split the tag
$h = explode(',', $arr[1]); // split the host,date
self::$server = $h[0];
} else {
$x = explode('@', $resource);
if (!strlen($x[0])) {
// e.g. @dan@pixelfed.org
array_shift($x);
}
$username = $x[0];
if (count($x) > 1) {
self::$server = $x[1];
} else {
return false;
}
if (strpos($resource, 'acct:') !== 0) {
self::$resource = urlencode('acct:' . $resource);
}
}
}
if (strpos($resource,'http') === 0) {
$m = parse_url($resource);
if ($m) {
if ($m['scheme'] !== 'https') {
return false;
}
self::$server = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
}
else {
return false;
}
}
elseif (strpos($resource,'tag:') === 0) {
$arr = explode(':',$resource); // split the tag
$h = explode(',',$arr[1]); // split the host,date
self::$server = $h[0];
}
else {
$x = explode('@',$resource);
if (! strlen($x[0])) {
// e.g. @dan@pixelfed.org
array_shift($x);
}
$username = $x[0];
if (count($x) > 1) {
self::$server = $x[1];
}
else {
return false;
}
if (strpos($resource,'acct:') !== 0) {
self::$resource = urlencode('acct:' . $resource);
}
}
}
/**
* @brief fetch a webfinger resource and return a zot6 discovery url if present
*
*/
/**
* @brief fetch a webfinger resource and return a zot6 discovery url if present
*
*/
public static function zot_url($resource)
{
static function zot_url($resource) {
$arr = self::exec($resource);
$arr = self::exec($resource);
if (is_array($arr) && array_key_exists('links',$arr)) {
foreach ($arr['links'] as $link) {
if (array_key_exists('rel',$link) && $link['rel'] === PROTOCOL_ZOT6) {
if (array_key_exists('href',$link) && $link['href'] !== EMPTY_STR) {
return $link['href'];
}
}
}
}
return false;
}
if (is_array($arr) && array_key_exists('links', $arr)) {
foreach ($arr['links'] as $link) {
if (array_key_exists('rel', $link) && $link['rel'] === PROTOCOL_ZOT6) {
if (array_key_exists('href', $link) && $link['href'] !== EMPTY_STR) {
return $link['href'];
}
}
}
}
return false;
}
}

View file

@ -36,7 +36,7 @@ class XConfig {
* The observer's hash
* @return void|false Returns false if xchan is not set
*/
static public function Load($xchan) {
public static function Load($xchan) {
if(! $xchan)
return false;
@ -76,10 +76,10 @@ class XConfig {
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param boolean $default (optional) default false
* @param bool $default (optional) default false
* @return mixed Stored $value or false if it does not exist
*/
static public function Get($xchan, $family, $key, $default = false) {
public static function Get($xchan, $family, $key, $default = false) {
if(! $xchan)
return $default;
@ -109,7 +109,7 @@ class XConfig {
* The value to store
* @return mixed Stored $value or false
*/
static public function Set($xchan, $family, $key, $value) {
public static function Set($xchan, $family, $key, $value) {
// manage array value
$dbvalue = ((is_array($value)) ? serialise($value) : $value);
@ -159,7 +159,7 @@ class XConfig {
* The configuration key to delete
* @return mixed
*/
static public function Delete($xchan, $family, $key) {
public static function Delete($xchan, $family, $key) {
if(isset(App::$config[$xchan]) && isset(App::$config[$xchan][$family]) && isset(App::$config[$xchan][$family][$key]))
unset(App::$config[$xchan][$family][$key]);

View file

@ -7,7 +7,7 @@ use Zotlabs\Web\HTTPSig;
class ZotURL {
static public function fetch($url,$channel,$hub = null) {
public static function fetch($url, $channel, $hub = null) {
$ret = [ 'success' => false ];
@ -66,7 +66,7 @@ class ZotURL {
}
static public function is_zoturl($s) {
public static function is_zoturl($s) {
if(strpos($url,'x-zot:') === 0) {
return true;
@ -75,7 +75,7 @@ class ZotURL {
}
static public function lookup($portable_id,$hub) {
public static function lookup($portable_id, $hub) {
$r = q("select * from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and site_dead = 0 order by hubloc_primary desc",
dbesc($portable_id)
@ -107,7 +107,7 @@ class ZotURL {
}
static public function parse_response($arr) {
public static function parse_response($arr) {
if(! $arr['success']) {
return false;
}

View file

@ -4,60 +4,61 @@ namespace Zotlabs\Lib;
use Zotlabs\Web\HTTPSig;
class Zotfinger {
class Zotfinger
{
static function exec($resource,$channel = null,$verify = true) {
public static function exec($resource, $channel = null, $verify = true)
{
if (! $resource) {
return false;
}
if (!$resource) {
return false;
}
$m = parse_url($resource);
$m = parse_url($resource);
if ($m['host'] !== punify($m['host'])) {
$url = str_replace($m['host'],punify($m['host']),$url);
$m['host'] = punify($m['host']);
}
if ($m['host'] !== punify($m['host'])) {
$url = str_replace($m['host'], punify($m['host']), $url);
$m['host'] = punify($m['host']);
}
$data = json_encode([ 'zot_token' => random_string() ]);
$data = json_encode(['zot_token' => random_string()]);
if ($channel && $m) {
if ($channel && $m) {
$headers = [
'Accept' => 'application/x-zot+json',
'Content-Type' => 'application/x-zot+json',
'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data),
'Host' => $m['host'],
'(request-target)' => 'post ' . get_request_string($resource)
];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
}
else {
$h = [ 'Accept: application/x-zot+json' ];
}
$headers = [
'Accept' => 'application/x-zot+json',
'Content-Type' => 'application/x-zot+json',
'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data),
'Host' => $m['host'],
'(request-target)' => 'post ' . get_request_string($resource)
];
$h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false);
} else {
$h = ['Accept: application/x-zot+json'];
}
$result = [];
$result = [];
$redirects = 0;
$x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] );
$redirects = 0;
$x = z_post_url($resource, $data, $redirects, ['headers' => $h]);
if ($x['success']) {
if ($x['success']) {
if ($verify) {
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
}
if ($verify) {
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
}
$result['data'] = json_decode($x['body'],true);
$result['data'] = json_decode($x['body'], true);
if ($result['data'] && is_array($result['data']) && array_key_exists('encrypted',$result['data']) && $result['data']['encrypted']) {
$result['data'] = json_decode(Crypto::unencapsulate($result['data'],get_config('system','prvkey')),true);
}
if ($result['data'] && is_array($result['data']) && array_key_exists('encrypted', $result['data']) && $result['data']['encrypted']) {
$result['data'] = json_decode(Crypto::unencapsulate($result['data'], get_config('system', 'prvkey')), true);
}
return $result;
}
return $result;
}
return false;
}
return false;
}
}

View file

@ -23,101 +23,100 @@ require_once('include/acl_selectors.php');
* keys however this functionality has grown in an ad-hoc manner and has gotten
* quite messy over time.
*/
class Acl extends Controller
{
class Acl extends Controller {
public function init()
{
function init() {
// logger('mod_acl: ' . print_r($_REQUEST,true),LOGGER_DATA);
// logger('mod_acl: ' . print_r($_REQUEST,true),LOGGER_DATA);
$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);
$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
// 'f' => forums only ACL request
// 'c' => Connections only ACL request or editor (textarea) mention request
// $_REQUEST['search'] contains ACL search text.
// $type =
// '' => standard ACL request
// 'g' => Groups only ACL request
// 'f' => forums 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)
// 'z' => autocomplete any xchan, but also include abook_alias, requires non-zero local_channel()
// and also contains xid without urlencode, used specifically by activity_filter widget
// $_REQUEST['query'] contains autocomplete 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)
// 'z' => autocomplete any xchan, but also include abook_alias, requires non-zero local_channel()
// and also contains xid without urlencode, used specifically by activity_filter widget
// $_REQUEST['query'] contains autocomplete search text.
// The different autocomplete libraries use different names for the search text
// parameter. Internally we'll use $search to represent the search text no matter
// what request variable it was attached to.
// The different autocomplete libraries use different names for the search text
// parameter. Internally we'll use $search to represent the search text no matter
// what request variable it was attached to.
if (array_key_exists('query',$_REQUEST)) {
$search = $_REQUEST['query'];
}
if (array_key_exists('query', $_REQUEST)) {
$search = $_REQUEST['query'];
}
if ( (! local_channel()) && (! in_array($type, [ 'x', 'c', 'f' ]))) {
killme();
}
if ((!local_channel()) && (!in_array($type, ['x', 'c', 'f']))) {
killme();
}
$permitted = [];
$permitted = [];
if (in_array($type, [ 'm', 'a', 'f' ])) {
if (in_array($type, ['m', 'a', 'f'])) {
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
// the requisite permissions which we can check against.
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
// the requisite permissions which we can check against.
$x = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s'",
intval(local_channel()),
dbesc(($type === 'm') ? '%post_mail%' : '%tag_deliver%')
);
$x = q("select xchan from abconfig where chan = %d and cat = 'system' and k = 'their_perms' and v like '%s'",
intval(local_channel()),
dbesc(($type === 'm') ? '%post_mail%' : '%tag_deliver%')
);
$permitted = ids_to_array($x,'xchan');
}
$permitted = ids_to_array($x, 'xchan');
}
if ($search) {
$sql_extra = " AND pgrp.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
// sql_extra2 is typically used when we don't have a local_channel - so we are not search abook_alias
$sql_extra2 = " AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
if ($search) {
$sql_extra = " AND pgrp.gname LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " ";
// sql_extra2 is typically used when we don't have a local_channel - so we are not search abook_alias
$sql_extra2 = " AND ( xchan_name LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR xchan_addr LIKE " . protect_sprintf("'%" . dbesc(punify($search)) . ((strpos($search, '@') === false) ? "%@%'" : "%'")) . ") ";
// 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)).
// 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('" . protect_sprintf(dbesc($search))
. "' IN xchan_name) else position('" . protect_sprintf(dbesc(punify($search))) . "' IN xchan_addr) end, ";
$order_extra2 = "CASE WHEN xchan_name LIKE "
. protect_sprintf( "'%" . dbesc($search) . "%'" )
. " then POSITION('" . protect_sprintf(dbesc($search))
. "' IN xchan_name) else position('" . protect_sprintf(dbesc(punify($search))) . "' IN xchan_addr) end, ";
$sql_extra3 = "AND ( xchan_addr like " . protect_sprintf("'%" . dbesc(punify($search)) . "%'") . " OR xchan_name like " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR abook_alias like " . protect_sprintf("'%" . dbesc($search) . "%'") . " ) ";
$sql_extra3 = "AND ( xchan_addr like " . protect_sprintf( "'%" . dbesc(punify($search)) . "%'" ) . " OR xchan_name like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR abook_alias like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ) ";
$sql_extra4 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . " OR abook_alias LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'") . ") ";
$sql_extra4 = "AND ( xchan_name LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR xchan_addr LIKE " . protect_sprintf("'%" . dbesc(punify($search)) . ((strpos($search, '@') === false) ? "%@%'" : "%'")) . " OR abook_alias LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . ") ";
}
else {
$sql_extra = $sql_extra2 = $sql_extra3 = $sql_extra4 = "";
}
} else {
$sql_extra = $sql_extra2 = $sql_extra3 = $sql_extra4 = "";
}
$groups = [];
$contacts = [];
$groups = [];
$contacts = [];
if ($type == '' || $type == 'g') {
if ($type == '' || $type == 'g') {
// Normal privacy groups
// Normal privacy groups
$r = q("SELECT pgrp.id, pgrp.hash, pgrp.gname
$r = q("SELECT pgrp.id, pgrp.hash, pgrp.gname
FROM pgrp, pgrp_member
WHERE pgrp.deleted = 0 AND pgrp.uid = %d
AND pgrp_member.gid = pgrp.id
@ -125,238 +124,232 @@ class Acl extends Controller {
GROUP BY pgrp.id
ORDER BY pgrp.gname
LIMIT %d OFFSET %d",
intval(local_channel()),
intval($count),
intval($start)
);
intval(local_channel()),
intval($count),
intval($start)
);
if ($r) {
foreach ($r as $g) {
// logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(),$g['id']));
$groups[] = [
"type" => "g",
"photo" => "images/twopeople.png",
"name" => $g['gname'],
"id" => $g['id'],
"xid" => $g['hash'],
"uids" => AccessList::members_xchan(local_channel(),$g['id']),
"link" => ''
];
}
}
}
if ($r) {
foreach ($r as $g) {
// logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(),$g['id']));
$groups[] = [
"type" => "g",
"photo" => "images/twopeople.png",
"name" => $g['gname'],
"id" => $g['id'],
"xid" => $g['hash'],
"uids" => AccessList::members_xchan(local_channel(), $g['id']),
"link" => ''
];
}
}
}
if ($type == '' || $type == 'c' || $type === 'f') {
if ($type == '' || $type == 'c' || $type === 'f') {
// Getting info from the abook is better for local users because it contains info about permissions
if (local_channel()) {
// Getting info from the abook is better for local users because it contains info about permissions
if (local_channel()) {
// add connections
// add connections
$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, xchan_type, abook_flags, abook_self
$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, xchan_type, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra4 order by xchan_name asc limit $count" ,
intval(local_channel())
);
WHERE abook_channel = %d AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra4 order by xchan_name asc limit $count",
intval(local_channel())
);
}
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_flags, 0 as abook_self
} 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_flags, 0 as abook_self
FROM xchan left join xlink on xlink_link = xchan_hash
WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc limit $count" ,
dbesc(get_observer_hash())
);
WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc limit $count",
dbesc(get_observer_hash())
);
}
if ((count($r) < 100) && $type == 'c') {
$r2 = 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_flags, 0 as abook_self
}
if ((count($r) < 100) && $type == 'c') {
$r2 = 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_flags, 0 as abook_self
FROM xchan WHERE xchan_deleted = 0 and xchan_network != 'unknown' $sql_extra2 order by $order_extra2 xchan_name asc limit $count"
);
if ($r2) {
$r = array_merge($r,$r2);
$r = unique_multidim_array($r,'hash');
}
}
);
if ($r2) {
$r = array_merge($r, $r2);
$r = unique_multidim_array($r, 'hash');
}
}
}
elseif ($type == 'm') {
} elseif ($type == 'm') {
$r = [];
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
$r = [];
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d
and xchan_deleted = 0
$sql_extra3
ORDER BY xchan_name ASC ",
intval(local_channel())
);
if ($z) {
foreach ($z as $zz) {
if (in_array($zz['hash'],$permitted)) {
$r[] = $zz;
}
}
}
intval(local_channel())
);
if ($z) {
foreach ($z as $zz) {
if (in_array($zz['hash'], $permitted)) {
$r[] = $zz;
}
}
}
}
elseif ($type == 'a') {
} 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 FROM abook left join xchan on abook_xchan = xchan_hash
$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 FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d
and xchan_deleted = 0
$sql_extra3
ORDER BY xchan_name ASC ",
intval(local_channel())
);
intval(local_channel())
);
}
elseif ($type == 'z') {
$r = q("SELECT 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 FROM xchan left join abook on xchan_hash = abook_xchan
} elseif ($type == 'z') {
$r = q("SELECT 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 FROM xchan left join abook on xchan_hash = abook_xchan
WHERE ( abook_channel = %d OR abook_channel IS NULL )
and xchan_deleted = 0
$sql_extra3
ORDER BY xchan_name ASC ",
intval(local_channel())
);
}
intval(local_channel())
);
} elseif ($type == 'x') {
$contacts = [];
$r = $this->navbar_complete();
if ($r) {
foreach ($r as $g) {
$contacts[] = [
"photo" => $g['photo'],
"name" => $g['name'],
"nick" => $g['address'],
'link' => (($g['address']) ? $g['address'] : $g['url']),
'xchan' => $g['hash']
];
}
}
elseif ($type == 'x') {
$contacts = [];
$r = $this->navbar_complete();
if ($r) {
foreach ($r as $g) {
$contacts[] = [
"photo" => $g['photo'],
"name" => $g['name'],
"nick" => $g['address'],
'link' => (($g['address']) ? $g['address'] : $g['url']),
'xchan' => $g['hash']
];
}
}
$o = [
'start' => $start,
'count' => $count,
'items' => $contacts,
];
json_return_and_die($o);
} else {
$r = [];
}
$o = [
'start' => $start,
'count' => $count,
'items' => $contacts,
];
json_return_and_die($o);
}
else {
$r = [];
}
if ($r) {
foreach ($r as $g) {
if ($r) {
foreach ($r as $g) {
if (isset($g['network']) && in_array($g['network'], ['rss', 'anon', 'unknown']) && ($type != 'a')) {
continue;
}
if (isset($g['network']) && in_array($g['network'],['rss','anon','unknown']) && ($type != 'a')) {
continue;
}
// 'z' (activity_filter autocomplete) requires an un-encoded hash to prevent double encoding
// 'z' (activity_filter autocomplete) requires an un-encoded hash to prevent double encoding
if ($type !== 'z') {
$g['hash'] = urlencode($g['hash']);
}
if ($type !== 'z') {
$g['hash'] = urlencode($g['hash']);
}
if (!$g['nick']) {
$g['nick'] = $g['url'];
}
if (! $g['nick']) {
$g['nick'] = $g['url'];
}
if (in_array($g['hash'], $permitted) && $type === 'f' && (!$noforums)) {
$contacts[] = [
"type" => "c",
"photo" => "images/twopeople.png",
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => substr($g['nick'], 0, strpos($g['nick'], '@')),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => 'taggable',
"label" => t('network')
];
}
if ($type !== 'f') {
$contacts[] = [
"type" => "c",
"photo" => $g['micro'],
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => ((strpos($g['nick'], '@')) ? substr($g['nick'], 0, strpos($g['nick'], '@')) : $g['nick']),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => '',
"label" => '',
];
}
}
}
if (in_array($g['hash'],$permitted) && $type === 'f' && (! $noforums)) {
$contacts[] = [
"type" => "c",
"photo" => "images/twopeople.png",
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => substr($g['nick'],0,strpos($g['nick'],'@')),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => 'taggable',
"label" => t('network')
];
}
if ($type !== 'f') {
$contacts[] = [
"type" => "c",
"photo" => $g['micro'],
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => ((strpos($g['nick'],'@')) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => '',
"label" => '',
];
}
}
}
$items = array_merge($groups, $contacts);
$items = array_merge($groups, $contacts);
$o = [
'start' => $start,
'count' => $count,
'items' => $items,
];
$o = [
'start' => $start,
'count' => $count,
'items' => $items,
];
json_return_and_die($o);
}
json_return_and_die($o);
}
function navbar_complete() {
public function navbar_complete()
{
// logger('navbar_complete');
// logger('navbar_complete');
if (observer_prohibited()) {
return;
}
if (observer_prohibited()) {
return;
}
$dirmode = intval(get_config('system','directory_mode'));
$search = ((x($_REQUEST,'search')) ? htmlentities($_REQUEST['search'],ENT_COMPAT,'UTF-8',false) : '');
if (! $search || mb_strlen($search) < 2) {
return [];
}
$dirmode = intval(get_config('system', 'directory_mode'));
$search = ((x($_REQUEST, 'search')) ? htmlentities($_REQUEST['search'], ENT_COMPAT, 'UTF-8', false) : '');
if (!$search || mb_strlen($search) < 2) {
return [];
}
$star = false;
$address = false;
$star = false;
$address = false;
if (substr($search,0,1) === '@') {
$search = substr($search,1);
}
if (substr($search, 0, 1) === '@') {
$search = substr($search, 1);
}
if (substr($search,0,1) === '*') {
$star = true;
$search = substr($search,1);
}
if (substr($search, 0, 1) === '*') {
$star = true;
$search = substr($search, 1);
}
if (strpos($search,'@') !== false) {
$address = true;
}
if (strpos($search, '@') !== false) {
$address = true;
}
$url = z_root() . '/dirsearch';
$url = z_root() . '/dirsearch';
$results = [];
$results = [];
$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(punify($search)) : '');
if ($url) {
$query = $url . '?f=';
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode(punify($search)) : '');
$x = z_fetch_url($query);
if ($x['success']) {
$t = 0;
$j = json_decode($x['body'],true);
if ($j && $j['results']) {
$results = $j['results'];
}
}
}
return $results;
}
$x = z_fetch_url($query);
if ($x['success']) {
$t = 0;
$j = json_decode($x['body'], true);
if ($j && $j['results']) {
$results = $j['results'];
}
}
}
return $results;
}
}

View file

@ -10,280 +10,280 @@ use Zotlabs\Lib\LDSignatures;
use Zotlabs\Lib\ThreadListener;
use App;
class Activity extends Controller {
class Activity extends Controller
{
function init() {
public function init()
{
if (ActivityStreams::is_as_request()) {
$item_id = argv(1);
if (ActivityStreams::is_as_request()) {
$item_id = argv(1);
if (! $item_id) {
return;
}
if (!$item_id) {
return;
}
$ob_authorise = false;
$item_uid = 0;
$ob_authorise = false;
$item_uid = 0;
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
$t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'",
dbesc($item_id)
);
if ($t) {
foreach ($t as $token) {
if ($token['v'] === $bear) {
$ob_authorize = true;
$item_uid = $token['uid'];
break;
}
}
}
}
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
$t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'",
dbesc($item_id)
);
if ($t) {
foreach ($t as $token) {
if ($token['v'] === $bear) {
$ob_authorize = true;
$item_uid = $token['uid'];
break;
}
}
}
}
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
and item.item_delayed = 0 and item.item_blocked = 0 ";
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (!check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (!check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
// Give ocap tokens priority
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
// Give ocap tokens priority
if ($ob_authorize) {
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
}
else {
$sql_extra = item_permissions_sql(0);
}
if ($ob_authorize) {
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
} else {
$sql_extra = item_permissions_sql(0);
}
$r = q("select * from item where ( uuid = '%s' or mid = '%s' or mid = '%s' ) $item_normal $sql_extra limit 1",
dbesc($item_id),
dbesc(z_root() . '/activity/' . $item_id),
dbesc(z_root() . '/item/' . $item_id)
);
$r = q("select * from item where ( uuid = '%s' or mid = '%s' or mid = '%s' ) $item_normal $sql_extra limit 1",
dbesc($item_id),
dbesc(z_root() . '/activity/' . $item_id),
dbesc(z_root() . '/item/' . $item_id)
);
if (! $r) {
$r = q("select * from item where ( uuid = '%s' or mid = '%s' or mid = '%s' ) $item_normal limit 1",
dbesc($item_id),
dbesc(z_root() . '/activity/' . $item_id),
dbesc(z_root() . '/item/' . $item_id)
);
if (!$r) {
$r = q("select * from item where ( uuid = '%s' or mid = '%s' or mid = '%s' ) $item_normal limit 1",
dbesc($item_id),
dbesc(z_root() . '/activity/' . $item_id),
dbesc(z_root() . '/item/' . $item_id)
);
if ($r) {
http_status_exit(403, 'Forbidden');
}
http_status_exit(404, 'Not found');
}
if ($r) {
http_status_exit(403, 'Forbidden');
}
http_status_exit(404, 'Not found');
}
xchan_query($r,true);
$items = fetch_post_tags($r,false);
xchan_query($r, true);
$items = fetch_post_tags($r, false);
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id);
}
}
if ($portable_id && (!intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (!$c) {
ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id);
}
}
$channel = channelx_by_n($items[0]['uid']);
$channel = channelx_by_n($items[0]['uid']);
as_return_and_die(ZlibActivity::encode_activity($items[0],true),$channel);
as_return_and_die(ZlibActivity::encode_activity($items[0], true), $channel);
}
}
if (Libzot::is_zot_request()) {
if (Libzot::is_zot_request()) {
$item_id = argv(1);
$item_id = argv(1);
if (! $item_id) {
http_status_exit(404, 'Not found');
}
if (!$item_id) {
http_status_exit(404, 'Not found');
}
$portable_id = EMPTY_STR;
$portable_id = EMPTY_STR;
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and not verb in ( 'Follow', 'Ignore' ) ";
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and not verb in ( 'Follow', 'Ignore' ) ";
$i = null;
$i = null;
// do we have the item (at all)?
// do we have the item (at all)?
$r = q("select * from item where mid = '%s' $item_normal limit 1",
dbesc(z_root() . '/activity/' . $item_id)
);
$r = q("select * from item where mid = '%s' $item_normal limit 1",
dbesc(z_root() . '/activity/' . $item_id)
);
if (! $r) {
$r = q("select * from item where mid = '%s' $item_normal limit 1",
dbesc(z_root() . '/item/' . $item_id)
);
if ($r) {
goaway(z_root() . '/item/' . $item_id);
}
http_status_exit(404,'Not found');
}
if (!$r) {
$r = q("select * from item where mid = '%s' $item_normal limit 1",
dbesc(z_root() . '/item/' . $item_id)
);
if ($r) {
goaway(z_root() . '/item/' . $item_id);
}
http_status_exit(404, 'Not found');
}
// process an authenticated fetch
// process an authenticated fetch
$sigdata = HTTPSig::verify(EMPTY_STR);
if($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
observer_auth($portable_id);
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
observer_auth($portable_id);
// first see if we have a copy of this item's parent owned by the current signer
// include xchans for all zot-like networks - these will have the same guid and public key
// first see if we have a copy of this item's parent owned by the current signer
// include xchans for all zot-like networks - these will have the same guid and public key
$x = q("select * from xchan where xchan_hash = '%s'",
dbesc($sigdata['portable_id'])
);
$x = q("select * from xchan where xchan_hash = '%s'",
dbesc($sigdata['portable_id'])
);
if ($x) {
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
dbesc($sigdata['portable_id']),
dbesc($x[0]['xchan_guid']),
dbesc($x[0]['xchan_pubkey'])
);
if ($x) {
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
dbesc($sigdata['portable_id']),
dbesc($x[0]['xchan_guid']),
dbesc($x[0]['xchan_pubkey'])
);
if ($xchans) {
$hashes = ids_to_querystr($xchans,'xchan_hash',true);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan in ( " . protect_sprintf($hashes) . " ) limit 1",
dbesc($r[0]['parent_mid'])
);
}
}
}
if ($xchans) {
$hashes = ids_to_querystr($xchans, 'xchan_hash', true);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan in ( " . protect_sprintf($hashes) . " ) limit 1",
dbesc($r[0]['parent_mid'])
);
}
}
}
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
// with a bias towards those items owned by channels on this site (item_wall = 1)
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
// with a bias towards those items owned by channels on this site (item_wall = 1)
$sql_extra = item_permissions_sql(0);
$sql_extra = item_permissions_sql(0);
if (! $i) {
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1",
dbesc($r[0]['parent_mid'])
);
}
if (!$i) {
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1",
dbesc($r[0]['parent_mid'])
);
}
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
if (! $i) {
$t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'",
dbesc($bear)
);
if ($t) {
$i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1",
dbesc($item_id),
intval($t[0]['iid'])
);
}
}
}
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
if (!$i) {
$t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'",
dbesc($bear)
);
if ($t) {
$i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1",
dbesc($item_id),
intval($t[0]['iid'])
);
}
}
}
if (! $i) {
http_status_exit(403,'Forbidden');
}
if (!$i) {
http_status_exit(403, 'Forbidden');
}
$parents_str = ids_to_querystr($i,'item_id');
$parents_str = ids_to_querystr($i, 'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal ",
dbesc($parents_str)
);
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal ",
dbesc($parents_str)
);
if(! $items) {
http_status_exit(404, 'Not found');
}
if (!$items) {
http_status_exit(404, 'Not found');
}
xchan_query($items,true);
$items = fetch_post_tags($items,true);
xchan_query($items, true);
$items = fetch_post_tags($items, true);
$observer = App::get_observer();
$parent = $items[0];
$recips = (($parent['owner']['xchan_network'] === 'activitypub') ? get_iconfig($parent['id'],'activitypub','recips', []) : []);
$to = (($recips && array_key_exists('to',$recips) && is_array($recips['to'])) ? $recips['to'] : null);
$nitems = [];
foreach($items as $i) {
$observer = App::get_observer();
$parent = $items[0];
$recips = (($parent['owner']['xchan_network'] === 'activitypub') ? get_iconfig($parent['id'], 'activitypub', 'recips', []) : []);
$to = (($recips && array_key_exists('to', $recips) && is_array($recips['to'])) ? $recips['to'] : null);
$nitems = [];
foreach ($items as $i) {
$mids = [];
$mids = [];
if(intval($i['item_private'])) {
if(! $observer) {
continue;
}
// ignore private reshare, possibly from hubzilla
if($i['verb'] === 'Announce') {
if(! in_array($i['thr_parent'],$mids)) {
$mids[] = $i['thr_parent'];
}
continue;
}
// also ignore any children of the private reshares
if(in_array($i['thr_parent'],$mids)) {
continue;
}
if (intval($i['item_private'])) {
if (!$observer) {
continue;
}
// ignore private reshare, possibly from hubzilla
if ($i['verb'] === 'Announce') {
if (!in_array($i['thr_parent'], $mids)) {
$mids[] = $i['thr_parent'];
}
continue;
}
// also ignore any children of the private reshares
if (in_array($i['thr_parent'], $mids)) {
continue;
}
if((! $to) || (! in_array($observer['xchan_url'],$to))) {
continue;
}
if ((!$to) || (!in_array($observer['xchan_url'], $to))) {
continue;
}
}
$nitems[] = $i;
}
}
$nitems[] = $i;
}
if(! $nitems)
http_status_exit(404, 'Not found');
if (!$nitems)
http_status_exit(404, 'Not found');
$chan = channelx_by_n($nitems[0]['uid']);
$chan = channelx_by_n($nitems[0]['uid']);
if(! $chan)
http_status_exit(404, 'Not found');
if (!$chan)
http_status_exit(404, 'Not found');
if(! perm_is_allowed($chan['channel_id'],get_observer_hash(),'view_stream'))
http_status_exit(403, 'Forbidden');
if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream'))
http_status_exit(403, 'Forbidden');
$i = ZlibActivity::encode_item_collection($nitems,'conversation/' . $item_id,'OrderedCollection',true, count($nitems));
if ($portable_id && (! intval($items[0]['item_private']))) {
ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id);
}
$i = ZlibActivity::encode_item_collection($nitems, 'conversation/' . $item_id, 'OrderedCollection', true, count($nitems));
if ($portable_id && (!intval($items[0]['item_private']))) {
ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id);
}
if(! $i)
http_status_exit(404, 'Not found');
if (!$i)
http_status_exit(404, 'Not found');
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
ZlibActivity::ap_schema()
]], $i);
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
ZlibActivity::ap_schema()
]], $i);
$headers = [];
$headers['Content-Type'] = 'application/x-zot+json' ;
$x['signature'] = LDSignatures::sign($x,$chan);
$ret = json_encode($x, JSON_UNESCAPED_SLASHES);
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
$h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan));
HTTPSig::set_headers($h);
echo $ret;
killme();
$headers = [];
$headers['Content-Type'] = 'application/x-zot+json';
$x['signature'] = LDSignatures::sign($x, $chan);
$ret = json_encode($x, JSON_UNESCAPED_SLASHES);
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
$h = HTTPSig::create_sig($headers, $chan['channel_prvkey'], channel_url($chan));
HTTPSig::set_headers($h);
echo $ret;
killme();
}
}
goaway(z_root() . '/item/' . argv(1));
}
goaway(z_root() . '/item/' . argv(1));
}
}

View file

@ -18,174 +18,176 @@ use Zotlabs\Lib\Config;
* @brief Admin area.
*
*/
class Admin extends Controller
{
class Admin extends Controller {
private $sm = null;
private $sm = null;
public function __construct()
{
$this->sm = new SubModule();
}
function __construct() {
$this->sm = new SubModule();
}
public function init()
{
function init() {
logger('admin_init', LOGGER_DEBUG);
logger('admin_init', LOGGER_DEBUG);
if (!is_site_admin()) {
logger('admin denied.');
return;
}
if (! is_site_admin()) {
logger('admin denied.');
return;
}
if (argc() > 1) {
$this->sm->call('init');
}
}
if (argc() > 1) {
$this->sm->call('init');
}
}
function post() {
public function post()
{
logger('admin_post', LOGGER_DEBUG);
logger('admin_post', LOGGER_DEBUG);
if (! is_site_admin()) {
logger('admin denied.');
return;
}
if (!is_site_admin()) {
logger('admin denied.');
return;
}
if (argc() > 1) {
$this->sm->call('post');
}
if (argc() > 1) {
$this->sm->call('post');
}
// goaway(z_root() . '/admin' );
}
// goaway(z_root() . '/admin' );
}
/**
* @return string
*/
/**
* @return string
*/
function get() {
public function get()
{
logger('admin_content', LOGGER_DEBUG);
logger('admin_content', LOGGER_DEBUG);
if (! is_site_admin()) {
logger('admin denied.');
return login(false);
}
if (!is_site_admin()) {
logger('admin denied.');
return login(false);
}
/*
* Page content
*/
/*
* Page content
*/
nav_set_selected('Admin');
nav_set_selected('Admin');
$o = '';
$o = '';
if (argc() > 1) {
$o = $this->sm->call('get');
if ($o === false) {
notice( t('Item not found.') );
}
}
else {
$o = $this->admin_page_summary();
}
if (argc() > 1) {
$o = $this->sm->call('get');
if ($o === false) {
notice(t('Item not found.'));
}
} else {
$o = $this->admin_page_summary();
}
if (is_ajax()) {
echo $o;
killme();
}
else {
return $o;
}
}
if (is_ajax()) {
echo $o;
killme();
} else {
return $o;
}
}
/**
* @brief Returns content for Admin Summary Page.
*
* @return string HTML from parsed admin_summary.tpl
*/
/**
* @brief Returns content for Admin Summary Page.
*
* @return string HTML from parsed admin_summary.tpl
*/
function admin_page_summary() {
public function admin_page_summary()
{
// list total user accounts, expirations etc.
$accounts = [];
$r = q("SELECT COUNT(CASE WHEN account_id > 0 THEN 1 ELSE NULL END) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires > '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account",
db_utcnow(),
db_utcnow(),
dbesc(NULL_DATE),
intval(ACCOUNT_BLOCKED)
);
if ($r) {
$accounts['total'] = [ 'label' => t('Accounts'), 'val' => $r[0]['total'] ];
$accounts['blocked'] = [ 'label' => t('Blocked accounts'), 'val' => $r[0]['blocked'] ];
$accounts['expired'] = [ 'label' => t('Expired accounts'), 'val' => $r[0]['expired'] ];
$accounts['expiring'] = [ 'label' => t('Expiring accounts'), 'val' => $r[0]['expiring'] ];
}
// list total user accounts, expirations etc.
$accounts = [];
$r = q("SELECT COUNT(CASE WHEN account_id > 0 THEN 1 ELSE NULL END) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires > '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account",
db_utcnow(),
db_utcnow(),
dbesc(NULL_DATE),
intval(ACCOUNT_BLOCKED)
);
if ($r) {
$accounts['total'] = ['label' => t('Accounts'), 'val' => $r[0]['total']];
$accounts['blocked'] = ['label' => t('Blocked accounts'), 'val' => $r[0]['blocked']];
$accounts['expired'] = ['label' => t('Expired accounts'), 'val' => $r[0]['expired']];
$accounts['expiring'] = ['label' => t('Expiring accounts'), 'val' => $r[0]['expiring']];
}
// pending registrations
// pending registrations
$pdg = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ",
intval(ACCOUNT_PENDING)
);
$pdg = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ",
intval(ACCOUNT_PENDING)
);
$pending = (($pdg) ? count($pdg) : 0);
$pending = (($pdg) ? count($pdg) : 0);
// available channels, primary and clones
$channels = [];
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0 and channel_system = 0");
if ($r) {
$channels['total'] = [ 'label' => t('Channels'), 'val' => $r[0]['total'] ];
$channels['main'] = [ 'label' => t('Primary'), 'val' => $r[0]['main'] ];
$channels['clones'] = [ 'label' => t('Clones'), 'val' => $r[0]['clones'] ];
}
// available channels, primary and clones
$channels = [];
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0 and channel_system = 0");
if ($r) {
$channels['total'] = ['label' => t('Channels'), 'val' => $r[0]['total']];
$channels['main'] = ['label' => t('Primary'), 'val' => $r[0]['main']];
$channels['clones'] = ['label' => t('Clones'), 'val' => $r[0]['clones']];
}
// We can do better, but this is a quick queue status
$r = q("SELECT COUNT(outq_delivered) AS total FROM outq WHERE outq_delivered = 0");
$queue = (($r) ? $r[0]['total'] : 0);
$queues = [ 'label' => t('Message queues'), 'queue' => $queue ];
// We can do better, but this is a quick queue status
$r = q("SELECT COUNT(outq_delivered) AS total FROM outq WHERE outq_delivered = 0");
$queue = (($r) ? $r[0]['total'] : 0);
$queues = ['label' => t('Message queues'), 'queue' => $queue];
$plugins = [];
$plugins = [];
if (is_array(App::$plugins) && App::$plugins) {
foreach (App::$plugins as $p) {
if ($p) {
$plugins[] = $p;
}
}
sort($plugins);
}
else {
$plugins = 0;
}
if (is_array(App::$plugins) && App::$plugins) {
foreach (App::$plugins as $p) {
if ($p) {
$plugins[] = $p;
}
}
sort($plugins);
} else {
$plugins = 0;
}
// Could be extended to provide also other alerts to the admin
// Could be extended to provide also other alerts to the admin
$alertmsg = '';
$alertmsg = '';
$upgrade = EMPTY_STR;
$upgrade = EMPTY_STR;
if((! defined('PLATFORM_ARCHITECTURE')) || (PLATFORM_ARCHITECTURE === 'zap')) {
$vrelease = get_repository_version('release');
$vdev = get_repository_version('dev');
$upgrade = ((version_compare(STD_VERSION,$vrelease) < 0) ? t('Your software should be updated') : '');
}
if ((!defined('PLATFORM_ARCHITECTURE')) || (PLATFORM_ARCHITECTURE === 'zap')) {
$vrelease = get_repository_version('release');
$vdev = get_repository_version('dev');
$upgrade = ((version_compare(STD_VERSION, $vrelease) < 0) ? t('Your software should be updated') : '');
}
$t = get_markup_template('admin_summary.tpl');
return replace_macros($t, [
'$title' => t('Administration'),
'$page' => t('Summary'),
'$adminalertmsg' => $alertmsg,
'$queues' => $queues,
'$accounts' => [ t('Registered accounts'), $accounts ],
'$pending' => [ t('Pending registrations'), $pending ],
'$channels' => [ t('Registered channels'), $channels ],
'$plugins' => (($plugins) ? [ t('Active addons'), $plugins ] : EMPTY_STR),
'$version' => [ t('Version'), STD_VERSION ],
'$vmaster' => [ t('Repository version (release)'), $vrelease ],
'$vdev' => [ t('Repository version (dev)'), $vdev ],
'$upgrade' => $upgrade,
'$build' => Config::Get('system', 'db_version')
]);
}
$t = get_markup_template('admin_summary.tpl');
return replace_macros($t, [
'$title' => t('Administration'),
'$page' => t('Summary'),
'$adminalertmsg' => $alertmsg,
'$queues' => $queues,
'$accounts' => [t('Registered accounts'), $accounts],
'$pending' => [t('Pending registrations'), $pending],
'$channels' => [t('Registered channels'), $channels],
'$plugins' => (($plugins) ? [t('Active addons'), $plugins] : EMPTY_STR),
'$version' => [t('Version'), STD_VERSION],
'$vmaster' => [t('Repository version (release)'), $vrelease],
'$vdev' => [t('Repository version (dev)'), $vdev],
'$upgrade' => $upgrade,
'$build' => Config::Get('system', 'db_version')
]);
}
}

View file

@ -3,79 +3,81 @@
namespace Zotlabs\Module\Admin;
class Account_edit
{
class Account_edit {
public function post()
{
function post() {
$account_id = $_REQUEST['aid'];
$account_id = $_REQUEST['aid'];
if (!$account_id)
return;
if(! $account_id)
return;
$pass1 = trim($_REQUEST['pass1']);
$pass2 = trim($_REQUEST['pass2']);
if($pass1 && $pass2 && ($pass1 === $pass2)) {
$salt = random_string(32);
$password_encoded = hash('whirlpool', $salt . $pass1);
$r = q("update account set account_salt = '%s', account_password = '%s',
$pass1 = trim($_REQUEST['pass1']);
$pass2 = trim($_REQUEST['pass2']);
if ($pass1 && $pass2 && ($pass1 === $pass2)) {
$salt = random_string(32);
$password_encoded = hash('whirlpool', $salt . $pass1);
$r = q("update account set account_salt = '%s', account_password = '%s',
account_password_changed = '%s' where account_id = %d",
dbesc($salt),
dbesc($password_encoded),
dbesc(datetime_convert()),
intval($account_id)
);
if($r)
info( sprintf( t('Password changed for account %d.'), $account_id). EOL);
dbesc($salt),
dbesc($password_encoded),
dbesc(datetime_convert()),
intval($account_id)
);
if ($r)
info(sprintf(t('Password changed for account %d.'), $account_id) . EOL);
}
}
$service_class = trim($_REQUEST['service_class']);
$account_language = trim($_REQUEST['account_language']);
$service_class = trim($_REQUEST['service_class']);
$account_language = trim($_REQUEST['account_language']);
$r = q("update account set account_service_class = '%s', account_language = '%s'
$r = q("update account set account_service_class = '%s', account_language = '%s'
where account_id = %d",
dbesc($service_class),
dbesc($account_language),
intval($account_id)
);
dbesc($service_class),
dbesc($account_language),
intval($account_id)
);
if($r)
info( t('Account settings updated.') . EOL);
if ($r)
info(t('Account settings updated.') . EOL);
goaway(z_root() . '/admin/accounts');
}
goaway(z_root() . '/admin/accounts');
}
function get() {
if(argc() > 2)
$account_id = argv(2);
public function get()
{
if (argc() > 2)
$account_id = argv(2);
$x = q("select * from account where account_id = %d limit 1",
intval($account_id)
);
$x = q("select * from account where account_id = %d limit 1",
intval($account_id)
);
if(! $x) {
notice ( t('Account not found.') . EOL);
return '';
}
if (!$x) {
notice(t('Account not found.') . EOL);
return '';
}
$a = replace_macros(get_markup_template('admin_account_edit.tpl'), [
'$account' => $x[0],
'$title' => t('Account Edit'),
'$pass1' => [ 'pass1', t('New Password'), ' ','' ],
'$pass2' => [ 'pass2', t('New Password again'), ' ','' ],
'$account_language' => [ 'account_language' , t('Account language (for emails)'), $x[0]['account_language'], '', language_list() ],
'$service_class' => [ 'service_class', t('Service class'), $x[0]['account_service_class'], '' ],
'$submit' => t('Submit'),
]
);
$a = replace_macros(get_markup_template('admin_account_edit.tpl'), [
'$account' => $x[0],
'$title' => t('Account Edit'),
'$pass1' => ['pass1', t('New Password'), ' ', ''],
'$pass2' => ['pass2', t('New Password again'), ' ', ''],
'$account_language' => ['account_language', t('Account language (for emails)'), $x[0]['account_language'], '', language_list()],
'$service_class' => ['service_class', t('Service class'), $x[0]['account_service_class'], ''],
'$submit' => t('Submit'),
]
);
return $a;
return $a;
}
}
}

View file

@ -4,199 +4,202 @@ namespace Zotlabs\Module\Admin;
use App;
class Accounts {
class Accounts
{
/**
* @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_accounts() will handle this.
*
*/
/**
* @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_accounts() will handle this.
*
*/
function post() {
public function post()
{
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : [] );
$users = ( x($_POST, 'user') ? $_POST['user'] : [] );
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : [] );
$pending = (x($_POST, 'pending') ? $_POST['pending'] : []);
$users = (x($_POST, 'user') ? $_POST['user'] : []);
$blocked = (x($_POST, 'blocked') ? $_POST['blocked'] : []);
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
// account block/unblock button was submitted
if (x($_POST, 'page_accounts_block')) {
for ($i = 0; $i < count($users); $i++) {
// if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag
$op = ($blocked[$i]) ? '& ~' : '| ';
q("UPDATE account SET account_flags = (account_flags $op %d) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($users[$i])
);
}
notice( sprintf( tt("%s account blocked/unblocked", "%s accounts blocked/unblocked", count($users)), count($users)) );
}
// account block/unblock button was submitted
if (x($_POST, 'page_accounts_block')) {
for ($i = 0; $i < count($users); $i++) {
// if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag
$op = ($blocked[$i]) ? '& ~' : '| ';
q("UPDATE account SET account_flags = (account_flags $op %d) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($users[$i])
);
}
notice(sprintf(tt("%s account blocked/unblocked", "%s accounts blocked/unblocked", count($users)), count($users)));
}
// account delete button was submitted
if (x($_POST, 'page_accounts_delete')) {
foreach ($users as $uid){
account_remove($uid, true, false);
}
notice( sprintf( tt("%s account deleted", "%s accounts deleted", count($users)), count($users)) );
}
// account delete button was submitted
if (x($_POST, 'page_accounts_delete')) {
foreach ($users as $uid) {
account_remove($uid, true, false);
}
notice(sprintf(tt("%s account deleted", "%s accounts deleted", count($users)), count($users)));
}
// registration approved button was submitted
if (x($_POST, 'page_accounts_approve')) {
foreach ($pending as $hash) {
account_allow($hash);
}
}
// registration approved button was submitted
if (x($_POST, 'page_accounts_approve')) {
foreach ($pending as $hash) {
account_allow($hash);
}
}
// registration deny button was submitted
if (x($_POST, 'page_accounts_deny')) {
foreach ($pending as $hash) {
account_deny($hash);
}
}
// registration deny button was submitted
if (x($_POST, 'page_accounts_deny')) {
foreach ($pending as $hash) {
account_deny($hash);
}
}
goaway(z_root() . '/admin/accounts' );
}
goaway(z_root() . '/admin/accounts');
}
/**
* @brief Generate accounts admin page and handle single item operations.
*
* 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_accounts_post().
*
* @return string
*/
/**
* @brief Generate accounts admin page and handle single item operations.
*
* 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_accounts_post().
*
* @return string
*/
function get(){
if (argc() > 2) {
$uid = argv(3);
$account = q("SELECT * FROM account WHERE account_id = %d",
intval($uid)
);
public function get()
{
if (argc() > 2) {
$uid = argv(3);
$account = q("SELECT * FROM account WHERE account_id = %d",
intval($uid)
);
if (! $account) {
notice( t('Account not found') . EOL);
goaway(z_root() . '/admin/accounts' );
}
if (!$account) {
notice(t('Account not found') . EOL);
goaway(z_root() . '/admin/accounts');
}
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
switch (argv(2)) {
case 'delete':
// delete user
account_remove($uid,true,false);
switch (argv(2)) {
case 'delete':
// delete user
account_remove($uid, true, false);
notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
break;
case 'block':
q("UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice(sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
break;
case 'block':
q("UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL);
break;
case 'unblock':
q("UPDATE account SET account_flags = ( account_flags & ~ %d ) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice(sprintf(t("Account '%s' blocked"), $account[0]['account_email']) . EOL);
break;
case 'unblock':
q("UPDATE account SET account_flags = ( account_flags & ~ %d ) WHERE account_id = %d",
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL);
break;
}
notice(sprintf(t("Account '%s' unblocked"), $account[0]['account_email']) . EOL);
break;
}
goaway(z_root() . '/admin/accounts' );
}
goaway(z_root() . '/admin/accounts');
}
/* get pending */
$pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) != 0 ",
intval(ACCOUNT_PENDING)
);
/* get pending */
$pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) != 0 ",
intval(ACCOUNT_PENDING)
);
/* get accounts */
/* get accounts */
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
App::set_pager_total($total[0]['total']);
App::set_pager_itemspage(100);
}
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
App::set_pager_total($total[0]['total']);
App::set_pager_itemspage(100);
}
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
$dir = 'asc';
if (array_key_exists('dir',$_REQUEST)) {
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : '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');
$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,
$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 and account_flags != %d order by $key $dir limit %d offset %d ",
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
intval(ACCOUNT_BLOCKED | ACCOUNT_PENDING),
intval(App::$pager['itemspage']),
intval(App::$pager['start'])
);
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
intval(ACCOUNT_BLOCKED | ACCOUNT_PENDING),
intval(App::$pager['itemspage']),
intval(App::$pager['start'])
);
if ($users) {
for($x = 0; $x < count($users); $x ++) {
$channel_arr = explode(' ',$users[$x]['channels']);
if ($channel_arr) {
$linked = [];
foreach ( $channel_arr as $c) {
$linked[] = '<a href="' . z_root() . '/channel/' . $c . '">' . $c . '</a>';
}
$users[$x]['channels'] = implode(' ',$linked);
}
}
}
if ($users) {
for ($x = 0; $x < count($users); $x++) {
$channel_arr = explode(' ', $users[$x]['channels']);
if ($channel_arr) {
$linked = [];
foreach ($channel_arr as $c) {
$linked[] = '<a href="' . z_root() . '/channel/' . $c . '">' . $c . '</a>';
}
$users[$x]['channels'] = implode(' ', $linked);
}
}
}
$t =
$o = replace_macros(get_markup_template('admin_accounts.tpl'), [
'$title' => t('Administration'),
'$page' => t('Accounts'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$h_pending' => t('Registrations waiting for confirm'),
'$th_pending' => array( t('Request date'), t('Email') ),
'$no_pending' => t('No registrations.'),
'$approve' => t('Approve'),
'$deny' => t('Deny'),
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
'$odir' => $odir,
'$base' => $base,
'$h_users' => t('Accounts'),
'$th_users' => [
[ 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_accounts"),
'$baseurl' => z_root(),
'$pending' => $pending,
'$users' => $users,
]);
$t =
$o = replace_macros(get_markup_template('admin_accounts.tpl'), [
'$title' => t('Administration'),
'$page' => t('Accounts'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$h_pending' => t('Registrations waiting for confirm'),
'$th_pending' => array(t('Request date'), t('Email')),
'$no_pending' => t('No registrations.'),
'$approve' => t('Approve'),
'$deny' => t('Deny'),
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
'$odir' => $odir,
'$base' => $base,
'$h_users' => t('Accounts'),
'$th_users' => [
[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_accounts"),
'$baseurl' => z_root(),
'$pending' => $pending,
'$users' => $users,
]);
$o .= paginate($a);
$o .= paginate($a);
return $o;
}
return $o;
}
}

View file

@ -7,476 +7,478 @@ use PHPGit\Exception\GitException;
use Zotlabs\Storage\GitRepo;
use Michelf\MarkdownExtra;
class Addons {
class Addons
{
/**
* @brief
*
*/
function post() {
/**
* @brief
*
*/
public function post()
{
if(argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) {
@include_once("addon/" . argv(2) . "/" . argv(2) . ".php");
if(function_exists(argv(2).'_plugin_admin_post')) {
$func = argv(2) . '_plugin_admin_post';
$func($a);
}
if (argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) {
@include_once("addon/" . argv(2) . "/" . argv(2) . ".php");
if (function_exists(argv(2) . '_plugin_admin_post')) {
$func = argv(2) . '_plugin_admin_post';
$func($a);
}
goaway(z_root() . '/admin/addons/' . argv(2) );
}
elseif(argc() > 2) {
switch(argv(2)) {
case 'updaterepo':
if (array_key_exists('repoName', $_REQUEST)) {
$repoName = $_REQUEST['repoName'];
}
else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
}
else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
$repoDir = 'cache/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
}
if (!is_writable($repoDir)) {
logger('Repo directory not writable to web server: ' . $repoDir);
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
}
$git = new GitRepo('sys', null, false, $repoName, $repoDir);
try {
if ($git->pull()) {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
logger('Error linking addons to /addon');
json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
}
}
}
json_return_and_die(array('message' => 'Repo updated.', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
}
} catch (GitException $e) {
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
}
case 'removerepo':
if (array_key_exists('repoName', $_REQUEST)) {
$repoName = $_REQUEST['repoName'];
} else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
$repoDir = 'cache/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
}
if (!is_writable($repoDir)) {
logger('Repo directory not writable to web server: ' . $repoDir);
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
}
/// @TODO remove directory and unlink /addon/files
if (rrmdir($repoDir)) {
json_return_and_die(array('message' => 'Repo deleted.', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false));
}
case 'installrepo':
if (array_key_exists('repoURL', $_REQUEST)) {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
if (!is_writable($extendDir)) {
logger('Directory not writable to web server: ' . $extendDir);
json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false));
}
$repoName = null;
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
$repoName = $_REQUEST['repoName'];
} else {
$repoName = GitRepo::getRepoNameFromURL($repoURL);
}
if (!$repoName) {
logger('Invalid git repo');
json_return_and_die(array('message' => 'Invalid git repo', 'success' => false));
}
$repoDir = $addonDir . '/' . $repoName;
$tempRepoBaseDir = 'cache/git/sys/temp/';
$tempAddonDir = $tempRepoBaseDir . $repoName;
goaway(z_root() . '/admin/addons/' . argv(2));
} elseif (argc() > 2) {
switch (argv(2)) {
case 'updaterepo':
if (array_key_exists('repoName', $_REQUEST)) {
$repoName = $_REQUEST['repoName'];
} else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
$repoDir = 'cache/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
}
if (!is_writable($repoDir)) {
logger('Repo directory not writable to web server: ' . $repoDir);
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
}
$git = new GitRepo('sys', null, false, $repoName, $repoDir);
try {
if ($git->pull()) {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
logger('Error linking addons to /addon');
json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
}
}
}
json_return_and_die(array('message' => 'Repo updated.', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
}
} catch (GitException $e) {
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
}
case 'removerepo':
if (array_key_exists('repoName', $_REQUEST)) {
$repoName = $_REQUEST['repoName'];
} else {
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
}
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
$repoDir = 'cache/git/sys/extend/addon/' . $repoName;
if (!is_dir($repoDir)) {
logger('Repo directory does not exist: ' . $repoDir);
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
}
if (!is_writable($repoDir)) {
logger('Repo directory not writable to web server: ' . $repoDir);
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
}
/// @TODO remove directory and unlink /addon/files
if (rrmdir($repoDir)) {
json_return_and_die(array('message' => 'Repo deleted.', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false));
}
case 'installrepo':
if (array_key_exists('repoURL', $_REQUEST)) {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
if (!is_writable($extendDir)) {
logger('Directory not writable to web server: ' . $extendDir);
json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false));
}
$repoName = null;
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
$repoName = $_REQUEST['repoName'];
} else {
$repoName = GitRepo::getRepoNameFromURL($repoURL);
}
if (!$repoName) {
logger('Invalid git repo');
json_return_and_die(array('message' => 'Invalid git repo', 'success' => false));
}
$repoDir = $addonDir . '/' . $repoName;
$tempRepoBaseDir = 'cache/git/sys/temp/';
$tempAddonDir = $tempRepoBaseDir . $repoName;
if (!is_writable($addonDir) || !is_writable($tempAddonDir)) {
logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false));
}
rename($tempAddonDir, $repoDir);
if (!is_writable($addonDir) || !is_writable($tempAddonDir)) {
logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false));
}
rename($tempAddonDir, $repoDir);
if (!is_writable(realpath('addon/'))) {
logger('/addon directory not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false));
}
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
logger('Error linking addons to /addon');
json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
}
}
}
$git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir);
$repo = $git->probeRepo();
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
}
case 'addrepo':
if (array_key_exists('repoURL', $_REQUEST)) {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
$tempAddonDir = realpath('cache') . '/git/sys/temp';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
if (!is_dir($tempAddonDir)) {
if (!mkdir($tempAddonDir, 0770, true)) {
logger('Error creating temp plugin repo folder: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false));
}
}
$repoName = null;
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
$repoName = $_REQUEST['repoName'];
} else {
$repoName = GitRepo::getRepoNameFromURL($repoURL);
}
if (!$repoName) {
logger('Invalid git repo');
json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false));
}
$repoDir = $tempAddonDir . '/' . $repoName;
if (!is_writable($tempAddonDir)) {
logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false));
}
// clone the repo if new automatically
$git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir);
if (!is_writable(realpath('addon/'))) {
logger('/addon directory not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false));
}
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
logger('Error linking addons to /addon');
json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
}
}
}
$git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir);
$repo = $git->probeRepo();
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
}
case 'addrepo':
if (array_key_exists('repoURL', $_REQUEST)) {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'cache/git/sys/extend';
$addonDir = $extendDir . '/addon';
$tempAddonDir = realpath('cache') . '/git/sys/temp';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
}
}
if (!is_dir($tempAddonDir)) {
if (!mkdir($tempAddonDir, 0770, true)) {
logger('Error creating temp plugin repo folder: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false));
}
}
$repoName = null;
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
$repoName = $_REQUEST['repoName'];
} else {
$repoName = GitRepo::getRepoNameFromURL($repoURL);
}
if (!$repoName) {
logger('Invalid git repo');
json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false));
}
$repoDir = $tempAddonDir . '/' . $repoName;
if (!is_writable($tempAddonDir)) {
logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir);
json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false));
}
// clone the repo if new automatically
$git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir);
$remotes = $git->git->remote();
$fetchURL = $remotes['origin']['fetch'];
if ($fetchURL !== $git->url) {
if (rrmdir($repoDir)) {
$git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir);
} else {
json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false));
}
}
$repo = $git->probeRepo();
$repo['readme'] = $repo['manifest'] = null;
foreach ($git->git->tree('master') as $object) {
if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) {
$repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash']));
} else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') {
$repo['manifest'] = $git->git->cat->blob($object['hash']);
}
}
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
} else {
json_return_and_die(array('message' => 'No repo URL provided', 'success' => false));
}
break;
default:
break;
}
}
}
$remotes = $git->git->remote();
$fetchURL = $remotes['origin']['fetch'];
if ($fetchURL !== $git->url) {
if (rrmdir($repoDir)) {
$git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir);
} else {
json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false));
}
}
$repo = $git->probeRepo();
$repo['readme'] = $repo['manifest'] = null;
foreach ($git->git->tree('master') as $object) {
if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) {
$repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash']));
} else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') {
$repo['manifest'] = $git->git->cat->blob($object['hash']);
}
}
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
} else {
json_return_and_die(array('message' => 'No repo URL provided', 'success' => false));
}
break;
default:
break;
}
}
}
/**
* @brief Addons admin page.
*
* @return string with parsed HTML
*/
function get() {
/**
* @brief Addons admin page.
*
* @return string with parsed HTML
*/
public function get()
{
/*
* Single plugin
*/
/*
* Single plugin
*/
if (App::$argc == 3){
$plugin = App::$argv[2];
if (!is_file("addon/$plugin/$plugin.php")){
notice( t("Item not found.") );
return '';
}
if (App::$argc == 3) {
$plugin = App::$argv[2];
if (!is_file("addon/$plugin/$plugin.php")) {
notice(t("Item not found."));
return '';
}
$enabled = in_array($plugin, App::$plugins);
$info = get_plugin_info($plugin);
$x = check_plugin_versions($info);
$enabled = in_array($plugin, App::$plugins);
$info = get_plugin_info($plugin);
$x = check_plugin_versions($info);
// disable plugins which are installed but incompatible versions
// disable plugins which are installed but incompatible versions
if($enabled && ! $x) {
$enabled = false;
$idz = array_search($plugin, App::$plugins);
if ($idz !== false) {
unset(App::$plugins[$idz]);
uninstall_plugin($plugin);
set_config("system","addon", implode(", ", App::$plugins));
}
}
$info['disabled'] = 1-intval($x);
if ($enabled && !$x) {
$enabled = false;
$idz = array_search($plugin, App::$plugins);
if ($idz !== false) {
unset(App::$plugins[$idz]);
uninstall_plugin($plugin);
set_config("system", "addon", implode(", ", App::$plugins));
}
}
$info['disabled'] = 1 - intval($x);
if (x($_GET,"a") && $_GET['a']=="t"){
check_form_security_token_redirectOnErr('/admin/addons', 'admin_addons', 't');
$pinstalled = false;
// Toggle plugin status
$idx = array_search($plugin, App::$plugins);
if ($idx !== false){
unset(App::$plugins[$idx]);
uninstall_plugin($plugin);
$pinstalled = false;
info( sprintf( t("Plugin %s disabled."), $plugin ) );
} else {
App::$plugins[] = $plugin;
install_plugin($plugin);
$pinstalled = true;
info( sprintf( t("Plugin %s enabled."), $plugin ) );
}
set_config("system","addon", implode(", ", App::$plugins));
if (x($_GET, "a") && $_GET['a'] == "t") {
check_form_security_token_redirectOnErr('/admin/addons', 'admin_addons', 't');
$pinstalled = false;
// Toggle plugin status
$idx = array_search($plugin, App::$plugins);
if ($idx !== false) {
unset(App::$plugins[$idx]);
uninstall_plugin($plugin);
$pinstalled = false;
info(sprintf(t("Plugin %s disabled."), $plugin));
} else {
App::$plugins[] = $plugin;
install_plugin($plugin);
$pinstalled = true;
info(sprintf(t("Plugin %s enabled."), $plugin));
}
set_config("system", "addon", implode(", ", App::$plugins));
if($pinstalled) {
@require_once("addon/$plugin/$plugin.php");
if(function_exists($plugin.'_plugin_admin'))
goaway(z_root() . '/admin/addons/' . $plugin);
}
goaway(z_root() . '/admin/addons' );
}
if ($pinstalled) {
@require_once("addon/$plugin/$plugin.php");
if (function_exists($plugin . '_plugin_admin'))
goaway(z_root() . '/admin/addons/' . $plugin);
}
goaway(z_root() . '/admin/addons');
}
// display plugin details
// display plugin details
if (in_array($plugin, App::$plugins)){
$status = 'on';
$action = t('Disable');
} else {
$status = 'off';
$action = t('Enable');
}
if (in_array($plugin, App::$plugins)) {
$status = 'on';
$action = t('Disable');
} else {
$status = 'off';
$action = t('Enable');
}
$readme = null;
if (is_file("addon/$plugin/README.md")){
$readme = file_get_contents("addon/$plugin/README.md");
$readme = MarkdownExtra::defaultTransform($readme);
} else if (is_file("addon/$plugin/README")){
$readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
}
$readme = null;
if (is_file("addon/$plugin/README.md")) {
$readme = file_get_contents("addon/$plugin/README.md");
$readme = MarkdownExtra::defaultTransform($readme);
} else if (is_file("addon/$plugin/README")) {
$readme = "<pre>" . file_get_contents("addon/$plugin/README") . "</pre>";
}
$admin_form = '';
$admin_form = '';
$r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1",
dbesc($plugin)
);
$r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1",
dbesc($plugin)
);
if($r) {
@require_once("addon/$plugin/$plugin.php");
if(function_exists($plugin.'_plugin_admin')) {
$func = $plugin.'_plugin_admin';
$func($a, $admin_form);
}
}
if ($r) {
@require_once("addon/$plugin/$plugin.php");
if (function_exists($plugin . '_plugin_admin')) {
$func = $plugin . '_plugin_admin';
$func($a, $admin_form);
}
}
$t = get_markup_template('admin_plugins_details.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Addons'),
'$toggle' => t('Toggle'),
'$settings' => t('Settings'),
'$baseurl' => z_root(),
$t = get_markup_template('admin_plugins_details.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Addons'),
'$toggle' => t('Toggle'),
'$settings' => t('Settings'),
'$baseurl' => z_root(),
'$plugin' => $plugin,
'$status' => $status,
'$action' => $action,
'$info' => $info,
'$str_author' => t('Author: '),
'$str_maintainer' => t('Maintainer: '),
'$str_minversion' => t('Minimum project version: '),
'$str_maxversion' => t('Maximum project version: '),
'$str_minphpversion' => t('Minimum PHP version: '),
'$str_serverroles' => t('Compatible Server Roles: '),
'$str_requires' => t('Requires: '),
'$disabled' => t('Disabled - version incompatibility'),
'$plugin' => $plugin,
'$status' => $status,
'$action' => $action,
'$info' => $info,
'$str_author' => t('Author: '),
'$str_maintainer' => t('Maintainer: '),
'$str_minversion' => t('Minimum project version: '),
'$str_maxversion' => t('Maximum project version: '),
'$str_minphpversion' => t('Minimum PHP version: '),
'$str_serverroles' => t('Compatible Server Roles: '),
'$str_requires' => t('Requires: '),
'$disabled' => t('Disabled - version incompatibility'),
'$admin_form' => $admin_form,
'$function' => 'addons',
'$screenshot' => '',
'$readme' => $readme,
'$admin_form' => $admin_form,
'$function' => 'addons',
'$screenshot' => '',
'$readme' => $readme,
'$form_security_token' => get_form_security_token('admin_addons'),
));
}
'$form_security_token' => get_form_security_token('admin_addons'),
));
}
/*
* List plugins
*/
$plugins = [];
$files = glob('addon/*/');
if($files) {
foreach($files as $file) {
if ($file === 'addon/vendor/') {
continue;
}
if (is_dir($file)){
list($tmp, $id) = array_map('trim', explode('/', $file));
$info = get_plugin_info($id);
$enabled = in_array($id, App::$plugins);
$x = check_plugin_versions($info);
/*
* List plugins
*/
$plugins = [];
$files = glob('addon/*/');
if ($files) {
foreach ($files as $file) {
if ($file === 'addon/vendor/') {
continue;
}
if (is_dir($file)) {
list($tmp, $id) = array_map('trim', explode('/', $file));
$info = get_plugin_info($id);
$enabled = in_array($id, App::$plugins);
$x = check_plugin_versions($info);
// disable plugins which are installed but incompatible versions
// disable plugins which are installed but incompatible versions
if($enabled && ! $x) {
$enabled = false;
$idz = array_search($id, App::$plugins);
if ($idz !== false) {
unset(App::$plugins[$idz]);
uninstall_plugin($id);
set_config("system","addon", implode(", ", App::$plugins));
}
}
$info['disabled'] = 1-intval($x);
if ($enabled && !$x) {
$enabled = false;
$idz = array_search($id, App::$plugins);
if ($idz !== false) {
unset(App::$plugins[$idz]);
uninstall_plugin($id);
set_config("system", "addon", implode(", ", App::$plugins));
}
}
$info['disabled'] = 1 - intval($x);
$plugins[] = array( $id, (($enabled)?"on":"off") , $info);
}
}
}
$plugins[] = array($id, (($enabled) ? "on" : "off"), $info);
}
}
}
usort($plugins,'self::plugin_sort');
usort($plugins, 'self::plugin_sort');
$allowManageRepos = false;
if(is_writable('extend/addon') && is_writable('cache')) {
$allowManageRepos = true;
}
$allowManageRepos = false;
if (is_writable('extend/addon') && is_writable('cache')) {
$allowManageRepos = true;
}
$admin_plugins_add_repo_form= replace_macros(
get_markup_template('admin_plugins_addrepo.tpl'), array(
'$post' => 'admin/addons/addrepo',
'$desc' => t('Enter the public git repository URL of the addon repo.'),
'$repoURL' => array('repoURL', t('Addon repo git URL'), '', ''),
'$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')),
'$submit' => t('Download Addon Repo')
)
);
$newRepoModalID = random_string(3);
$newRepoModal = replace_macros(
get_markup_template('generic_modal.tpl'), array(
'$id' => $newRepoModalID,
'$title' => t('Install new repo'),
'$ok' => t('Install'),
'$cancel' => t('Cancel')
)
);
$admin_plugins_add_repo_form = replace_macros(
get_markup_template('admin_plugins_addrepo.tpl'), array(
'$post' => 'admin/addons/addrepo',
'$desc' => t('Enter the public git repository URL of the addon repo.'),
'$repoURL' => array('repoURL', t('Addon repo git URL'), '', ''),
'$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')),
'$submit' => t('Download Addon Repo')
)
);
$newRepoModalID = random_string(3);
$newRepoModal = replace_macros(
get_markup_template('generic_modal.tpl'), array(
'$id' => $newRepoModalID,
'$title' => t('Install new repo'),
'$ok' => t('Install'),
'$cancel' => t('Cancel')
)
);
$reponames = $this->listAddonRepos();
$addonrepos = [];
foreach($reponames as $repo) {
$addonrepos[] = array('name' => $repo, 'description' => '');
/// @TODO Parse repo info to provide more information about repos
}
$reponames = $this->listAddonRepos();
$addonrepos = [];
foreach ($reponames as $repo) {
$addonrepos[] = array('name' => $repo, 'description' => '');
/// @TODO Parse repo info to provide more information about repos
}
$t = get_markup_template('admin_plugins.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Addons'),
'$submit' => t('Submit'),
'$baseurl' => z_root(),
'$function' => 'addons',
'$plugins' => $plugins,
'$disabled' => t('Disabled - version incompatibility'),
'$form_security_token' => get_form_security_token('admin_addons'),
'$allowManageRepos' => $allowManageRepos,
'$managerepos' => t('Manage Repos'),
'$installedtitle' => t('Installed Addon Repositories'),
'$addnewrepotitle' => t('Install a New Addon Repository'),
'$expandform' => false,
'$form' => $admin_plugins_add_repo_form,
'$newRepoModal' => $newRepoModal,
'$newRepoModalID' => $newRepoModalID,
'$addonrepos' => $addonrepos,
'$repoUpdateButton' => t('Update'),
'$repoBranchButton' => t('Switch branch'),
'$repoRemoveButton' => t('Remove')
));
}
$t = get_markup_template('admin_plugins.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Addons'),
'$submit' => t('Submit'),
'$baseurl' => z_root(),
'$function' => 'addons',
'$plugins' => $plugins,
'$disabled' => t('Disabled - version incompatibility'),
'$form_security_token' => get_form_security_token('admin_addons'),
'$allowManageRepos' => $allowManageRepos,
'$managerepos' => t('Manage Repos'),
'$installedtitle' => t('Installed Addon Repositories'),
'$addnewrepotitle' => t('Install a New Addon Repository'),
'$expandform' => false,
'$form' => $admin_plugins_add_repo_form,
'$newRepoModal' => $newRepoModal,
'$newRepoModalID' => $newRepoModalID,
'$addonrepos' => $addonrepos,
'$repoUpdateButton' => t('Update'),
'$repoBranchButton' => t('Switch branch'),
'$repoRemoveButton' => t('Remove')
));
}
function listAddonRepos() {
$addonrepos = [];
$addonDir = 'extend/addon/';
if(is_dir($addonDir)) {
if ($handle = opendir($addonDir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$addonrepos[] = $entry;
}
}
closedir($handle);
}
}
return $addonrepos;
}
public function listAddonRepos()
{
$addonrepos = [];
$addonDir = 'extend/addon/';
if (is_dir($addonDir)) {
if ($handle = opendir($addonDir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$addonrepos[] = $entry;
}
}
closedir($handle);
}
}
return $addonrepos;
}
static public function plugin_sort($a,$b) {
return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name'])));
}
public static function plugin_sort($a, $b)
{
return (strcmp(strtolower($a[2]['name']), strtolower($b[2]['name'])));
}
}

View file

@ -9,178 +9,183 @@ use Zotlabs\Daemon\Run;
* @brief Admin Module for Channels.
*
*/
class Channels
{
class Channels {
/**
* @brief Handle POST actions on channels admin page.
*
*/
public function post()
{
/**
* @brief Handle POST actions on channels admin page.
*
*/
function post() {
$channels = (x($_POST, 'channel') ? $_POST['channel'] : array());
$channels = ( x($_POST, 'channel') ? $_POST['channel'] : Array() );
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels');
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels');
$xor = db_getfunc('^');
$xor = db_getfunc('^');
if (x($_POST, 'page_channels_block')) {
foreach ($channels as $uid) {
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
intval(PAGE_CENSORED),
intval($uid)
);
Run::Summon(['Directory', $uid, 'nopush']);
}
notice(sprintf(tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)));
}
if (x($_POST, 'page_channels_code')) {
foreach ($channels as $uid) {
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
intval(PAGE_ALLOWCODE),
intval($uid)
);
}
notice(sprintf(tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)));
}
if (x($_POST, 'page_channels_delete')) {
foreach ($channels as $uid) {
channel_remove($uid, true);
}
notice(sprintf(tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)));
}
if(x($_POST, 'page_channels_block')) {
foreach($channels as $uid) {
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
intval(PAGE_CENSORED),
intval( $uid )
);
Run::Summon( [ 'Directory', $uid, 'nopush' ] );
}
notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) );
}
if(x($_POST, 'page_channels_code')) {
foreach($channels as $uid) {
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
intval(PAGE_ALLOWCODE),
intval( $uid )
);
}
notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
}
if(x($_POST, 'page_channels_delete')) {
foreach($channels as $uid) {
channel_remove($uid, true);
}
notice( sprintf( tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)) );
}
goaway(z_root() . '/admin/channels');
}
goaway(z_root() . '/admin/channels' );
}
/**
* @brief Generate channels admin page and handle single item operations.
*
* @return string with parsed HTML
*/
public function get()
{
if (argc() > 2) {
$uid = argv(3);
$channel = q("SELECT * FROM channel WHERE channel_id = %d",
intval($uid)
);
/**
* @brief Generate channels admin page and handle single item operations.
*
* @return string with parsed HTML
*/
function get() {
if(argc() > 2) {
$uid = argv(3);
$channel = q("SELECT * FROM channel WHERE channel_id = %d",
intval($uid)
);
if (!$channel) {
notice(t('Channel not found') . EOL);
goaway(z_root() . '/admin/channels');
}
if(! $channel) {
notice( t('Channel not found') . EOL);
goaway(z_root() . '/admin/channels' );
}
switch (argv(2)) {
case "delete":
{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
// delete channel
channel_remove($uid, true);
switch(argv(2)) {
case "delete":{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
// delete channel
channel_remove($uid,true);
notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL);
}
notice(sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL);
}
break;
case "block":{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
$pflags = $channel[0]['channel_pageflags'] ^ PAGE_CENSORED;
q("UPDATE channel SET channel_pageflags = %d where channel_id = %d",
intval($pflags),
intval( $uid )
);
Run::Summon( [ 'Directory', $uid, 'nopush' ]);
case "block":
{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
$pflags = $channel[0]['channel_pageflags'] ^ PAGE_CENSORED;
q("UPDATE channel SET channel_pageflags = %d where channel_id = %d",
intval($pflags),
intval($uid)
);
Run::Summon(['Directory', $uid, 'nopush']);
notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL);
}
notice(sprintf((($pflags & PAGE_CENSORED) ? t("Channel '%s' censored") : t("Channel '%s' uncensored")), $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')') . EOL);
}
break;
case "code":{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
$pflags = $channel[0]['channel_pageflags'] ^ PAGE_ALLOWCODE;
q("UPDATE channel SET channel_pageflags = %d where channel_id = %d",
intval($pflags),
intval( $uid )
);
case "code":
{
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
$pflags = $channel[0]['channel_pageflags'] ^ PAGE_ALLOWCODE;
q("UPDATE channel SET channel_pageflags = %d where channel_id = %d",
intval($pflags),
intval($uid)
);
notice( sprintf( (($pflags & PAGE_ALLOWCODE) ? t("Channel '%s' code allowed"): t("Channel '%s' code disallowed")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL);
}
notice(sprintf((($pflags & PAGE_ALLOWCODE) ? t("Channel '%s' code allowed") : t("Channel '%s' code disallowed")), $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')') . EOL);
}
break;
default:
break;
}
goaway(z_root() . '/admin/channels' );
}
default:
break;
}
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');
$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');
$base = z_root() . '/admin/channels?f=';
$odir = (($dir === 'asc') ? '0' : '1');
/* get channels */
/* get channels */
$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0");
if($total) {
App::set_pager_total($total[0]['total']);
App::set_pager_itemspage(100);
}
$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0");
if ($total) {
App::set_pager_total($total[0]['total']);
App::set_pager_itemspage(100);
}
$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'])
);
$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'])
);
if($channels) {
for($x = 0; $x < count($channels); $x ++) {
if($channels[$x]['channel_pageflags'] & PAGE_CENSORED)
$channels[$x]['blocked'] = true;
else
$channels[$x]['blocked'] = false;
if ($channels) {
for ($x = 0; $x < count($channels); $x++) {
if ($channels[$x]['channel_pageflags'] & PAGE_CENSORED)
$channels[$x]['blocked'] = true;
else
$channels[$x]['blocked'] = false;
if($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE)
$channels[$x]['allowcode'] = true;
else
$channels[$x]['allowcode'] = false;
if ($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE)
$channels[$x]['allowcode'] = true;
else
$channels[$x]['allowcode'] = false;
$channels[$x]['channel_link'] = z_root() . '/channel/' . $channels[$x]['channel_address'];
}
}
$channels[$x]['channel_link'] = z_root() . '/channel/' . $channels[$x]['channel_address'];
}
}
call_hooks('admin_channels',$channels);
call_hooks('admin_channels', $channels);
$o = replace_macros(get_markup_template('admin_channels.tpl'), [
// strings //
'$title' => t('Administration'),
'$page' => t('Channels'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$delete' => t('Delete'),
'$block' => t('Censor'),
'$unblock' => t('Uncensor'),
'$code' => t('Allow Code'),
'$uncode' => t('Disallow Code'),
'$h_channels' => t('Channel'),
'$base' => $base,
'$odir' => $odir,
'$th_channels' => array(
[ t('UID'), 'channel_id' ],
[ t('Name'), 'channel_name' ],
[ t('Address'), 'channel_address' ]),
$o = replace_macros(get_markup_template('admin_channels.tpl'), [
// strings //
'$title' => t('Administration'),
'$page' => t('Channels'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$delete' => t('Delete'),
'$block' => t('Censor'),
'$unblock' => t('Uncensor'),
'$code' => t('Allow Code'),
'$uncode' => t('Disallow Code'),
'$h_channels' => t('Channel'),
'$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?'),
'$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?'),
'$form_security_token' => get_form_security_token('admin_channels'),
'$form_security_token' => get_form_security_token('admin_channels'),
// values //
'$baseurl' => z_root(),
'$channels' => $channels,
]);
$o .= paginate($a);
// values //
'$baseurl' => z_root(),
'$channels' => $channels,
]);
$o .= paginate($a);
return $o;
}
return $o;
}
}

View file

@ -25,422 +25,419 @@ require_once('include/photos.php');
* @return void
*
*/
class Cover_photo
{
public function init()
{
if (!is_site_admin()) {
return;
}
$channel = get_sys_channel();
Libprofile::load($channel['channel_address']);
}
/**
* @brief Evaluate posted values
*
* @return void
*
*/
public function post()
{
if (!is_site_admin()) {
return;
}
$channel = get_sys_channel();
check_form_security_token_redirectOnErr('/admin/cover_photo', 'cover_photo');
if ((array_key_exists('cropfinal', $_POST)) && ($_POST['cropfinal'] == 1)) {
// phase 2 - we have finished cropping
if (argc() != 3) {
notice(t('Image uploaded but image cropping failed.') . EOL);
return;
}
$image_id = argv(2);
if (substr($image_id, -2, 1) == '-') {
$scale = substr($image_id, -1, 1);
$image_id = substr($image_id, 0, -2);
}
$srcX = intval($_POST['xstart']);
$srcY = intval($_POST['ystart']);
$srcW = intval($_POST['xfinal']) - $srcX;
$srcH = intval($_POST['yfinal']) - $srcY;
$r = q("select gender from profile where uid = %d and is_default = 1 limit 1",
intval($channel['channel_id'])
);
if ($r) {
$profile = array_shift($r);
}
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale > 0 order by imgscale asc LIMIT 1",
dbesc($image_id),
intval($channel['channel_id'])
);
if ($r) {
$max_thumb = intval(get_config('system', 'max_thumbnail', 1600));
$iscaled = false;
if (intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) {
$imagick_path = get_config('system', 'imagick_convert_path');
if ($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) {
$fname = dbunescbin($r[0]['content']);
$tmp_name = $fname . '-001';
$newsize = photo_calculate_scale(array_merge(getimagesize($fname), ['max' => $max_thumb]));
$cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $fname) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name);
// logger('imagick thumbnail command: ' . $cmd);
for ($x = 0; $x < 4; $x++) {
exec($cmd);
if (file_exists($tmp_name)) {
break;
}
}
if (file_exists($tmp_name)) {
$base_image = $r[0];
$gis = getimagesize($tmp_name);
logger('gis: ' . print_r($gis, true));
$base_image['width'] = $gis[0];
$base_image['height'] = $gis[1];
$base_image['content'] = @file_get_contents($tmp_name);
$iscaled = true;
@unlink($tmp_name);
}
}
}
if (!$iscaled) {
$base_image = $r[0];
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
}
$im = photo_factory($base_image['content'], $base_image['mimetype']);
if ($im->is_valid()) {
// We are scaling and cropping the relative pixel locations to the original photo instead of the
// scaled photo we operated on.
// First load the scaled photo to check its size. (Should probably pass this in the post form and save
// a query.)
$g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3",
dbesc($image_id),
intval($channel['channel_id'])
);
$scaled_width = $g[0]['width'];
$scaled_height = $g[0]['height'];
if ((!$scaled_width) || (!$scaled_height)) {
logger('potential divide by zero scaling cover photo');
return;
}
// unset all other cover photos
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_COVER),
intval($channel['channel_id'])
);
$orig_srcx = ($base_image['width'] / $scaled_width) * $srcX;
$orig_srcy = ($base_image['height'] / $scaled_height) * $srcY;
$orig_srcw = ($srcW / $scaled_width) * $base_image['width'];
$orig_srch = ($srcH / $scaled_height) * $base_image['height'];
$im->cropImageRect(1200, 435, $orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
$aid = get_account_id();
$p = [
'aid' => 0,
'uid' => $channel['channel_id'],
'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'],
'album' => t('Cover Photos'),
'os_path' => $base_image['os_path'],
'display_path' => $base_image['display_path'],
'created' => $base_image['created'],
'edited' => $base_image['edited']
];
$p['imgscale'] = 7;
$p['photo_usage'] = PHOTO_COVER;
$r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
$im->doScaleImage(850, 310);
$p['imgscale'] = 8;
$r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850);
$im->doScaleImage(425, 160);
$p['imgscale'] = 9;
$r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425);
if ($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice(t('Image resize failed.') . EOL);
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ",
dbesc($base_image['resource_id']),
intval($channel['channel_id'])
);
return;
}
} else
notice(t('Unable to process image') . EOL);
}
goaway(z_root() . '/admin');
}
$hash = photo_new_resource();
$smallest = 0;
$matches = [];
$partial = false;
if (array_key_exists('HTTP_CONTENT_RANGE', $_SERVER)) {
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/', $_SERVER['HTTP_CONTENT_RANGE'], $matches);
if ($pm) {
logger('Content-Range: ' . print_r($matches, true));
$partial = true;
}
}
if ($partial) {
$x = save_chunk($channel, $matches[1], $matches[2], $matches[3]);
class Cover_photo {
function init() {
if (! is_site_admin()) {
return;
}
$channel = get_sys_channel();
Libprofile::load($channel['channel_address']);
}
/**
* @brief Evaluate posted values
*
* @return void
*
*/
function post() {
if (! is_site_admin()) {
return;
}
if ($x['partial']) {
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
json_return_and_die($x);
} else {
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
$channel = get_sys_channel();
check_form_security_token_redirectOnErr('/admin/cover_photo', 'cover_photo');
if ((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
// phase 2 - we have finished cropping
if (argc() != 3) {
notice( t('Image uploaded but image cropping failed.') . EOL );
return;
}
$_FILES['userfile'] = [
'name' => $x['name'],
'type' => $x['type'],
'tmp_name' => $x['tmp_name'],
'error' => $x['error'],
'size' => $x['size']
];
}
} else {
if (!array_key_exists('userfile', $_FILES)) {
$_FILES['userfile'] = [
'name' => $_FILES['files']['name'],
'type' => $_FILES['files']['type'],
'tmp_name' => $_FILES['files']['tmp_name'],
'error' => $_FILES['files']['error'],
'size' => $_FILES['files']['size']
];
}
}
$image_id = argv(2);
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Cover Photos'), 'hash' => $hash));
if (substr($image_id,-2,1) == '-') {
$scale = substr($image_id,-1,1);
$image_id = substr($image_id,0,-2);
}
$srcX = intval($_POST['xstart']);
$srcY = intval($_POST['ystart']);
$srcW = intval($_POST['xfinal']) - $srcX;
$srcH = intval($_POST['yfinal']) - $srcY;
$r = q("select gender from profile where uid = %d and is_default = 1 limit 1",
intval($channel['channel_id'])
);
if ($r) {
$profile = array_shift($r);
}
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale > 0 order by imgscale asc LIMIT 1",
dbesc($image_id),
intval($channel['channel_id'])
);
if ($r) {
logger('attach_store: ' . print_r($res, true), LOGGER_DEBUG);
$max_thumb = intval(get_config('system','max_thumbnail',1600));
$iscaled = false;
if (intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) {
$imagick_path = get_config('system','imagick_convert_path');
if ($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) {
$fname = dbunescbin($r[0]['content']);
$tmp_name = $fname . '-001';
$newsize = photo_calculate_scale(array_merge(getimagesize($fname),['max' => $max_thumb]));
$cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $fname) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name);
// logger('imagick thumbnail command: ' . $cmd);
for ($x = 0; $x < 4; $x ++) {
exec($cmd);
if (file_exists($tmp_name)) {
break;
}
}
if (file_exists($tmp_name)) {
$base_image = $r[0];
$gis = getimagesize($tmp_name);
logger('gis: ' . print_r($gis,true));
$base_image['width'] = $gis[0];
$base_image['height'] = $gis[1];
$base_image['content'] = @file_get_contents($tmp_name);
$iscaled = true;
@unlink($tmp_name);
}
}
}
if (! $iscaled) {
$base_image = $r[0];
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
}
$im = photo_factory($base_image['content'], $base_image['mimetype']);
if ($im->is_valid()) {
// We are scaling and cropping the relative pixel locations to the original photo instead of the
// scaled photo we operated on.
// First load the scaled photo to check its size. (Should probably pass this in the post form and save
// a query.)
$g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3",
dbesc($image_id),
intval($channel['channel_id'])
);
$scaled_width = $g[0]['width'];
$scaled_height = $g[0]['height'];
if ((! $scaled_width) || (! $scaled_height)) {
logger('potential divide by zero scaling cover photo');
return;
}
// unset all other cover photos
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_COVER),
intval($channel['channel_id'])
);
$orig_srcx = ( $base_image['width'] / $scaled_width ) * $srcX;
$orig_srcy = ( $base_image['height'] / $scaled_height ) * $srcY;
$orig_srcw = ( $srcW / $scaled_width ) * $base_image['width'];
$orig_srch = ( $srcH / $scaled_height ) * $base_image['height'];
$im->cropImageRect(1200,435,$orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
$aid = get_account_id();
$p = [
'aid' => 0,
'uid' => $channel['channel_id'],
'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'],
'album' => t('Cover Photos'),
'os_path' => $base_image['os_path'],
'display_path' => $base_image['display_path'],
'created' => $base_image['created'],
'edited' => $base_image['edited']
];
$p['imgscale'] = 7;
$p['photo_usage'] = PHOTO_COVER;
$r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
$im->doScaleImage(850,310);
$p['imgscale'] = 8;
$r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850);
$im->doScaleImage(425,160);
$p['imgscale'] = 9;
$r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425);
if ($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ",
dbesc($base_image['resource_id']),
intval($channel['channel_id'])
);
return;
}
}
else
notice( t('Unable to process image') . EOL);
}
goaway(z_root() . '/admin');
}
$hash = photo_new_resource();
$smallest = 0;
$matches = [];
$partial = false;
if (array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
if ($pm) {
logger('Content-Range: ' . print_r($matches,true));
$partial = true;
}
}
json_return_and_die(['message' => $hash]);
if ($partial) {
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
}
if ($x['partial']) {
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
json_return_and_die($x);
}
else {
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
$_FILES['userfile'] = [
'name' => $x['name'],
'type' => $x['type'],
'tmp_name' => $x['tmp_name'],
'error' => $x['error'],
'size' => $x['size']
];
}
}
else {
if (! array_key_exists('userfile',$_FILES)) {
$_FILES['userfile'] = [
'name' => $_FILES['files']['name'],
'type' => $_FILES['files']['type'],
'tmp_name' => $_FILES['files']['tmp_name'],
'error' => $_FILES['files']['error'],
'size' => $_FILES['files']['size']
];
}
}
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Cover Photos'), 'hash' => $hash));
logger('attach_store: ' . print_r($res,true),LOGGER_DEBUG);
/**
* @brief Generate content of profile-photo view
*
* @return string
*
*/
json_return_and_die([ 'message' => $hash ]);
}
/**
* @brief Generate content of profile-photo view
*
* @return string
*
*/
public function get()
{
function get() {
if (!is_site_admin()) {
notice(t('Permission denied.') . EOL);
return;
}
if (! is_site_admin()) {
notice( t('Permission denied.') . EOL );
return;
}
$channel = get_sys_channel();
$channel = get_sys_channel();
$newuser = false;
$newuser = false;
if (argc() == 3 && argv(1) === 'new')
$newuser = true;
if (argv(2) === 'reset') {
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_COVER),
intval($channel['channel_id'])
);
}
if (argv(2) === 'use') {
if (argc() < 4) {
notice( t('Permission denied.') . EOL );
return;
}
if (argc() == 3 && argv(1) === 'new')
$newuser = true;
if (argv(2) === 'reset') {
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_COVER),
intval($channel['channel_id'])
);
}
if (argv(2) === 'use') {
if (argc() < 4) {
notice(t('Permission denied.') . EOL);
return;
}
// check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
$resource_id = argv(3);
$resource_id = argv(3);
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC",
intval($channel['channel_id']),
dbesc($resource_id)
);
if (! $r) {
notice( t('Photo not available.') . EOL );
return;
}
$havescale = false;
foreach ($r as $rr) {
if ($rr['imgscale'] == 7) {
$havescale = true;
}
}
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC",
intval($channel['channel_id']),
dbesc($resource_id)
);
if (!$r) {
notice(t('Photo not available.') . EOL);
return;
}
$havescale = false;
foreach ($r as $rr) {
if ($rr['imgscale'] == 7) {
$havescale = true;
}
}
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval($channel['channel_id'])
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval($channel['channel_id'])
);
if (! $r) {
notice( t('Photo not available.') . EOL );
return;
}
);
if (!$r) {
notice(t('Photo not available.') . EOL);
return;
}
if (intval($r[0]['os_storage'])) {
$data = @file_get_contents(dbunescbin($r[0]['content']));
}
else {
$data = dbunescbin($r[0]['content']);
}
if (intval($r[0]['os_storage'])) {
$data = @file_get_contents(dbunescbin($r[0]['content']));
} else {
$data = dbunescbin($r[0]['content']);
}
$ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if ($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0",
dbesc($r[0]['resource_id']),
intval($channel['channel_id'])
);
$ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if ($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0",
dbesc($r[0]['resource_id']),
intval($channel['channel_id'])
);
if ($i) {
$hash = $i[0]['resource_id'];
foreach ($i as $ii) {
$smallest = intval($ii['imgscale']);
}
}
}
if ($i) {
$hash = $i[0]['resource_id'];
foreach ($i as $ii) {
$smallest = intval($ii['imgscale']);
}
}
}
$this->cover_photo_crop_ui_head($ph, $hash, $smallest);
}
$this->cover_photo_crop_ui_head($ph, $hash, $smallest);
}
if(! array_key_exists('imagecrop',App::$data)) {
if (!array_key_exists('imagecrop', App::$data)) {
$o .= replace_macros(get_markup_template('admin_cover_photo.tpl'), [
'$user' => $channel['channel_address'],
'$channel_id' => $channel['channel_id'],
'$info' => t('Your cover photo may be visible to anybody on the internet'),
'$existing' => get_cover_photo($channel['channel_id'],'array',PHOTO_RES_COVER_850),
'$lbl_upfile' => t('Upload File:'),
'$lbl_profiles' => t('Select a profile:'),
'$title' => t('Change Cover Photo'),
'$submit' => t('Upload'),
'$profiles' => $profiles,
'$embedPhotos' => t('Use a photo from your albums'),
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
'$embedPhotosModalCancel' => t('Cancel'),
'$embedPhotosModalOK' => t('OK'),
'$modalchooseimages' => t('Choose images to embed'),
'$modalchoosealbum' => t('Choose an album'),
'$modaldiffalbum' => t('Choose a different album'),
'$modalerrorlist' => t('Error getting album list'),
'$modalerrorlink' => t('Error getting photo link'),
'$modalerroralbum' => t('Error getting album'),
'$form_security_token' => get_form_security_token("cover_photo"),
'$select' => t('Select previously uploaded photo'),
$o .= replace_macros(get_markup_template('admin_cover_photo.tpl'), [
'$user' => $channel['channel_address'],
'$channel_id' => $channel['channel_id'],
'$info' => t('Your cover photo may be visible to anybody on the internet'),
'$existing' => get_cover_photo($channel['channel_id'], 'array', PHOTO_RES_COVER_850),
'$lbl_upfile' => t('Upload File:'),
'$lbl_profiles' => t('Select a profile:'),
'$title' => t('Change Cover Photo'),
'$submit' => t('Upload'),
'$profiles' => $profiles,
'$embedPhotos' => t('Use a photo from your albums'),
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
'$embedPhotosModalCancel' => t('Cancel'),
'$embedPhotosModalOK' => t('OK'),
'$modalchooseimages' => t('Choose images to embed'),
'$modalchoosealbum' => t('Choose an album'),
'$modaldiffalbum' => t('Choose a different album'),
'$modalerrorlist' => t('Error getting album list'),
'$modalerrorlink' => t('Error getting photo link'),
'$modalerroralbum' => t('Error getting album'),
'$form_security_token' => get_form_security_token("cover_photo"),
'$select' => t('Select previously uploaded photo'),
]);
]);
call_hooks('cover_photo_content_end', $o);
call_hooks('cover_photo_content_end', $o);
return $o;
}
else {
$filename = App::$data['imagecrop'] . '-3';
$resolution = 3;
return $o;
} else {
$filename = App::$data['imagecrop'] . '-3';
$resolution = 3;
$o .= replace_macros(get_markup_template('admin_cropcover.tpl'), [
'$filename' => $filename,
'$profile' => intval($_REQUEST['profile']),
'$resource' => App::$data['imagecrop'] . '-3',
'$image_url' => z_root() . '/photo/' . $filename,
'$title' => t('Crop Image'),
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
'$form_security_token' => get_form_security_token("cover_photo"),
'$done' => t('Done Editing')
]);
return $o;
}
}
$o .= replace_macros(get_markup_template('admin_cropcover.tpl'), [
'$filename' => $filename,
'$profile' => intval($_REQUEST['profile']),
'$resource' => App::$data['imagecrop'] . '-3',
'$image_url' => z_root() . '/photo/' . $filename,
'$title' => t('Crop Image'),
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
'$form_security_token' => get_form_security_token("cover_photo"),
'$done' => t('Done Editing')
]);
return $o;
}
}
/* @brief Generate the UI for photo-cropping
*
* @param $a Current application
* @param $ph Photo-Factory
* @return void
*
*/
/* @brief Generate the UI for photo-cropping
*
* @param $a Current application
* @param $ph Photo-Factory
* @return void
*
*/
function cover_photo_crop_ui_head($ph, $hash, $smallest){
public function cover_photo_crop_ui_head($ph, $hash, $smallest)
{
$max_length = get_config('system','max_image_length', MAX_IMAGE_LENGTH);
$max_length = get_config('system', 'max_image_length', MAX_IMAGE_LENGTH);
if ($max_length > 0) {
$ph->scaleImage($max_length);
}
if ($max_length > 0) {
$ph->scaleImage($max_length);
}
$width = $ph->getWidth();
$height = $ph->getHeight();
$width = $ph->getWidth();
$height = $ph->getHeight();
if ($width < 300 || $height < 300) {
$ph->scaleImageUp(240);
$width = $ph->getWidth();
$height = $ph->getHeight();
}
if ($width < 300 || $height < 300) {
$ph->scaleImageUp(240);
$width = $ph->getWidth();
$height = $ph->getHeight();
}
App::$data['imagecrop'] = $hash;
App::$data['imagecrop_resolution'] = $smallest;
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
return;
}
App::$data['imagecrop'] = $hash;
App::$data['imagecrop_resolution'] = $smallest;
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
return;
}
}

View file

@ -3,111 +3,101 @@
namespace Zotlabs\Module\Admin;
class Dbsync {
class Dbsync
{
function get() {
$o = '';
public function get()
{
$o = '';
if(argc() > 3 && intval(argv(3)) && argv(2) === 'mark') {
// remove the old style config if it exists
del_config('database', 'update_r' . intval(argv(3)));
set_config('database', '_' . intval(argv(3)), 'success');
if(intval(get_config('system','db_version')) < intval(argv(3)))
set_config('system','db_version',intval(argv(3)));
info( t('Update has been marked successful') . EOL);
goaway(z_root() . '/admin/dbsync');
}
if (argc() > 3 && intval(argv(3)) && argv(2) === 'mark') {
// remove the old style config if it exists
del_config('database', 'update_r' . intval(argv(3)));
set_config('database', '_' . intval(argv(3)), 'success');
if (intval(get_config('system', 'db_version')) < intval(argv(3)))
set_config('system', 'db_version', intval(argv(3)));
info(t('Update has been marked successful') . EOL);
goaway(z_root() . '/admin/dbsync');
}
if(argc() > 3 && intval(argv(3)) && argv(2) === 'verify') {
if (argc() > 3 && intval(argv(3)) && argv(2) === 'verify') {
$s = '_' . intval(argv(3));
$cls = '\\Zotlabs\Update\\' . $s ;
if(class_exists($cls)) {
$c = new $cls();
if(method_exists($c,'verify')) {
$retval = $c->verify();
if($retval === UPDATE_FAILED) {
$o .= sprintf( t('Verification of update %s failed. Check system logs.'), $s);
}
elseif($retval === UPDATE_SUCCESS) {
$o .= sprintf( t('Update %s was successfully applied.'), $s);
set_config('database',$s, 'success');
}
else
$o .= sprintf( t('Verifying update %s did not return a status. Unknown if it succeeded.'), $s);
}
else {
$o .= sprintf( t('Update %s does not contain a verification function.'), $s );
}
}
else
$o .= sprintf( t('Update function %s could not be found.'), $s);
$s = '_' . intval(argv(3));
$cls = '\\Zotlabs\Update\\' . $s;
if (class_exists($cls)) {
$c = new $cls();
if (method_exists($c, 'verify')) {
$retval = $c->verify();
if ($retval === UPDATE_FAILED) {
$o .= sprintf(t('Verification of update %s failed. Check system logs.'), $s);
} elseif ($retval === UPDATE_SUCCESS) {
$o .= sprintf(t('Update %s was successfully applied.'), $s);
set_config('database', $s, 'success');
} else
$o .= sprintf(t('Verifying update %s did not return a status. Unknown if it succeeded.'), $s);
} else {
$o .= sprintf(t('Update %s does not contain a verification function.'), $s);
}
} else
$o .= sprintf(t('Update function %s could not be found.'), $s);
return $o;
return $o;
// remove the old style config if it exists
del_config('database', 'update_r' . intval(argv(3)));
set_config('database', '_' . intval(argv(3)), 'success');
if (intval(get_config('system', 'db_version')) < intval(argv(3)))
set_config('system', 'db_version', intval(argv(3)));
info(t('Update has been marked successful') . EOL);
goaway(z_root() . '/admin/dbsync');
}
if (argc() > 2 && intval(argv(2))) {
$x = intval(argv(2));
$s = '_' . $x;
$cls = '\\Zotlabs\Update\\' . $s;
if (class_exists($cls)) {
$c = new $cls();
$retval = $c->run();
if ($retval === UPDATE_FAILED) {
$o .= sprintf(t('Executing update procedure %s failed. Check system logs.'), $s);
} elseif ($retval === UPDATE_SUCCESS) {
$o .= sprintf(t('Update %s was successfully applied.'), $s);
set_config('database', $s, 'success');
} else
$o .= sprintf(t('Update %s did not return a status. It cannot be determined if it was successful.'), $s);
} else
$o .= sprintf(t('Update function %s could not be found.'), $s);
return $o;
}
// remove the old style config if it exists
del_config('database', 'update_r' . intval(argv(3)));
set_config('database', '_' . intval(argv(3)), 'success');
if(intval(get_config('system','db_version')) < intval(argv(3)))
set_config('system','db_version',intval(argv(3)));
info( t('Update has been marked successful') . EOL);
goaway(z_root() . '/admin/dbsync');
}
$failed = [];
$r = q("select * from config where cat = 'database' ");
if (count($r)) {
foreach ($r as $rr) {
$upd = intval(substr($rr['k'], -4));
if ($rr['v'] === 'success')
continue;
$failed[] = $upd;
}
}
if (count($failed)) {
$o = replace_macros(get_markup_template('failed_updates.tpl'), array(
'$base' => z_root(),
'$banner' => t('Failed Updates'),
'$desc' => '',
'$mark' => t('Mark success (if update was manually applied)'),
'$verify' => t('Attempt to verify this update if a verification procedure exists'),
'$apply' => t('Attempt to execute this update step automatically'),
'$failed' => $failed
));
} else {
return '<div class="generic-content-wrapper-styled"><h3>' . t('No failed updates.') . '</h3></div>';
}
if(argc() > 2 && intval(argv(2))) {
$x = intval(argv(2));
$s = '_' . $x;
$cls = '\\Zotlabs\Update\\' . $s ;
if(class_exists($cls)) {
$c = new $cls();
$retval = $c->run();
if($retval === UPDATE_FAILED) {
$o .= sprintf( t('Executing update procedure %s failed. Check system logs.'), $s);
}
elseif($retval === UPDATE_SUCCESS) {
$o .= sprintf( t('Update %s was successfully applied.'), $s);
set_config('database',$s, 'success');
}
else
$o .= sprintf( t('Update %s did not return a status. It cannot be determined if it was successful.'), $s);
}
else
$o .= sprintf( t('Update function %s could not be found.'), $s);
return $o;
}
$failed = [];
$r = q("select * from config where cat = 'database' ");
if(count($r)) {
foreach($r as $rr) {
$upd = intval(substr($rr['k'],-4));
if($rr['v'] === 'success')
continue;
$failed[] = $upd;
}
}
if(count($failed)) {
$o = replace_macros(get_markup_template('failed_updates.tpl'),array(
'$base' => z_root(),
'$banner' => t('Failed Updates'),
'$desc' => '',
'$mark' => t('Mark success (if update was manually applied)'),
'$verify' => t('Attempt to verify this update if a verification procedure exists'),
'$apply' => t('Attempt to execute this update step automatically'),
'$failed' => $failed
));
}
else {
return '<div class="generic-content-wrapper-styled"><h3>' . t('No failed updates.') . '</h3></div>';
}
return $o;
}
return $o;
}
}

View file

@ -3,99 +3,97 @@
namespace Zotlabs\Module\Admin;
class Logs {
class Logs
{
/**
* @brief POST handler for logs admin page.
*
*/
/**
* @brief POST handler for logs admin page.
*
*/
public function post()
{
if (x($_POST, 'page_logs')) {
check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
function post() {
if (x($_POST, 'page_logs')) {
check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
$logfile = ((x($_POST, 'logfile')) ? notags(trim($_POST['logfile'])) : '');
$debugging = ((x($_POST, 'debugging')) ? true : false);
$loglevel = ((x($_POST, 'loglevel')) ? intval(trim($_POST['loglevel'])) : 0);
$logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : '');
$debugging = ((x($_POST,'debugging')) ? true : false);
$loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0);
set_config('system', 'logfile', $logfile);
set_config('system', 'debugging', $debugging);
set_config('system', 'loglevel', $loglevel);
}
set_config('system','logfile', $logfile);
set_config('system','debugging', $debugging);
set_config('system','loglevel', $loglevel);
}
info(t('Log settings updated.'));
goaway(z_root() . '/admin/logs');
}
info( t('Log settings updated.') );
goaway(z_root() . '/admin/logs' );
}
/**
* @brief Logs admin page.
*
* @return string
*/
/**
* @brief Logs admin page.
*
* @return string
*/
public function get()
{
function get() {
$log_choices = array(
LOGGER_NORMAL => 'Normal',
LOGGER_TRACE => 'Trace',
LOGGER_DEBUG => 'Debug',
LOGGER_DATA => 'Data',
LOGGER_ALL => 'All'
);
$log_choices = Array(
LOGGER_NORMAL => 'Normal',
LOGGER_TRACE => 'Trace',
LOGGER_DEBUG => 'Debug',
LOGGER_DATA => 'Data',
LOGGER_ALL => 'All'
);
$t = get_markup_template('admin_logs.tpl');
$t = get_markup_template('admin_logs.tpl');
$f = get_config('system', 'logfile');
$f = get_config('system', 'logfile');
$data = '';
$data = '';
if(!file_exists($f)) {
$data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
if (!file_exists($f)) {
$data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
readable.");
}
else {
$fp = fopen($f, 'r');
if(!$fp) {
$data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
}
else {
$fstat = fstat($fp);
$size = $fstat['size'];
if($size != 0)
{
if($size > 5000000 || $size < 0)
$size = 5000000;
$seek = fseek($fp,0-$size,SEEK_END);
if($seek === 0) {
$data = escape_tags(fread($fp,$size));
while(! feof($fp))
$data .= escape_tags(fread($fp,4096));
}
}
fclose($fp);
}
}
} else {
$fp = fopen($f, 'r');
if (!$fp) {
$data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
} else {
$fstat = fstat($fp);
$size = $fstat['size'];
if ($size != 0) {
if ($size > 5000000 || $size < 0)
$size = 5000000;
$seek = fseek($fp, 0 - $size, SEEK_END);
if ($seek === 0) {
$data = escape_tags(fread($fp, $size));
while (!feof($fp))
$data .= escape_tags(fread($fp, 4096));
}
}
fclose($fp);
}
}
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Logs'),
'$submit' => t('Submit'),
'$clear' => t('Clear'),
'$data' => $data,
'$baseurl' => z_root(),
'$logname' => get_config('system','logfile'),
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Logs'),
'$submit' => t('Submit'),
'$clear' => t('Clear'),
'$data' => $data,
'$baseurl' => z_root(),
'$logname' => get_config('system', 'logfile'),
// name, label, value, help string, extra data...
'$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
'$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")),
'$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
'$form_security_token' => get_form_security_token('admin_logs'),
));
}
// name, label, value, help string, extra data...
'$debugging' => array('debugging', t("Debugging"), get_config('system', 'debugging'), ""),
'$logfile' => array('logfile', t("Log file"), get_config('system', 'logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")),
'$loglevel' => array('loglevel', t("Log level"), get_config('system', 'loglevel'), "", $log_choices),
'$form_security_token' => get_form_security_token('admin_logs'),
));
}
}

View file

@ -19,516 +19,513 @@ require_once('include/photo_factory.php');
require_once('include/photos.php');
class Profile_photo {
class Profile_photo
{
/* @brief Initalize the profile-photo edit view
*
* @return void
*
*/
/* @brief Initalize the profile-photo edit view
*
* @return void
*
*/
function init() {
public function init()
{
if(! is_site_admin()) {
return;
}
if (!is_site_admin()) {
return;
}
$channel = get_sys_channel();
Libprofile::load($channel['channel_address']);
$channel = get_sys_channel();
Libprofile::load($channel['channel_address']);
}
}
/* @brief Evaluate posted values
*
* @param $a Current application
* @return void
*
*/
/* @brief Evaluate posted values
*
* @param $a Current application
* @return void
*
*/
function post() {
public function post()
{
if (! is_site_admin()) {
return;
}
if (!is_site_admin()) {
return;
}
$channel = get_sys_channel();
$channel = get_sys_channel();
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
if ((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
if ((array_key_exists('cropfinal', $_POST)) && (intval($_POST['cropfinal']) == 1)) {
// logger('crop: ' . print_r($_POST,true));
// logger('crop: ' . print_r($_POST,true));
// phase 2 - we have finished cropping
// phase 2 - we have finished cropping
if (argc() != 3) {
notice( t('Image uploaded but image cropping failed.') . EOL );
return;
}
if (argc() != 3) {
notice(t('Image uploaded but image cropping failed.') . EOL);
return;
}
$image_id = argv(2);
$image_id = argv(2);
if (substr($image_id,-2,1) == '-') {
$scale = substr($image_id,-1,1);
$image_id = substr($image_id,0,-2);
}
if (substr($image_id, -2, 1) == '-') {
$scale = substr($image_id, -1, 1);
$image_id = substr($image_id, 0, -2);
}
// unless proven otherwise
$is_default_profile = 1;
// unless proven otherwise
$is_default_profile = 1;
if ($_REQUEST['profile']) {
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
intval($_REQUEST['profile']),
intval($channel['channel_id'])
);
if ($r) {
$profile = array_shift($r);
if (! intval($profile['is_default'])) {
$is_default_profile = 0;
}
}
}
if ($_REQUEST['profile']) {
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
intval($_REQUEST['profile']),
intval($channel['channel_id'])
);
if ($r) {
$profile = array_shift($r);
if (!intval($profile['is_default'])) {
$is_default_profile = 0;
}
}
}
$srcX = intval($_POST['xstart']);
$srcY = intval($_POST['ystart']);
$srcW = intval($_POST['xfinal']) - $srcX;
$srcH = intval($_POST['yfinal']) - $srcY;
$srcX = intval($_POST['xstart']);
$srcY = intval($_POST['ystart']);
$srcW = intval($_POST['xfinal']) - $srcX;
$srcH = intval($_POST['yfinal']) - $srcY;
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($image_id),
dbesc($channel['channel_id']),
intval($scale));
if ($r) {
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($image_id),
dbesc($channel['channel_id']),
intval($scale));
if ($r) {
$base_image = array_shift($r);
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
$base_image = array_shift($r);
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
$im = photo_factory($base_image['content'], $base_image['mimetype']);
if ($im->is_valid()) {
$im = photo_factory($base_image['content'], $base_image['mimetype']);
if ($im->is_valid()) {
$im->cropImage(300,$srcX,$srcY,$srcW,$srcH);
$im->cropImage(300, $srcX, $srcY, $srcW, $srcH);
$aid = 0;
$aid = 0;
$p = [
'aid' => $aid,
'uid' => $channel['channel_id'],
'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'],
'album' => t('Profile Photos'),
'os_path' => $base_image['os_path'],
'display_path' => $base_image['display_path'],
'created' => $base_image['created'],
'edited' => $base_image['edited']
];
$p = [
'aid' => $aid,
'uid' => $channel['channel_id'],
'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'],
'album' => t('Profile Photos'),
'os_path' => $base_image['os_path'],
'display_path' => $base_image['display_path'],
'created' => $base_image['created'],
'edited' => $base_image['edited']
];
$p['imgscale'] = PHOTO_RES_PROFILE_300;
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
$p['imgscale'] = PHOTO_RES_PROFILE_300;
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
$im->scaleImage(80);
$p['imgscale'] = PHOTO_RES_PROFILE_80;
$im->scaleImage(80);
$p['imgscale'] = PHOTO_RES_PROFILE_80;
$r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
$r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
$im->scaleImage(48);
$p['imgscale'] = PHOTO_RES_PROFILE_48;
$im->scaleImage(48);
$p['imgscale'] = PHOTO_RES_PROFILE_48;
$r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48);
$r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48);
if ($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
dbesc($base_image['resource_id']),
$channel['channel_id'],
intval(PHOTO_RES_PROFILE_300),
intval(PHOTO_RES_PROFILE_80),
intval(PHOTO_RES_PROFILE_48)
);
return;
}
if ($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice(t('Image resize failed.') . EOL);
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
dbesc($base_image['resource_id']),
$channel['channel_id'],
intval(PHOTO_RES_PROFILE_300),
intval(PHOTO_RES_PROFILE_80),
intval(PHOTO_RES_PROFILE_48)
);
return;
}
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
AND resource_id != '%s' AND uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
dbesc($base_image['resource_id']),
intval($channel['channel_id'])
);
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
dbesc($base_image['resource_id']),
intval($channel['channel_id'])
);
// We'll set the updated profile-photo timestamp even if it isn't the default profile,
// so that browsers will do a cache update unconditionally
// Also set links back to site-specific profile photo url in case it was
// changed to a generic URL by a clone operation. Otherwise the new photo may
// not get pushed to other sites correctly.
// We'll set the updated profile-photo timestamp even if it isn't the default profile,
// so that browsers will do a cache update unconditionally
// Also set links back to site-specific profile photo url in case it was
// changed to a generic URL by a clone operation. Otherwise the new photo may
// not get pushed to other sites correctly.
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
where xchan_hash = '%s'",
dbesc($im->getType()),
dbesc(datetime_convert()),
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
dbesc($channel['xchan_hash'])
);
dbesc($im->getType()),
dbesc(datetime_convert()),
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
dbesc($channel['xchan_hash'])
);
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
$_SESSION['reload_avatar'] = true;
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
$_SESSION['reload_avatar'] = true;
Config::Set('system','site_icon_url',z_root() . '/photo/profile/m/' . $channel['channel_id']);
Config::Set('system', 'site_icon_url', z_root() . '/photo/profile/m/' . $channel['channel_id']);
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
}
else {
notice( t('Unable to process image') . EOL);
}
}
} else {
notice(t('Unable to process image') . EOL);
}
}
goaway(z_root() . '/admin');
}
goaway(z_root() . '/admin');
}
// A new photo was uploaded. Store it and save some important details
// in App::$data for use in the cropping function
// A new photo was uploaded. Store it and save some important details
// in App::$data for use in the cropping function
$hash = photo_new_resource();
$importing = false;
$smallest = 0;
$hash = photo_new_resource();
$importing = false;
$smallest = 0;
if ($_REQUEST['importfile']) {
$hash = $_REQUEST['importfile'];
$importing = true;
}
else {
if ($_REQUEST['importfile']) {
$hash = $_REQUEST['importfile'];
$importing = true;
} else {
$matches = [];
$partial = false;
$matches = [];
$partial = false;
if (array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
if ($pm) {
logger('Content-Range: ' . print_r($matches,true), LOGGER_DEBUG);
$partial = true;
}
}
if (array_key_exists('HTTP_CONTENT_RANGE', $_SERVER)) {
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/', $_SERVER['HTTP_CONTENT_RANGE'], $matches);
if ($pm) {
logger('Content-Range: ' . print_r($matches, true), LOGGER_DEBUG);
$partial = true;
}
}
if ($partial) {
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
if ($partial) {
$x = save_chunk($channel, $matches[1], $matches[2], $matches[3]);
if ($x['partial']) {
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
json_return_and_die($x);
}
else {
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
if ($x['partial']) {
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
json_return_and_die($x);
} else {
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
$_FILES['userfile'] = [
'name' => $x['name'],
'type' => $x['type'],
'tmp_name' => $x['tmp_name'],
'error' => $x['error'],
'size' => $x['size']
];
}
}
else {
if (! array_key_exists('userfile',$_FILES)) {
$_FILES['userfile'] = [
'name' => $_FILES['files']['name'],
'type' => $_FILES['files']['type'],
'tmp_name' => $_FILES['files']['tmp_name'],
'error' => $_FILES['files']['error'],
'size' => $_FILES['files']['size']
];
}
}
$_FILES['userfile'] = [
'name' => $x['name'],
'type' => $x['type'],
'tmp_name' => $x['tmp_name'],
'error' => $x['error'],
'size' => $x['size']
];
}
} else {
if (!array_key_exists('userfile', $_FILES)) {
$_FILES['userfile'] = [
'name' => $_FILES['files']['name'],
'type' => $_FILES['files']['type'],
'tmp_name' => $_FILES['files']['tmp_name'],
'error' => $_FILES['files']['error'],
'size' => $_FILES['files']['size']
];
}
}
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Profile Photos'), 'hash' => $hash));
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Profile Photos'), 'hash' => $hash));
logger('attach_store: ' . print_r($res,true), LOGGER_DEBUG);
logger('attach_store: ' . print_r($res, true), LOGGER_DEBUG);
json_return_and_die([ 'message' => $hash ]);
}
json_return_and_die(['message' => $hash]);
}
if (($res && intval($res['data']['is_photo'])) || $importing) {
$i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($hash),
intval($channel['channel_hash'])
);
if (($res && intval($res['data']['is_photo'])) || $importing) {
$i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($hash),
intval($channel['channel_hash'])
);
if (! $i) {
notice( t('Image upload failed.') . EOL );
return;
}
$os_storage = false;
if (!$i) {
notice(t('Image upload failed.') . EOL);
return;
}
$os_storage = false;
foreach ($i as $ii) {
if (intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
$imagedata = $ii['content'];
$filetype = $ii['mimetype'];
}
}
}
foreach ($i as $ii) {
if (intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
$imagedata = $ii['content'];
$filetype = $ii['mimetype'];
}
}
}
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
$ph = photo_factory($imagedata, $filetype);
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
$ph = photo_factory($imagedata, $filetype);
if (! $ph->is_valid()) {
notice( t('Unable to process image.') . EOL );
return;
}
if (!$ph->is_valid()) {
notice(t('Unable to process image.') . EOL);
return;
}
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
// This will "fall through" to the get() method, and since
// App::$data['imagecrop'] is set, it will proceed to cropping
// rather than present the upload form
}
// This will "fall through" to the get() method, and since
// App::$data['imagecrop'] is set, it will proceed to cropping
// rather than present the upload form
}
/* @brief Generate content of profile-photo view
*
* @return void
*
*/
/* @brief Generate content of profile-photo view
*
* @return void
*
*/
function get() {
public function get()
{
if (! is_site_admin()) {
notice( t('Permission denied.') . EOL );
return;
}
if (!is_site_admin()) {
notice(t('Permission denied.') . EOL);
return;
}
$channel = get_sys_channel();
$pf = 0;
$newuser = false;
$channel = get_sys_channel();
$pf = 0;
$newuser = false;
if (argc() == 3 && argv(2) === 'new') {
$newuser = true;
}
if (argc() == 3 && argv(2) === 'new') {
$newuser = true;
}
if (argv(2) === 'reset') {
Config::Delete('system','site_icon_url');
}
if (argv(2) === 'reset') {
Config::Delete('system', 'site_icon_url');
}
if (argv(2) === 'use') {
if (argc() < 4) {
notice( t('Permission denied.') . EOL );
return;
}
if (argv(2) === 'use') {
if (argc() < 4) {
notice(t('Permission denied.') . EOL);
return;
}
$resource_id = argv(3);
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0);
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0);
$c = q("select id, is_default from profile where uid = %d",
intval($channel['channel_id'])
);
$c = q("select id, is_default from profile where uid = %d",
intval($channel['channel_id'])
);
$multi_profiles = true;
$multi_profiles = true;
if (($c) && (count($c) === 1) && (intval($c[0]['is_default']))) {
$_REQUEST['profile'] = $c[0]['id'];
$multi_profiles = false;
}
else {
$_REQUEST['profile'] = $pf;
}
if (($c) && (count($c) === 1) && (intval($c[0]['is_default']))) {
$_REQUEST['profile'] = $c[0]['id'];
$multi_profiles = false;
} else {
$_REQUEST['profile'] = $pf;
}
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
intval($channel['channel_id']),
dbesc($resource_id)
);
if (! $r) {
notice( t('Photo not available.') . EOL );
return;
}
$havescale = false;
foreach ($r as $rr) {
if ($rr['imgscale'] == PHOTO_RES_PROFILE_80) {
$havescale = true;
}
}
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
intval($channel['channel_id']),
dbesc($resource_id)
);
if (!$r) {
notice(t('Photo not available.') . EOL);
return;
}
$havescale = false;
foreach ($r as $rr) {
if ($rr['imgscale'] == PHOTO_RES_PROFILE_80) {
$havescale = true;
}
}
// set an already loaded and cropped photo as profile photo
// set an already loaded and cropped photo as profile photo
if ($havescale) {
// unset any existing profile photos
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($channel['channel_id'])
);
if ($havescale) {
// unset any existing profile photos
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($channel['channel_id'])
);
$r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'",
intval(PHOTO_PROFILE),
intval($channel['channel_id']),
dbesc($resource_id)
);
$r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'",
intval(PHOTO_PROFILE),
intval($channel['channel_id']),
dbesc($resource_id)
);
$r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
);
$r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
);
goaway(z_root() . '/admin');
}
goaway(z_root() . '/admin');
}
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval($channel['channel_id'])
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
intval($r[0]['id']),
intval($channel['channel_id'])
);
if (! $r) {
notice( t('Photo not available.') . EOL );
return;
}
);
if (!$r) {
notice(t('Photo not available.') . EOL);
return;
}
if (intval($r[0]['os_storage'])) {
$data = @file_get_contents(dbunescbin($r[0]['content']));
}
else {
$data = dbunescbin($r[0]['content']);
}
if (intval($r[0]['os_storage'])) {
$data = @file_get_contents(dbunescbin($r[0]['content']));
} else {
$data = dbunescbin($r[0]['content']);
}
$ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if ($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($r[0]['resource_id']),
intval($channel['channel_id'])
);
$ph = photo_factory($data, $r[0]['mimetype']);
$smallest = 0;
if ($ph->is_valid()) {
// go ahead as if we have just uploaded a new photo to crop
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale",
dbesc($r[0]['resource_id']),
intval($channel['channel_id'])
);
if ($i) {
$hash = $i[0]['resource_id'];
foreach ($i as $ii) {
if (intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
}
}
}
}
if ($i) {
$hash = $i[0]['resource_id'];
foreach ($i as $ii) {
if (intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
}
}
}
}
if ($multi_profiles) {
App::$data['importfile'] = $resource_id;
}
else {
$this->profile_photo_crop_ui_head($ph, $hash, $smallest);
}
if ($multi_profiles) {
App::$data['importfile'] = $resource_id;
} else {
$this->profile_photo_crop_ui_head($ph, $hash, $smallest);
}
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
}
}
// present an upload form
// present an upload form
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
intval($channel['channel_id'])
);
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
intval($channel['channel_id'])
);
if ($profiles) {
for ($x = 0; $x < count($profiles); $x ++) {
$profiles[$x]['selected'] = false;
if ($pf && $profiles[$x]['id'] == $pf) {
$profiles[$x]['selected'] = true;
}
if ((! $pf) && $profiles[$x]['is_default']) {
$profiles[$x]['selected'] = true;
}
}
}
if ($profiles) {
for ($x = 0; $x < count($profiles); $x++) {
$profiles[$x]['selected'] = false;
if ($pf && $profiles[$x]['id'] == $pf) {
$profiles[$x]['selected'] = true;
}
if ((!$pf) && $profiles[$x]['is_default']) {
$profiles[$x]['selected'] = true;
}
}
}
$importing = ((array_key_exists('importfile',App::$data)) ? true : false);
$importing = ((array_key_exists('importfile', App::$data)) ? true : false);
if (! array_key_exists('imagecrop', App::$data)) {
if (!array_key_exists('imagecrop', App::$data)) {
$tpl = get_markup_template('admin_profile_photo.tpl');
$tpl = get_markup_template('admin_profile_photo.tpl');
$o .= replace_macros($tpl, [
'$user' => $channel['channel_address'],
'$channel_id' => $channel['channel_id'],
'$info' => ((count($profiles) > 1) ? t('Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile') : t('Your site photo is visible to anybody on the internet and may be distributed to other websites.')),
'$importfile' => (($importing) ? App::$data['importfile'] : ''),
'$lbl_upfile' => t('Upload File:'),
'$lbl_profiles' => t('Select a profile:'),
'$title' => (($importing) ? t('Use Photo for Site Logo') : t('Change Site Logo')),
'$submit' => (($importing) ? t('Use') : t('Upload')),
'$profiles' => $profiles,
'$single' => ((count($profiles) == 1) ? true : false),
'$profile0' => $profiles[0],
'$embedPhotos' => t('Use a photo from your albums'),
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
'$embedPhotosModalCancel' => t('Cancel'),
'$embedPhotosModalOK' => t('OK'),
'$modalchooseimages' => t('Choose images to embed'),
'$modalchoosealbum' => t('Choose an album'),
'$modaldiffalbum' => t('Choose a different album'),
'$modalerrorlist' => t('Error getting album list'),
'$modalerrorlink' => t('Error getting photo link'),
'$modalerroralbum' => t('Error getting album'),
'$form_security_token' => get_form_security_token("profile_photo"),
'$select' => t('Select previously uploaded photo'),
]);
$o .= replace_macros($tpl, [
'$user' => $channel['channel_address'],
'$channel_id' => $channel['channel_id'],
'$info' => ((count($profiles) > 1) ? t('Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile') : t('Your site photo is visible to anybody on the internet and may be distributed to other websites.')),
'$importfile' => (($importing) ? App::$data['importfile'] : ''),
'$lbl_upfile' => t('Upload File:'),
'$lbl_profiles' => t('Select a profile:'),
'$title' => (($importing) ? t('Use Photo for Site Logo') : t('Change Site Logo')),
'$submit' => (($importing) ? t('Use') : t('Upload')),
'$profiles' => $profiles,
'$single' => ((count($profiles) == 1) ? true : false),
'$profile0' => $profiles[0],
'$embedPhotos' => t('Use a photo from your albums'),
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
'$embedPhotosModalCancel' => t('Cancel'),
'$embedPhotosModalOK' => t('OK'),
'$modalchooseimages' => t('Choose images to embed'),
'$modalchoosealbum' => t('Choose an album'),
'$modaldiffalbum' => t('Choose a different album'),
'$modalerrorlist' => t('Error getting album list'),
'$modalerrorlink' => t('Error getting photo link'),
'$modalerroralbum' => t('Error getting album'),
'$form_security_token' => get_form_security_token("profile_photo"),
'$select' => t('Select previously uploaded photo'),
]);
call_hooks('profile_photo_content_end', $o);
return $o;
}
else {
call_hooks('profile_photo_content_end', $o);
return $o;
} else {
// present a cropping form
// present a cropping form
$filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'];
$resolution = App::$data['imagecrop_resolution'];
$o .= replace_macros(get_markup_template('admin_cropbody.tpl'), [
'$filename' => $filename,
'$profile' => intval($_REQUEST['profile']),
'$resource' => App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'],
'$image_url' => z_root() . '/photo/' . $filename,
'$title' => t('Crop Image'),
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
'$form_security_token' => get_form_security_token("profile_photo"),
'$done' => t('Done Editing')
]);
return $o;
}
}
$filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'];
$resolution = App::$data['imagecrop_resolution'];
$o .= replace_macros(get_markup_template('admin_cropbody.tpl'), [
'$filename' => $filename,
'$profile' => intval($_REQUEST['profile']),
'$resource' => App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'],
'$image_url' => z_root() . '/photo/' . $filename,
'$title' => t('Crop Image'),
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
'$form_security_token' => get_form_security_token("profile_photo"),
'$done' => t('Done Editing')
]);
return $o;
}
}
/* @brief Generate the UI for photo-cropping
*
* @param $ph Photo-Factory
* @return void
*
*/
/* @brief Generate the UI for photo-cropping
*
* @param $ph Photo-Factory
* @return void
*
*/
function profile_photo_crop_ui_head($ph, $hash, $smallest) {
$max_length = get_config('system','max_image_length', MAX_IMAGE_LENGTH);
public function profile_photo_crop_ui_head($ph, $hash, $smallest)
{
$max_length = get_config('system', 'max_image_length', MAX_IMAGE_LENGTH);
if ($max_length > 0) {
$ph->scaleImage($max_length);
}
if ($max_length > 0) {
$ph->scaleImage($max_length);
}
App::$data['width'] = $ph->getWidth();
App::$data['height'] = $ph->getHeight();
App::$data['width'] = $ph->getWidth();
App::$data['height'] = $ph->getHeight();
if (App::$data['width'] < 500 || App::$data['height'] < 500) {
$ph->scaleImageUp(400);
App::$data['width'] = $ph->getWidth();
App::$data['height'] = $ph->getHeight();
}
if (App::$data['width'] < 500 || App::$data['height'] < 500) {
$ph->scaleImageUp(400);
App::$data['width'] = $ph->getWidth();
App::$data['height'] = $ph->getHeight();
}
App::$data['imagecrop'] = $hash;
App::$data['imagecrop_resolution'] = $smallest;
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
return;
}
App::$data['imagecrop'] = $hash;
App::$data['imagecrop_resolution'] = $smallest;
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
return;
}
}

View file

@ -3,188 +3,187 @@
namespace Zotlabs\Module\Admin;
class Profs {
class Profs
{
function post() {
public function post()
{
if(array_key_exists('basic',$_REQUEST)) {
$arr = explode(',',$_REQUEST['basic']);
array_walk($arr,'array_trim');
$narr = [];
if(count($arr)) {
foreach($arr as $a) {
if(strlen($a)) {
$narr[] = $a;
}
}
}
if(! $narr)
del_config('system','profile_fields_basic');
else
set_config('system','profile_fields_basic',$narr);
if (array_key_exists('basic', $_REQUEST)) {
$arr = explode(',', $_REQUEST['basic']);
array_walk($arr, 'array_trim');
$narr = [];
if (count($arr)) {
foreach ($arr as $a) {
if (strlen($a)) {
$narr[] = $a;
}
}
}
if (!$narr)
del_config('system', 'profile_fields_basic');
else
set_config('system', 'profile_fields_basic', $narr);
if(array_key_exists('advanced',$_REQUEST)) {
$arr = explode(',',$_REQUEST['advanced']);
array_walk($arr,'array_trim');
$narr = [];
if(count($arr)) {
foreach($arr as $a) {
if(strlen($a)) {
$narr[] = $a;
}
}
}
if(! $narr)
del_config('system','profile_fields_advanced');
else
set_config('system','profile_fields_advanced',$narr);
if (array_key_exists('advanced', $_REQUEST)) {
$arr = explode(',', $_REQUEST['advanced']);
array_walk($arr, 'array_trim');
$narr = [];
if (count($arr)) {
foreach ($arr as $a) {
if (strlen($a)) {
$narr[] = $a;
}
}
}
if (!$narr)
del_config('system', 'profile_fields_advanced');
else
set_config('system', 'profile_fields_advanced', $narr);
}
goaway(z_root() . '/admin/profs');
}
}
goaway(z_root() . '/admin/profs');
}
if(array_key_exists('field_name',$_REQUEST)) {
if($_REQUEST['id']) {
$r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs']),
intval($_REQUEST['id'])
);
}
else {
$r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs'])
);
}
}
if (array_key_exists('field_name', $_REQUEST)) {
if ($_REQUEST['id']) {
$r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs']),
intval($_REQUEST['id'])
);
} else {
$r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )",
dbesc($_REQUEST['field_name']),
dbesc($_REQUEST['field_type']),
dbesc($_REQUEST['field_desc']),
dbesc($_REQUEST['field_help']),
dbesc($_REQUEST['field_inputs'])
);
}
}
// add to chosen array basic or advanced
// add to chosen array basic or advanced
goaway(z_root() . '/admin/profs');
}
goaway(z_root() . '/admin/profs');
}
function get() {
public function get()
{
if((argc() > 3) && argv(2) == 'drop' && intval(argv(3))) {
$r = q("delete from profdef where id = %d",
intval(argv(3))
);
// remove from allowed fields
if ((argc() > 3) && argv(2) == 'drop' && intval(argv(3))) {
$r = q("delete from profdef where id = %d",
intval(argv(3))
);
// remove from allowed fields
goaway(z_root() . '/admin/profs');
}
goaway(z_root() . '/admin/profs');
}
if((argc() > 2) && argv(2) === 'new') {
return replace_macros(get_markup_template('profdef_edit.tpl'),array(
'$header' => t('New Profile Field'),
'$field_name' => array('field_name',t('Field nickname'),$_REQUEST['field_name'],t('System name of field')),
'$field_type' => array('field_type',t('Input type'),(($_REQUEST['field_type']) ? $_REQUEST['field_type'] : 'text'),''),
'$field_desc' => array('field_desc',t('Field Name'),$_REQUEST['field_desc'],t('Label on profile pages')),
'$field_help' => array('field_help',t('Help text'),$_REQUEST['field_help'],t('Additional info (optional)')),
'$submit' => t('Save')
));
}
if ((argc() > 2) && argv(2) === 'new') {
return replace_macros(get_markup_template('profdef_edit.tpl'), array(
'$header' => t('New Profile Field'),
'$field_name' => array('field_name', t('Field nickname'), $_REQUEST['field_name'], t('System name of field')),
'$field_type' => array('field_type', t('Input type'), (($_REQUEST['field_type']) ? $_REQUEST['field_type'] : 'text'), ''),
'$field_desc' => array('field_desc', t('Field Name'), $_REQUEST['field_desc'], t('Label on profile pages')),
'$field_help' => array('field_help', t('Help text'), $_REQUEST['field_help'], t('Additional info (optional)')),
'$submit' => t('Save')
));
}
if((argc() > 2) && intval(argv(2))) {
$r = q("select * from profdef where id = %d limit 1",
intval(argv(2))
);
if(! $r) {
notice( t('Field definition not found') . EOL);
goaway(z_root() . '/admin/profs');
}
if ((argc() > 2) && intval(argv(2))) {
$r = q("select * from profdef where id = %d limit 1",
intval(argv(2))
);
if (!$r) {
notice(t('Field definition not found') . EOL);
goaway(z_root() . '/admin/profs');
}
return replace_macros(get_markup_template('profdef_edit.tpl'),array(
'$id' => intval($r[0]['id']),
'$header' => t('Edit Profile Field'),
'$field_name' => array('field_name',t('Field nickname'),$r[0]['field_name'],t('System name of field')),
'$field_type' => array('field_type',t('Input type'),$r[0]['field_type'],''),
'$field_desc' => array('field_desc',t('Field Name'),$r[0]['field_desc'],t('Label on profile pages')),
'$field_help' => array('field_help',t('Help text'),$r[0]['field_help'],t('Additional info (optional)')),
'$submit' => t('Save')
));
}
return replace_macros(get_markup_template('profdef_edit.tpl'), array(
'$id' => intval($r[0]['id']),
'$header' => t('Edit Profile Field'),
'$field_name' => array('field_name', t('Field nickname'), $r[0]['field_name'], t('System name of field')),
'$field_type' => array('field_type', t('Input type'), $r[0]['field_type'], ''),
'$field_desc' => array('field_desc', t('Field Name'), $r[0]['field_desc'], t('Label on profile pages')),
'$field_help' => array('field_help', t('Help text'), $r[0]['field_help'], t('Additional info (optional)')),
'$submit' => t('Save')
));
}
$basic = '';
$barr = [];
$fields = get_profile_fields_basic();
$basic = '';
$barr = [];
$fields = get_profile_fields_basic();
if(! $fields)
$fields = get_profile_fields_basic(1);
if($fields) {
foreach($fields as $k => $v) {
if($basic)
$basic .= ', ';
$basic .= trim($k);
$barr[] = trim($k);
}
}
if (!$fields)
$fields = get_profile_fields_basic(1);
if ($fields) {
foreach ($fields as $k => $v) {
if ($basic)
$basic .= ', ';
$basic .= trim($k);
$barr[] = trim($k);
}
}
$advanced = '';
$fields = get_profile_fields_advanced();
if(! $fields)
$fields = get_profile_fields_advanced(1);
if($fields) {
foreach($fields as $k => $v) {
if(in_array(trim($k),$barr))
continue;
if($advanced)
$advanced .= ', ';
$advanced .= trim($k);
}
}
$advanced = '';
$fields = get_profile_fields_advanced();
if (!$fields)
$fields = get_profile_fields_advanced(1);
if ($fields) {
foreach ($fields as $k => $v) {
if (in_array(trim($k), $barr))
continue;
if ($advanced)
$advanced .= ', ';
$advanced .= trim($k);
}
}
$all = '';
$fields = get_profile_fields_advanced(1);
if($fields) {
foreach($fields as $k => $v) {
if($all)
$all .= ', ';
$all .= trim($k);
}
}
$all = '';
$fields = get_profile_fields_advanced(1);
if ($fields) {
foreach ($fields as $k => $v) {
if ($all)
$all .= ', ';
$all .= trim($k);
}
}
$r = q("select * from profdef where true");
if($r) {
foreach($r as $rr) {
if($all)
$all .= ', ';
$all .= $rr['field_name'];
}
}
$r = q("select * from profdef where true");
if ($r) {
foreach ($r as $rr) {
if ($all)
$all .= ', ';
$all .= $rr['field_name'];
}
}
$o = replace_macros(get_markup_template('admin_profiles.tpl'),array(
'$title' => t('Profile Fields'),
'$basic' => array('basic',t('Basic Profile Fields'),$basic,''),
'$advanced' => array('advanced',t('Advanced Profile Fields'),$advanced,t('(In addition to basic fields)')),
'$all' => $all,
'$all_desc' => t('All available fields'),
'$cust_field_desc' => t('Custom Fields'),
'$cust_fields' => $r,
'$edit' => t('Edit'),
'$drop' => t('Delete'),
'$new' => t('Create Custom Field'),
'$submit' => t('Submit')
));
return $o;
}
$o = replace_macros(get_markup_template('admin_profiles.tpl'), array(
'$title' => t('Profile Fields'),
'$basic' => array('basic', t('Basic Profile Fields'), $basic, ''),
'$advanced' => array('advanced', t('Advanced Profile Fields'), $advanced, t('(In addition to basic fields)')),
'$all' => $all,
'$all_desc' => t('All available fields'),
'$cust_field_desc' => t('Custom Fields'),
'$cust_fields' => $r,
'$edit' => t('Edit'),
'$drop' => t('Delete'),
'$new' => t('Create Custom Field'),
'$submit' => t('Submit')
));
return $o;
}
}

View file

@ -4,48 +4,48 @@ namespace Zotlabs\Module\Admin;
use Zotlabs\Lib\Queue as ZQueue;
class Queue {
class Queue
{
function get() {
public function get()
{
$o = '';
$o = '';
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
$expert = ((array_key_exists('expert', $_REQUEST)) ? intval($_REQUEST['expert']) : 0);
if($_REQUEST['drophub']) {
hubloc_mark_as_down($_REQUEST['drophub']);
ZQueue::remove_by_posturl($_REQUEST['drophub']);
}
if ($_REQUEST['drophub']) {
hubloc_mark_as_down($_REQUEST['drophub']);
ZQueue::remove_by_posturl($_REQUEST['drophub']);
}
if($_REQUEST['emptyhub']) {
ZQueue::remove_by_posturl($_REQUEST['emptyhub']);
}
if ($_REQUEST['emptyhub']) {
ZQueue::remove_by_posturl($_REQUEST['emptyhub']);
}
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
where outq_delivered = 0 group by outq_posturl order by total desc");
for($x = 0; $x < count($r); $x ++) {
$r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']);
$r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d');
}
$o = replace_macros(get_markup_template('admin_queue.tpl'), array(
'$banner' => t('Queue Statistics'),
'$numentries' => t('Total Entries'),
'$priority' => t('Priority'),
'$desturl' => t('Destination URL'),
'$nukehub' => t('Mark hub permanently offline'),
'$empty' => t('Empty queue for this hub'),
'$lastconn' => t('Last known contact'),
'$hasentries' => ((count($r)) ? true : false),
'$entries' => $r,
'$expert' => $expert
));
return $o;
}
for ($x = 0; $x < count($r); $x++) {
$r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']);
$r[$x]['connected'] = datetime_convert('UTC', date_default_timezone_get(), $r[$x]['connected'], 'Y-m-d');
}
$o = replace_macros(get_markup_template('admin_queue.tpl'), array(
'$banner' => t('Queue Statistics'),
'$numentries' => t('Total Entries'),
'$priority' => t('Priority'),
'$desturl' => t('Destination URL'),
'$nukehub' => t('Mark hub permanently offline'),
'$empty' => t('Empty queue for this hub'),
'$lastconn' => t('Last known contact'),
'$hasentries' => ((count($r)) ? true : false),
'$entries' => $r,
'$expert' => $expert
));
return $o;
}
}

View file

@ -3,185 +3,188 @@
namespace Zotlabs\Module\Admin;
class Security {
class Security
{
function post() {
check_form_security_token_redirectOnErr('/admin/security', 'admin_security');
public function post()
{
check_form_security_token_redirectOnErr('/admin/security', 'admin_security');
$allowed_email = ((x($_POST,'allowed_email')) ? notags(trim($_POST['allowed_email'])) : '');
set_config('system','allowed_email', $allowed_email);
$allowed_email = ((x($_POST, 'allowed_email')) ? notags(trim($_POST['allowed_email'])) : '');
set_config('system', 'allowed_email', $allowed_email);
$not_allowed_email = ((x($_POST,'not_allowed_email')) ? notags(trim($_POST['not_allowed_email'])) : '');
set_config('system','not_allowed_email', $not_allowed_email);
$not_allowed_email = ((x($_POST, 'not_allowed_email')) ? notags(trim($_POST['not_allowed_email'])) : '');
set_config('system', 'not_allowed_email', $not_allowed_email);
$anonymous_comments = ((x($_POST,'anonymous_comments')) ? intval($_POST['anonymous_comments']) : 0);
set_config('system','anonymous_comments', $anonymous_comments);
$anonymous_comments = ((x($_POST, 'anonymous_comments')) ? intval($_POST['anonymous_comments']) : 0);
set_config('system', 'anonymous_comments', $anonymous_comments);
$block_public = ((x($_POST,'block_public')) ? True : False);
set_config('system','block_public',$block_public);
$block_public = ((x($_POST, 'block_public')) ? True : False);
set_config('system', 'block_public', $block_public);
$block_public_search = ((x($_POST,'block_public_search')) ? 1 : 0);
set_config('system','block_public_search',$block_public_search);
$block_public_search = ((x($_POST, 'block_public_search')) ? 1 : 0);
set_config('system', 'block_public_search', $block_public_search);
$block_public_dir = ((x($_POST,'block_public_directory')) ? True : False);
set_config('system', 'block_public_directory', $block_public_dir);
$block_public_dir = ((x($_POST, 'block_public_directory')) ? True : False);
set_config('system', 'block_public_directory', $block_public_dir);
$localdir_hide = ((x($_POST,'localdir_hide')) ? 1 : 0);
set_config('system','localdir_hide',$localdir_hide);
$localdir_hide = ((x($_POST, 'localdir_hide')) ? 1 : 0);
set_config('system', 'localdir_hide', $localdir_hide);
$cloud_noroot = ((x($_POST,'cloud_noroot')) ? 1 : 0);
set_config('system','cloud_disable_siteroot',1 - $cloud_noroot);
$cloud_noroot = ((x($_POST, 'cloud_noroot')) ? 1 : 0);
set_config('system', 'cloud_disable_siteroot', 1 - $cloud_noroot);
$cloud_disksize = ((x($_POST,'cloud_disksize')) ? 1 : 0);
set_config('system','cloud_report_disksize',$cloud_disksize);
$cloud_disksize = ((x($_POST, 'cloud_disksize')) ? 1 : 0);
set_config('system', 'cloud_report_disksize', $cloud_disksize);
$thumbnail_security = ((x($_POST,'thumbnail_security')) ? intval($_POST['thumbnail_security']) : 0);
set_config('system', 'thumbnail_security' , $thumbnail_security);
$thumbnail_security = ((x($_POST, 'thumbnail_security')) ? intval($_POST['thumbnail_security']) : 0);
set_config('system', 'thumbnail_security', $thumbnail_security);
$inline_pdf = ((x($_POST,'inline_pdf')) ? intval($_POST['inline_pdf']) : 0);
set_config('system', 'inline_pdf' , $inline_pdf);
$inline_pdf = ((x($_POST, 'inline_pdf')) ? intval($_POST['inline_pdf']) : 0);
set_config('system', 'inline_pdf', $inline_pdf);
$ws = $this->trim_array_elems(explode("\n",$_POST['allowed_sites']));
set_config('system','allowed_sites',$ws);
$ws = $this->trim_array_elems(explode("\n", $_POST['allowed_sites']));
set_config('system', 'allowed_sites', $ws);
$bs = $this->trim_array_elems(explode("\n",$_POST['denied_sites']));
set_config('system','denied_sites',$bs);
$bs = $this->trim_array_elems(explode("\n", $_POST['denied_sites']));
set_config('system', 'denied_sites', $bs);
$wc = $this->trim_array_elems(explode("\n",$_POST['allowed_channels']));
set_config('system','allowed_channels',$wc);
$wc = $this->trim_array_elems(explode("\n", $_POST['allowed_channels']));
set_config('system', 'allowed_channels', $wc);
$bc = $this->trim_array_elems(explode("\n",$_POST['denied_channels']));
set_config('system','denied_channels',$bc);
$bc = $this->trim_array_elems(explode("\n", $_POST['denied_channels']));
set_config('system', 'denied_channels', $bc);
$ws = $this->trim_array_elems(explode("\n",$_POST['pubstream_allowed_sites']));
set_config('system','pubstream_allowed_sites',$ws);
$ws = $this->trim_array_elems(explode("\n", $_POST['pubstream_allowed_sites']));
set_config('system', 'pubstream_allowed_sites', $ws);
$bs = $this->trim_array_elems(explode("\n",$_POST['pubstream_denied_sites']));
set_config('system','pubstream_denied_sites',$bs);
$bs = $this->trim_array_elems(explode("\n", $_POST['pubstream_denied_sites']));
set_config('system', 'pubstream_denied_sites', $bs);
$wc = $this->trim_array_elems(explode("\n",$_POST['pubstream_allowed_channels']));
set_config('system','pubstream_allowed_channels',$wc);
$wc = $this->trim_array_elems(explode("\n", $_POST['pubstream_allowed_channels']));
set_config('system', 'pubstream_allowed_channels', $wc);
$bc = $this->trim_array_elems(explode("\n",$_POST['pubstream_denied_channels']));
set_config('system','pubstream_denied_channels',$bc);
$bc = $this->trim_array_elems(explode("\n", $_POST['pubstream_denied_channels']));
set_config('system', 'pubstream_denied_channels', $bc);
$embed_sslonly = ((x($_POST,'embed_sslonly')) ? True : False);
set_config('system','embed_sslonly',$embed_sslonly);
$embed_sslonly = ((x($_POST, 'embed_sslonly')) ? True : False);
set_config('system', 'embed_sslonly', $embed_sslonly);
$we = $this->trim_array_elems(explode("\n",$_POST['embed_allow']));
set_config('system','embed_allow',$we);
$we = $this->trim_array_elems(explode("\n", $_POST['embed_allow']));
set_config('system', 'embed_allow', $we);
$be = $this->trim_array_elems(explode("\n",$_POST['embed_deny']));
set_config('system','embed_deny',$be);
$be = $this->trim_array_elems(explode("\n", $_POST['embed_deny']));
set_config('system', 'embed_deny', $be);
$ts = ((x($_POST,'transport_security')) ? True : False);
set_config('system','transport_security_header',$ts);
$ts = ((x($_POST, 'transport_security')) ? True : False);
set_config('system', 'transport_security_header', $ts);
$cs = ((x($_POST,'content_security')) ? True : False);
set_config('system','content_security_policy',$cs);
$cs = ((x($_POST, 'content_security')) ? True : False);
set_config('system', 'content_security_policy', $cs);
goaway(z_root() . '/admin/security');
}
goaway(z_root() . '/admin/security');
}
public function get()
{
function get() {
$allowedsites = get_config('system', 'allowed_sites');
$allowedsites_str = ((is_array($allowedsites)) ? implode("\n", $allowedsites) : '');
$allowedsites = get_config('system','allowed_sites');
$allowedsites_str = ((is_array($allowedsites)) ? implode("\n",$allowedsites) : '');
$deniedsites = get_config('system','denied_sites');
$deniedsites_str = ((is_array($deniedsites)) ? implode("\n",$deniedsites) : '');
$deniedsites = get_config('system', 'denied_sites');
$deniedsites_str = ((is_array($deniedsites)) ? implode("\n", $deniedsites) : '');
$allowedchannels = get_config('system','allowed_channels');
$allowedchannels_str = ((is_array($allowedchannels)) ? implode("\n",$allowedchannels) : '');
$allowedchannels = get_config('system', 'allowed_channels');
$allowedchannels_str = ((is_array($allowedchannels)) ? implode("\n", $allowedchannels) : '');
$deniedchannels = get_config('system','denied_channels');
$deniedchannels_str = ((is_array($deniedchannels)) ? implode("\n",$deniedchannels) : '');
$deniedchannels = get_config('system', 'denied_channels');
$deniedchannels_str = ((is_array($deniedchannels)) ? implode("\n", $deniedchannels) : '');
$psallowedsites = get_config('system','pubstream_allowed_sites');
$psallowedsites_str = ((is_array($psallowedsites)) ? implode("\n",$psallowedsites) : '');
$psallowedsites = get_config('system', 'pubstream_allowed_sites');
$psallowedsites_str = ((is_array($psallowedsites)) ? implode("\n", $psallowedsites) : '');
$psdeniedsites = get_config('system','pubstream_denied_sites');
$psdeniedsites_str = ((is_array($psdeniedsites)) ? implode("\n",$psdeniedsites) : '');
$psdeniedsites = get_config('system', 'pubstream_denied_sites');
$psdeniedsites_str = ((is_array($psdeniedsites)) ? implode("\n", $psdeniedsites) : '');
$psallowedchannels = get_config('system','pubstream_allowed_channels');
$psallowedchannels_str = ((is_array($psallowedchannels)) ? implode("\n",$psallowedchannels) : '');
$psallowedchannels = get_config('system', 'pubstream_allowed_channels');
$psallowedchannels_str = ((is_array($psallowedchannels)) ? implode("\n", $psallowedchannels) : '');
$psdeniedchannels = get_config('system','pubstream_denied_channels');
$psdeniedchannels_str = ((is_array($psdeniedchannels)) ? implode("\n",$psdeniedchannels) : '');
$psdeniedchannels = get_config('system', 'pubstream_denied_channels');
$psdeniedchannels_str = ((is_array($psdeniedchannels)) ? implode("\n", $psdeniedchannels) : '');
$allowedembeds = get_config('system','embed_allow');
$allowedembeds_str = ((is_array($allowedembeds)) ? implode("\n",$allowedembeds) : '');
$allowedembeds = get_config('system', 'embed_allow');
$allowedembeds_str = ((is_array($allowedembeds)) ? implode("\n", $allowedembeds) : '');
$deniedembeds = get_config('system','embed_deny');
$deniedembeds_str = ((is_array($deniedembeds)) ? implode("\n",$deniedembeds) : '');
$deniedembeds = get_config('system', 'embed_deny');
$deniedembeds_str = ((is_array($deniedembeds)) ? implode("\n", $deniedembeds) : '');
$embed_coop = intval(get_config('system','embed_coop'));
$embed_coop = intval(get_config('system', 'embed_coop'));
if((! $allowedembeds) && (! $deniedembeds)) {
$embedhelp1 = t("By default, unfiltered HTML is allowed in embedded media. This is inherently insecure.");
}
if ((!$allowedembeds) && (!$deniedembeds)) {
$embedhelp1 = t("By default, unfiltered HTML is allowed in embedded media. This is inherently insecure.");
}
$embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:");
$embedhelp3 = t("https://youtube.com/<br>https://www.youtube.com/<br>https://youtu.be/<br>https://vimeo.com/<br>https://soundcloud.com/<br>");
$embedhelp4 = t("All other embedded content will be filtered, <strong>unless</strong> embedded content from that site is explicitly blocked.");
$embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:");
$embedhelp3 = t("https://youtube.com/<br>https://www.youtube.com/<br>https://youtu.be/<br>https://vimeo.com/<br>https://soundcloud.com/<br>");
$embedhelp4 = t("All other embedded content will be filtered, <strong>unless</strong> embedded content from that site is explicitly blocked.");
$t = get_markup_template('admin_security.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Security'),
'$form_security_token' => get_form_security_token('admin_security'),
'$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated.")),
'$block_public_search' => array('block_public_search', t("Block public search"), get_config('system','block_public_search', 1), t("Prevent access to search content unless you are currently authenticated.")),
'$block_public_dir' => [ 'block_public_directory', t('Block directory from visitors'), get_config('system','block_public_directory',true), t('Only allow authenticated access to directory.') ],
'$localdir_hide' => [ 'localdir_hide', t('Hide local directory'), intval(get_config('system','localdir_hide')), t('Only use the global directory') ],
'$cloud_noroot' => [ 'cloud_noroot', t('Provide a cloud root directory'), 1 - intval(get_config('system','cloud_disable_siteroot',true)), t('The cloud root directory lists all channel names which provide public files. Otherwise only the names of connections are shown.') ],
'$cloud_disksize' => [ 'cloud_disksize', t('Show total disk space available to cloud uploads'), intval(get_config('system','cloud_report_disksize')), '' ],
'$thumbnail_security' => [ 'thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.") ],
$t = get_markup_template('admin_security.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Security'),
'$form_security_token' => get_form_security_token('admin_security'),
'$block_public' => array('block_public', t("Block public"), get_config('system', 'block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated.")),
'$block_public_search' => array('block_public_search', t("Block public search"), get_config('system', 'block_public_search', 1), t("Prevent access to search content unless you are currently authenticated.")),
'$block_public_dir' => ['block_public_directory', t('Block directory from visitors'), get_config('system', 'block_public_directory', true), t('Only allow authenticated access to directory.')],
'$localdir_hide' => ['localdir_hide', t('Hide local directory'), intval(get_config('system', 'localdir_hide')), t('Only use the global directory')],
'$cloud_noroot' => ['cloud_noroot', t('Provide a cloud root directory'), 1 - intval(get_config('system', 'cloud_disable_siteroot', true)), t('The cloud root directory lists all channel names which provide public files. Otherwise only the names of connections are shown.')],
'$cloud_disksize' => ['cloud_disksize', t('Show total disk space available to cloud uploads'), intval(get_config('system', 'cloud_report_disksize')), ''],
'$thumbnail_security' => ['thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system', 'thumbnail_security', 0), t("WARNING: SVG images may contain malicious code.")],
'$inline_pdf' => [ 'inline_pdf', t("Allow embedded (inline) PDF files"), get_config('system','inline_pdf',0), '' ],
'$anonymous_comments' => [ 'anonymous_comments', t('Permit anonymous comments'), intval(get_config('system','anonymous_comments')), t('Moderation will be performed by channels that select this comment option.') ],
'$transport_security' => array('transport_security', t('Set "Transport Security" HTTP header'),intval(get_config('system','transport_security_header')),''),
'$content_security' => array('content_security', t('Set "Content Security Policy" HTTP header'),intval(get_config('system','content_security_policy')),''),
'$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
'$not_allowed_email' => array('not_allowed_email', t("Not allowed email domains"), get_config('system','not_allowed_email'), t("Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined.")),
'$allowed_sites' => array('allowed_sites', t('Allow communications only from these sites'), $allowedsites_str, t('One site per line. Leave empty to allow communication from anywhere by default')),
'$denied_sites' => array('denied_sites', t('Block communications from these sites'), $deniedsites_str, ''),
'$allowed_channels' => array('allowed_channels', t('Allow communications only from these channels'), $allowedchannels_str, t('One channel (hash) per line. Leave empty to allow communication from any channel by default')),
'$denied_channels' => array('denied_channels', t('Block communications from these channels'), $deniedchannels_str, ''),
'$inline_pdf' => ['inline_pdf', t("Allow embedded (inline) PDF files"), get_config('system', 'inline_pdf', 0), ''],
'$anonymous_comments' => ['anonymous_comments', t('Permit anonymous comments'), intval(get_config('system', 'anonymous_comments')), t('Moderation will be performed by channels that select this comment option.')],
'$transport_security' => array('transport_security', t('Set "Transport Security" HTTP header'), intval(get_config('system', 'transport_security_header')), ''),
'$content_security' => array('content_security', t('Set "Content Security Policy" HTTP header'), intval(get_config('system', 'content_security_policy')), ''),
'$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system', 'allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
'$not_allowed_email' => array('not_allowed_email', t("Not allowed email domains"), get_config('system', 'not_allowed_email'), t("Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined.")),
'$allowed_sites' => array('allowed_sites', t('Allow communications only from these sites'), $allowedsites_str, t('One site per line. Leave empty to allow communication from anywhere by default')),
'$denied_sites' => array('denied_sites', t('Block communications from these sites'), $deniedsites_str, ''),
'$allowed_channels' => array('allowed_channels', t('Allow communications only from these channels'), $allowedchannels_str, t('One channel (hash) per line. Leave empty to allow communication from any channel by default')),
'$denied_channels' => array('denied_channels', t('Block communications from these channels'), $deniedchannels_str, ''),
'$psallowed_sites' => array('pubstream_allowed_sites', t('Allow public stream communications only from these sites'), $psallowedsites_str, t('One site per line. Leave empty to allow communication from anywhere by default')),
'$psdenied_sites' => array('pubstream_denied_sites', t('Block public stream communications from these sites'), $psdeniedsites_str, ''),
'$psallowed_channels' => array('pubstream_allowed_channels', t('Allow public stream communications only from these channels'), $psallowedchannels_str, t('One channel (hash) per line. Leave empty to allow communication from any channel by default')),
'$psdenied_channels' => array('pubstream_denied_channels', t('Block public stream communications from these channels'), $psdeniedchannels_str, ''),
'$psallowed_sites' => array('pubstream_allowed_sites', t('Allow public stream communications only from these sites'), $psallowedsites_str, t('One site per line. Leave empty to allow communication from anywhere by default')),
'$psdenied_sites' => array('pubstream_denied_sites', t('Block public stream communications from these sites'), $psdeniedsites_str, ''),
'$psallowed_channels' => array('pubstream_allowed_channels', t('Allow public stream communications only from these channels'), $psallowedchannels_str, t('One channel (hash) per line. Leave empty to allow communication from any channel by default')),
'$psdenied_channels' => array('pubstream_denied_channels', t('Block public stream communications from these channels'), $psdeniedchannels_str, ''),
'$embed_sslonly' => array('embed_sslonly',t('Only allow embeds from secure (SSL) websites and links.'), intval(get_config('system','embed_sslonly')),''),
'$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $allowedembeds_str, t('One site per line. By default embedded content is filtered.')),
'$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $deniedembeds_str, ''),
'$embed_sslonly' => array('embed_sslonly', t('Only allow embeds from secure (SSL) websites and links.'), intval(get_config('system', 'embed_sslonly')), ''),
'$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $allowedembeds_str, t('One site per line. By default embedded content is filtered.')),
'$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $deniedembeds_str, ''),
// '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')),
'$submit' => t('Submit')
));
}
'$submit' => t('Submit')
));
}
function trim_array_elems($arr) {
$narr = [];
public function trim_array_elems($arr)
{
$narr = [];
if($arr && is_array($arr)) {
for($x = 0; $x < count($arr); $x ++) {
$y = trim($arr[$x]);
if($y)
$narr[] = $y;
}
}
return $narr;
}
if ($arr && is_array($arr)) {
for ($x = 0; $x < count($arr); $x++) {
$y = trim($arr[$x]);
if ($y)
$narr[] = $y;
}
}
return $narr;
}
}

View file

@ -6,364 +6,365 @@ use App;
use Zotlabs\Lib\System;
use Zotlabs\Access\PermissionRoles;
class Site {
class Site
{
/**
* @brief POST handler for Admin Site Page.
*
*/
function post() {
/**
* @brief POST handler for Admin Site Page.
*
*/
public function post()
{
if(! is_site_admin()) {
return;
}
if (!is_site_admin()) {
return;
}
if (! x($_POST, 'page_site')) {
return;
}
if (!x($_POST, 'page_site')) {
return;
}
$sys = get_sys_channel();
$sys = get_sys_channel();
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : App::get_hostname());
$sitename = ((x($_POST, 'sitename')) ? notags(trim($_POST['sitename'])) : App::get_hostname());
$admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false);
$siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : '');
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : 'en');
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
$admininfo = ((x($_POST, 'admininfo')) ? trim($_POST['admininfo']) : false);
$siteinfo = ((x($_POST, 'siteinfo')) ? trim($_POST['siteinfo']) : '');
$language = ((x($_POST, 'language')) ? notags(trim($_POST['language'])) : 'en');
$theme = ((x($_POST, 'theme')) ? notags(trim($_POST['theme'])) : '');
// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
$maximagesize = ((x($_POST, 'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
$minimum_age = ((x($_POST,'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13);
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
$invite_only = ((x($_POST,'invite_only')) ? True : False);
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
$register_policy = ((x($_POST, 'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
$minimum_age = ((x($_POST, 'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13);
$access_policy = ((x($_POST, 'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
$invite_only = ((x($_POST, 'invite_only')) ? True : False);
$abandon_days = ((x($_POST, 'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
$site_sellpage = ((x($_POST,'site_sellpage')) ? notags(trim($_POST['site_sellpage'])) : '');
$site_location = ((x($_POST,'site_location')) ? notags(trim($_POST['site_location'])) : '');
$frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
$firstpage = ((x($_POST,'firstpage')) ? notags(trim($_POST['firstpage'])) : 'profiles');
$first_page = ((x($_POST,'first_page')) ? notags(trim($_POST['first_page'])) : 'profiles');
// check value after trim
if(! $first_page) {
$first_page = 'profiles';
}
$mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
$directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : '');
$force_publish = ((x($_POST,'publish_all')) ? True : False);
$open_pubstream = ((x($_POST,'open_pubstream')) ? True : False);
$public_stream_mode = ((x($_POST,'public_stream_mode')) ? intval($_POST['public_stream_mode']) : PUBLIC_STREAM_NONE);
$animations = ((x($_POST,'animations')) ? True : False);
$login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False);
$enable_context_help = ((x($_POST,'enable_context_help')) ? True : False);
$global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
$default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0);
$active_expire_days = ((array_key_exists('active_expire_days',$_POST)) ? intval($_POST['active_expire_days']) : 7);
$max_imported_follow = ((x($_POST,'max_imported_follow')) ? intval(trim($_POST['max_imported_follow'])) : MAX_IMPORTED_FOLLOW);
$register_text = ((x($_POST, 'register_text')) ? notags(trim($_POST['register_text'])) : '');
$site_sellpage = ((x($_POST, 'site_sellpage')) ? notags(trim($_POST['site_sellpage'])) : '');
$site_location = ((x($_POST, 'site_location')) ? notags(trim($_POST['site_location'])) : '');
$frontpage = ((x($_POST, 'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
$firstpage = ((x($_POST, 'firstpage')) ? notags(trim($_POST['firstpage'])) : 'profiles');
$first_page = ((x($_POST, 'first_page')) ? notags(trim($_POST['first_page'])) : 'profiles');
// check value after trim
if (!$first_page) {
$first_page = 'profiles';
}
$mirror_frontpage = ((x($_POST, 'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
$directory_server = ((x($_POST, 'directory_server')) ? trim($_POST['directory_server']) : '');
$force_publish = ((x($_POST, 'publish_all')) ? True : False);
$open_pubstream = ((x($_POST, 'open_pubstream')) ? True : False);
$public_stream_mode = ((x($_POST, 'public_stream_mode')) ? intval($_POST['public_stream_mode']) : PUBLIC_STREAM_NONE);
$animations = ((x($_POST, 'animations')) ? True : False);
$login_on_homepage = ((x($_POST, 'login_on_homepage')) ? True : False);
$enable_context_help = ((x($_POST, 'enable_context_help')) ? True : False);
$global_directory = ((x($_POST, 'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
$no_community_page = !((x($_POST, 'no_community_page')) ? True : False);
$default_expire_days = ((array_key_exists('default_expire_days', $_POST)) ? intval($_POST['default_expire_days']) : 0);
$active_expire_days = ((array_key_exists('active_expire_days', $_POST)) ? intval($_POST['active_expire_days']) : 7);
$max_imported_follow = ((x($_POST, 'max_imported_follow')) ? intval(trim($_POST['max_imported_follow'])) : MAX_IMPORTED_FOLLOW);
$reply_address = ((array_key_exists('reply_address',$_POST) && trim($_POST['reply_address'])) ? trim($_POST['reply_address']) : 'noreply@' . App::get_hostname());
$from_email = ((array_key_exists('from_email',$_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . App::get_hostname());
$from_email_name = ((array_key_exists('from_email_name',$_POST) && trim($_POST['from_email_name'])) ? trim($_POST['from_email_name']) : System::get_site_name());
$reply_address = ((array_key_exists('reply_address', $_POST) && trim($_POST['reply_address'])) ? trim($_POST['reply_address']) : 'noreply@' . App::get_hostname());
$from_email = ((array_key_exists('from_email', $_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . App::get_hostname());
$from_email_name = ((array_key_exists('from_email_name', $_POST) && trim($_POST['from_email_name'])) ? trim($_POST['from_email_name']) : System::get_site_name());
$verifyssl = ((x($_POST,'verifyssl')) ? True : False);
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
$proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
$timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60);
$post_timeout = ((x($_POST,'post_timeout')) ? intval(trim($_POST['post_timeout'])) : 90);
$show_like_counts = ((x($_POST,'show_like_counts')) ? intval(trim($_POST['show_like_counts'])) : 0);
$cache_images = ((x($_POST,'cache_images')) ? intval(trim($_POST['cache_images'])) : 0);
$delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0);
$delivery_batch_count = ((x($_POST,'delivery_batch_count') && $_POST['delivery_batch_count'] > 0)? intval(trim($_POST['delivery_batch_count'])) : 3);
$poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$verifyssl = ((x($_POST, 'verifyssl')) ? True : False);
$proxyuser = ((x($_POST, 'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
$proxy = ((x($_POST, 'proxy')) ? notags(trim($_POST['proxy'])) : '');
$timeout = ((x($_POST, 'timeout')) ? intval(trim($_POST['timeout'])) : 60);
$post_timeout = ((x($_POST, 'post_timeout')) ? intval(trim($_POST['post_timeout'])) : 90);
$show_like_counts = ((x($_POST, 'show_like_counts')) ? intval(trim($_POST['show_like_counts'])) : 0);
$cache_images = ((x($_POST, 'cache_images')) ? intval(trim($_POST['cache_images'])) : 0);
$delivery_interval = ((x($_POST, 'delivery_interval')) ? intval(trim($_POST['delivery_interval'])) : 0);
$delivery_batch_count = ((x($_POST, 'delivery_batch_count') && $_POST['delivery_batch_count'] > 0) ? intval(trim($_POST['delivery_batch_count'])) : 3);
$poll_interval = ((x($_POST, 'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
$maxloadavg = ((x($_POST, 'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
// $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
$ap_contacts = ((x($_POST,'ap_contacts')) ? intval($_POST['ap_contacts']) : 0);
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
$imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : '');
$force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000);
$pub_incl = escape_tags(trim($_POST['pub_incl']));
$pub_excl = escape_tags(trim($_POST['pub_excl']));
$ap_contacts = ((x($_POST, 'ap_contacts')) ? intval($_POST['ap_contacts']) : 0);
$verify_email = ((x($_POST, 'verify_email')) ? 1 : 0);
$imagick_path = ((x($_POST, 'imagick_path')) ? trim($_POST['imagick_path']) : '');
$force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000);
$pub_incl = escape_tags(trim($_POST['pub_incl']));
$pub_excl = escape_tags(trim($_POST['pub_excl']));
$permissions_role = escape_tags(trim($_POST['permissions_role']));
$permissions_role = escape_tags(trim($_POST['permissions_role']));
// set_config('system', 'feed_contacts', $feed_contacts);
set_config('system', 'activitypub', $ap_contacts);
set_config('system', 'delivery_interval', $delivery_interval);
set_config('system', 'delivery_batch_count', $delivery_batch_count);
set_config('system', 'poll_interval', $poll_interval);
set_config('system', 'maxloadavg', $maxloadavg);
set_config('system', 'frontpage', $frontpage);
set_config('system', 'cache_images', $cache_images);
set_config('system', 'sellpage', $site_sellpage);
set_config('system', 'workflow_channel_next', $first_page);
set_config('system', 'site_location', $site_location);
set_config('system', 'mirror_frontpage', $mirror_frontpage);
set_config('system', 'sitename', $sitename);
set_config('system', 'login_on_homepage', $login_on_homepage);
set_config('system', 'enable_context_help', $enable_context_help);
set_config('system', 'verify_email', $verify_email);
set_config('system', 'default_expire_days', $default_expire_days);
set_config('system', 'active_expire_days', $active_expire_days);
set_config('system', 'reply_address', $reply_address);
set_config('system', 'from_email', $from_email);
set_config('system', 'from_email_name' , $from_email_name);
set_config('system', 'imagick_convert_path' , $imagick_path);
set_config('system', 'default_permissions_role', $permissions_role);
set_config('system', 'show_like_counts', $show_like_counts);
set_config('system', 'pubstream_incl',$pub_incl);
set_config('system', 'pubstream_excl',$pub_excl);
set_config('system', 'max_imported_follow', $max_imported_follow);
set_config('system', 'animated_avatars', $animations);
set_config('system', 'activitypub', $ap_contacts);
set_config('system', 'delivery_interval', $delivery_interval);
set_config('system', 'delivery_batch_count', $delivery_batch_count);
set_config('system', 'poll_interval', $poll_interval);
set_config('system', 'maxloadavg', $maxloadavg);
set_config('system', 'frontpage', $frontpage);
set_config('system', 'cache_images', $cache_images);
set_config('system', 'sellpage', $site_sellpage);
set_config('system', 'workflow_channel_next', $first_page);
set_config('system', 'site_location', $site_location);
set_config('system', 'mirror_frontpage', $mirror_frontpage);
set_config('system', 'sitename', $sitename);
set_config('system', 'login_on_homepage', $login_on_homepage);
set_config('system', 'enable_context_help', $enable_context_help);
set_config('system', 'verify_email', $verify_email);
set_config('system', 'default_expire_days', $default_expire_days);
set_config('system', 'active_expire_days', $active_expire_days);
set_config('system', 'reply_address', $reply_address);
set_config('system', 'from_email', $from_email);
set_config('system', 'from_email_name', $from_email_name);
set_config('system', 'imagick_convert_path', $imagick_path);
set_config('system', 'default_permissions_role', $permissions_role);
set_config('system', 'show_like_counts', $show_like_counts);
set_config('system', 'pubstream_incl', $pub_incl);
set_config('system', 'pubstream_excl', $pub_excl);
set_config('system', 'max_imported_follow', $max_imported_follow);
set_config('system', 'animated_avatars', $animations);
if ($directory_server) {
set_config('system','directory_server',$directory_server);
}
if ($directory_server) {
set_config('system', 'directory_server', $directory_server);
}
if ($admininfo == '') {
del_config('system', 'admininfo');
}
else {
require_once('include/text.php');
linkify_tags($admininfo, local_channel());
set_config('system', 'admininfo', $admininfo);
}
set_config('system','siteinfo',$siteinfo);
if ($admininfo == '') {
del_config('system', 'admininfo');
} else {
require_once('include/text.php');
linkify_tags($admininfo, local_channel());
set_config('system', 'admininfo', $admininfo);
}
set_config('system', 'siteinfo', $siteinfo);
// sync sitename and siteinfo updates to the system channel
// sync sitename and siteinfo updates to the system channel
q("update profile set about = '%s' where uid = %d and is_default = 1",
dbesc($siteinfo),
intval($sys['channel_id'])
);
q("update profile set fullname = '%s' where uid = %d and is_default = 1",
dbesc($sitename),
intval($sys['channel_id'])
);
q("update channel set channel_name = '%s' where channel_id = %d",
dbesc($sitename),
intval($sys['channel_id'])
);
q("update xchan set xchan_name = '%s' , xchan_name_updated = '%s' where xchan_hash = '%s'",
dbesc($sitename),
dbesc(datetime_convert()),
dbesc($sys['channel_hash'])
);
q("update profile set about = '%s' where uid = %d and is_default = 1",
dbesc($siteinfo),
intval($sys['channel_id'])
);
q("update profile set fullname = '%s' where uid = %d and is_default = 1",
dbesc($sitename),
intval($sys['channel_id'])
);
q("update channel set channel_name = '%s' where channel_id = %d",
dbesc($sitename),
intval($sys['channel_id'])
);
q("update xchan set xchan_name = '%s' , xchan_name_updated = '%s' where xchan_hash = '%s'",
dbesc($sitename),
dbesc(datetime_convert()),
dbesc($sys['channel_hash'])
);
set_config('system', 'language', $language);
set_config('system', 'theme', $theme);
// set_config('system','site_channel', $site_channel);
set_config('system','maximagesize', $maximagesize);
set_config('system', 'language', $language);
set_config('system', 'theme', $theme);
// set_config('system','site_channel', $site_channel);
set_config('system', 'maximagesize', $maximagesize);
set_config('system','register_policy', $register_policy);
set_config('system','minimum_age', $minimum_age);
set_config('system','invitation_only', $invite_only);
set_config('system','access_policy', $access_policy);
set_config('system','account_abandon_days', $abandon_days);
set_config('system','register_text', $register_text);
set_config('system','publish_all', $force_publish);
set_config('system','public_stream_mode', $public_stream_mode);
set_config('system','open_pubstream', $open_pubstream);
set_config('system','force_queue_threshold', $force_queue);
if ($global_directory == '') {
del_config('system', 'directory_submit_url');
} else {
set_config('system', 'directory_submit_url', $global_directory);
}
set_config('system', 'register_policy', $register_policy);
set_config('system', 'minimum_age', $minimum_age);
set_config('system', 'invitation_only', $invite_only);
set_config('system', 'access_policy', $access_policy);
set_config('system', 'account_abandon_days', $abandon_days);
set_config('system', 'register_text', $register_text);
set_config('system', 'publish_all', $force_publish);
set_config('system', 'public_stream_mode', $public_stream_mode);
set_config('system', 'open_pubstream', $open_pubstream);
set_config('system', 'force_queue_threshold', $force_queue);
if ($global_directory == '') {
del_config('system', 'directory_submit_url');
} else {
set_config('system', 'directory_submit_url', $global_directory);
}
set_config('system','no_community_page', $no_community_page);
set_config('system','no_utf', $no_utf);
set_config('system','verifyssl', $verifyssl);
set_config('system','proxyuser', $proxyuser);
set_config('system','proxy', $proxy);
set_config('system','curl_timeout', $timeout);
set_config('system','curl_post_timeout', $post_timeout);
set_config('system', 'no_community_page', $no_community_page);
set_config('system', 'no_utf', $no_utf);
set_config('system', 'verifyssl', $verifyssl);
set_config('system', 'proxyuser', $proxyuser);
set_config('system', 'proxy', $proxy);
set_config('system', 'curl_timeout', $timeout);
set_config('system', 'curl_post_timeout', $post_timeout);
info( t('Site settings updated.') . EOL);
goaway(z_root() . '/admin/site' );
}
info(t('Site settings updated.') . EOL);
goaway(z_root() . '/admin/site');
}
/**
* @brief Admin page site.
*
* @return string with HTML
*/
/**
* @brief Admin page site.
*
* @return string with HTML
*/
function get() {
public function get()
{
/* Installed langs */
$lang_choices = [];
$langs = glob('view/*/strings.php');
/* Installed langs */
$lang_choices = [];
$langs = glob('view/*/strings.php');
if (is_array($langs) && count($langs)) {
if (! in_array('view/en/strings.php',$langs))
$langs[] = 'view/en/';
asort($langs);
foreach ($langs as $l) {
$t = explode("/",$l);
$lang_choices[$t[1]] = $t[1];
}
}
if (is_array($langs) && count($langs)) {
if (!in_array('view/en/strings.php', $langs))
$langs[] = 'view/en/';
asort($langs);
foreach ($langs as $l) {
$t = explode("/", $l);
$lang_choices[$t[1]] = $t[1];
}
}
/* Installed themes */
$theme_choices_mobile["---"] = t("Default");
$theme_choices = [];
$files = glob('view/theme/*');
if ($files) {
foreach ($files as $file) {
$vars = '';
$f = basename($file);
/* Installed themes */
$theme_choices_mobile["---"] = t("Default");
$theme_choices = [];
$files = glob('view/theme/*');
if ($files) {
foreach ($files as $file) {
$vars = '';
$f = basename($file);
$info = get_theme_info($f);
$compatible = check_plugin_versions($info);
if (! $compatible) {
$theme_choices[$f] = $theme_choices_mobile[$f] = sprintf(t('%s - (Incompatible)'), $f);
continue;
}
$info = get_theme_info($f);
$compatible = check_plugin_versions($info);
if (!$compatible) {
$theme_choices[$f] = $theme_choices_mobile[$f] = sprintf(t('%s - (Incompatible)'), $f);
continue;
}
if (file_exists($file . '/library'))
continue;
if (file_exists($file . '/mobile'))
$vars = t('mobile');
if (file_exists($file . '/experimental'))
$vars .= t('experimental');
if (file_exists($file . '/unsupported'))
$vars .= t('unsupported');
if ($vars) {
$theme_choices[$f] = $f . ' (' . $vars . ')';
$theme_choices_mobile[$f] = $f . ' (' . $vars . ')';
}
else {
$theme_choices[$f] = $f;
$theme_choices_mobile[$f] = $f;
}
}
}
if (file_exists($file . '/library'))
continue;
if (file_exists($file . '/mobile'))
$vars = t('mobile');
if (file_exists($file . '/experimental'))
$vars .= t('experimental');
if (file_exists($file . '/unsupported'))
$vars .= t('unsupported');
if ($vars) {
$theme_choices[$f] = $f . ' (' . $vars . ')';
$theme_choices_mobile[$f] = $f . ' (' . $vars . ')';
} else {
$theme_choices[$f] = $f;
$theme_choices_mobile[$f] = $f;
}
}
}
$dir_choices = null;
$dirmode = get_config('system','directory_mode');
$realm = get_directory_realm();
$dir_choices = null;
$dirmode = get_config('system', 'directory_mode');
$realm = get_directory_realm();
// directory server should not be set or settable unless we are a directory client
// avoid older redmatrix servers which don't have modern encryption
// directory server should not be set or settable unless we are a directory client
// avoid older redmatrix servers which don't have modern encryption
if ($dirmode == DIRECTORY_MODE_NORMAL) {
$x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s' and site_dead = 0",
intval(DIRECTORY_MODE_SECONDARY),
intval(DIRECTORY_MODE_PRIMARY),
dbesc($realm)
);
if ($x) {
$dir_choices = [];
foreach ($x as $xx) {
$dir_choices[$xx['site_url']] = $xx['site_url'];
}
}
}
if ($dirmode == DIRECTORY_MODE_NORMAL) {
$x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s' and site_dead = 0",
intval(DIRECTORY_MODE_SECONDARY),
intval(DIRECTORY_MODE_PRIMARY),
dbesc($realm)
);
if ($x) {
$dir_choices = [];
foreach ($x as $xx) {
$dir_choices[$xx['site_url']] = $xx['site_url'];
}
}
}
/* Admin Info */
/* Admin Info */
$admininfo = get_config('system', 'admininfo');
$admininfo = get_config('system', 'admininfo');
/* Register policy */
$register_choices = [
REGISTER_CLOSED => t("No"),
REGISTER_APPROVE => t("Yes - with approval"),
REGISTER_OPEN => t("Yes")
];
/* Register policy */
$register_choices = [
REGISTER_CLOSED => t("No"),
REGISTER_APPROVE => t("Yes - with approval"),
REGISTER_OPEN => t("Yes")
];
/* Acess policy */
$access_choices = [
ACCESS_PRIVATE => t("My site is not a public server"),
ACCESS_FREE => t("My site provides free public access"),
ACCESS_PAID => t("My site provides paid public access"),
ACCESS_TIERED => t("My site provides free public access and premium paid plans")
];
/* Acess policy */
$access_choices = [
ACCESS_PRIVATE => t("My site is not a public server"),
ACCESS_FREE => t("My site provides free public access"),
ACCESS_PAID => t("My site provides paid public access"),
ACCESS_TIERED => t("My site provides free public access and premium paid plans")
];
$perm_roles = PermissionRoles::roles();
$default_role = get_config('system','default_permissions_role','social');
$perm_roles = PermissionRoles::roles();
$default_role = get_config('system', 'default_permissions_role', 'social');
$role = [ 'permissions_role' , t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'),$perm_roles ];
$role = ['permissions_role', t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'), $perm_roles];
$homelogin = get_config('system','login_on_homepage');
$enable_context_help = get_config('system','enable_context_help');
$homelogin = get_config('system', 'login_on_homepage');
$enable_context_help = get_config('system', 'enable_context_help');
return replace_macros(get_markup_template('admin_site.tpl'), [
'$title' => t('Administration'),
'$page' => t('Site'),
'$submit' => t('Submit'),
'$h_basic' => t('Site Configuration'),
'$registration' => t('Registration'),
'$upload' => t('File upload'),
'$corporate' => t('Policies'),
'$advanced' => t('Advanced'),
'$baseurl' => z_root(),
'$sitename' => [ 'sitename', t("Site name"), htmlspecialchars(get_config('system','sitename', App::get_hostname()), ENT_QUOTES, 'UTF-8'),'' ],
'$admininfo' => [ 'admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode may be used here.") ],
'$siteinfo' => [ 'siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode may be used here.") ],
'$language' => [ 'language', t("System language"), get_config('system','language','en'), "", $lang_choices ],
'$theme' => [ 'theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices ],
return replace_macros(get_markup_template('admin_site.tpl'), [
'$title' => t('Administration'),
'$page' => t('Site'),
'$submit' => t('Submit'),
'$h_basic' => t('Site Configuration'),
'$registration' => t('Registration'),
'$upload' => t('File upload'),
'$corporate' => t('Policies'),
'$advanced' => t('Advanced'),
'$baseurl' => z_root(),
'$sitename' => ['sitename', t("Site name"), htmlspecialchars(get_config('system', 'sitename', App::get_hostname()), ENT_QUOTES, 'UTF-8'), ''],
'$admininfo' => ['admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode may be used here.")],
'$siteinfo' => ['siteinfo', t('Site Information'), get_config('system', 'siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode may be used here.")],
'$language' => ['language', t("System language"), get_config('system', 'language', 'en'), "", $lang_choices],
'$theme' => ['theme', t("System theme"), get_config('system', 'theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices],
// '$theme_mobile' => [ 'theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile ],
// '$site_channel' => [ 'site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel") ],
'$ap_contacts' => [ 'ap_contacts', t('ActivityPub protocol'),get_config('system','activitypub', ACTIVITYPUB_ENABLED),t('Provides access to software supporting the ActivityPub protocol.') ],
'$maximagesize' => [ 'maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.") ],
'$cache_images' => [ 'cache_images', t('Cache all public images'), intval(get_config('system','cache_images',1)), t('If disabled, proxy non-SSL images, but do not store locally') ],
'$register_policy' => [ 'register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices ],
'$invite_only' => [ 'invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. New member registration must be allowed for this to work.") ],
'$invite_working' => defined('INVITE_WORKING'),
'$minimum_age' => [ 'minimum_age', t("Minimum age"), (x(get_config('system','minimum_age'))?get_config('system','minimum_age'):13), t("Minimum age (in years) for who may register on this site.") ],
'$access_policy' => [ 'access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), t("If a public server policy is selected, this information may be displayed on the public server site list."), $access_choices ],
'$register_text' => [ 'register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.") ],
'$role' => $role,
'$frontpage' => [ 'frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.") ],
'$mirror_frontpage' => [ 'mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting') ],
'$abandon_days' => [ 'abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.') ],
'$block_public_dir' => [ 'block_public_directory', t('Block directory from visitors'), get_config('system','block_public_directory',true), t('Only allow authenticated access to directory.') ],
'$verify_email' => [ 'verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).") ],
'$force_publish' => [ 'publish_all', t("Force publish in directory"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.") ],
'$ap_contacts' => ['ap_contacts', t('ActivityPub protocol'), get_config('system', 'activitypub', ACTIVITYPUB_ENABLED), t('Provides access to software supporting the ActivityPub protocol.')],
'$maximagesize' => ['maximagesize', t("Maximum image size"), intval(get_config('system', 'maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")],
'$cache_images' => ['cache_images', t('Cache all public images'), intval(get_config('system', 'cache_images', 1)), t('If disabled, proxy non-SSL images, but do not store locally')],
'$register_policy' => ['register_policy', t("Does this site allow new member registration?"), get_config('system', 'register_policy'), "", $register_choices],
'$invite_only' => ['invite_only', t("Invitation only"), get_config('system', 'invitation_only'), t("Only allow new member registrations with an invitation code. New member registration must be allowed for this to work.")],
'$invite_working' => defined('INVITE_WORKING'),
'$minimum_age' => ['minimum_age', t("Minimum age"), (x(get_config('system', 'minimum_age')) ? get_config('system', 'minimum_age') : 13), t("Minimum age (in years) for who may register on this site.")],
'$access_policy' => ['access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system', 'access_policy'), t("If a public server policy is selected, this information may be displayed on the public server site list."), $access_choices],
'$register_text' => ['register_text', t("Register text"), htmlspecialchars(get_config('system', 'register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")],
'$role' => $role,
'$frontpage' => ['frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system', 'frontpage'), t("example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")],
'$mirror_frontpage' => ['mirror_frontpage', t("Preserve site homepage URL"), get_config('system', 'mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')],
'$abandon_days' => ['abandon_days', t('Accounts abandoned after x days'), get_config('system', 'account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')],
'$block_public_dir' => ['block_public_directory', t('Block directory from visitors'), get_config('system', 'block_public_directory', true), t('Only allow authenticated access to directory.')],
'$verify_email' => ['verify_email', t("Verify Email Addresses"), get_config('system', 'verify_email'), t("Check to verify email addresses used in account registration (recommended).")],
'$force_publish' => ['publish_all', t("Force publish in directory"), get_config('system', 'publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")],
'$public_stream_mode' => [ 'public_stream_mode', t('Public stream'), intval(get_config('system','public_stream_mode',0)), t('Provide a Public stream on your site. This content is unmoderated.'), [
0 => t('the Public stream is disabled'),
1 => t('the Public stream contains public conversations from this site only'),
2 => t('the Public stream contains public conversations from anywhere on the internet'),
]],
'$public_stream_mode' => ['public_stream_mode', t('Public stream'), intval(get_config('system', 'public_stream_mode', 0)), t('Provide a Public stream on your site. This content is unmoderated.'), [
0 => t('the Public stream is disabled'),
1 => t('the Public stream contains public conversations from this site only'),
2 => t('the Public stream contains public conversations from anywhere on the internet'),
]],
'$open_pubstream' => [ 'open_pubstream', t('Allow anybody on the internet to access the Public stream'), get_config('system','open_pubstream',0), t('Default is to only allow viewing by site members. Warning: this content is unmoderated.') ],
'$show_like_counts' => [ 'show_like_counts', t('Show numbers of likes and dislikes in conversations'), get_config('system','show_like_counts',1), t('If disabled, the presence of likes and dislikes will be shown, but without totals.') ],
'$animations' => [ 'animations', t('Permit animated profile photos'), get_config('system','animated_avatars',true), t('Changing this may take several days to work through the system') ],
'$incl' => [ 'pub_incl',t('Only import Public stream posts with this text'), get_config('system','pubstream_incl'),t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts') ],
'$excl' => [ 'pub_excl',t('Do not import Public stream posts with this text'), get_config('system','pubstream_excl'),t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts') ],
'$max_imported_follow' => [ 'max_imported_follow', t('Maximum number of imported friends of friends'), get_config('system','max_imported_follow', MAX_IMPORTED_FOLLOW), t('Warning: higher numbers will improve the quality of friend suggestions and directory results but can exponentially increase resource usage') ],
'$login_on_homepage' => [ 'login_on_homepage', t("Login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.") ],
'$enable_context_help' => [ 'enable_context_help', t("Enable context help"),((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0) , t("Display contextual help for the current page when the help button is pressed.") ],
'$reply_address' => [ 'reply_address', t('Reply-to email address for system generated email.'), get_config('system','reply_address','noreply@' . App::get_hostname()),'' ],
'$from_email' => [ 'from_email', t('Sender (From) email address for system generated email.'), get_config('system','from_email','Administrator@' . App::get_hostname()),'' ],
'$from_email_name' => [ 'from_email_name', t('Display name of email sender for system generated email.'), get_config('system','from_email_name', System::get_site_name()),'' ],
'$directory_server' => (($dir_choices) ? [ 'directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices ] : null),
'$proxyuser' => [ 'proxyuser', t("Proxy user"), get_config('system','proxyuser'), "" ],
'$proxy' => [ 'proxy', t("Proxy URL"), get_config('system','proxy'), "" ],
'$timeout' => [ 'timeout', t("Network fetch timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).") ],
'$post_timeout' => [ 'post_timeout', t("Network post timeout"), (x(get_config('system','curl_post_timeout'))?get_config('system','curl_post_timeout'):90), t("Value is in seconds. Set to 0 for unlimited (not recommended).") ],
'$delivery_interval' => [ 'delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.") ],
'$delivery_batch_count' => [ 'delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):3), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.") ],
'$force_queue' => [ 'force_queue', t("Queue Threshold"), get_config('system','force_queue_threshold',3000), t("Always defer immediate delivery if queue contains more than this number of entries.") ],
'$poll_interval' => [ 'poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.") ],
'$imagick_path' => [ 'imagick_path', t("Path to ImageMagick convert program"), get_config('system','imagick_convert_path'), t("If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert") ],
'$maxloadavg' => [ 'maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.") ],
'$default_expire_days' => [ 'default_expire_days', t('Expiration period in days for imported streams and cached images'), intval(get_config('system','default_expire_days',60)), t('0 for no expiration of imported content') ],
'$active_expire_days' => [ 'active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), '' ],
'$sellpage' => [ 'site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root()) ],
'$first_page' => [ 'first_page', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Default: profiles') ],
'$location' => [ 'site_location', t('Site location'), get_config('system','site_location',''), t('Region or country - shared with other sites') ],
'$form_security_token' => get_form_security_token("admin_site"),
]);
}
'$open_pubstream' => ['open_pubstream', t('Allow anybody on the internet to access the Public stream'), get_config('system', 'open_pubstream', 0), t('Default is to only allow viewing by site members. Warning: this content is unmoderated.')],
'$show_like_counts' => ['show_like_counts', t('Show numbers of likes and dislikes in conversations'), get_config('system', 'show_like_counts', 1), t('If disabled, the presence of likes and dislikes will be shown, but without totals.')],
'$animations' => ['animations', t('Permit animated profile photos'), get_config('system', 'animated_avatars', true), t('Changing this may take several days to work through the system')],
'$incl' => ['pub_incl', t('Only import Public stream posts with this text'), get_config('system', 'pubstream_incl'), t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')],
'$excl' => ['pub_excl', t('Do not import Public stream posts with this text'), get_config('system', 'pubstream_excl'), t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')],
'$max_imported_follow' => ['max_imported_follow', t('Maximum number of imported friends of friends'), get_config('system', 'max_imported_follow', MAX_IMPORTED_FOLLOW), t('Warning: higher numbers will improve the quality of friend suggestions and directory results but can exponentially increase resource usage')],
'$login_on_homepage' => ['login_on_homepage', t("Login on Homepage"), ((intval($homelogin) || $homelogin === false) ? 1 : ''), t("Present a login box to visitors on the home page if no other content has been configured.")],
'$enable_context_help' => ['enable_context_help', t("Enable context help"), ((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0), t("Display contextual help for the current page when the help button is pressed.")],
'$reply_address' => ['reply_address', t('Reply-to email address for system generated email.'), get_config('system', 'reply_address', 'noreply@' . App::get_hostname()), ''],
'$from_email' => ['from_email', t('Sender (From) email address for system generated email.'), get_config('system', 'from_email', 'Administrator@' . App::get_hostname()), ''],
'$from_email_name' => ['from_email_name', t('Display name of email sender for system generated email.'), get_config('system', 'from_email_name', System::get_site_name()), ''],
'$directory_server' => (($dir_choices) ? ['directory_server', t("Directory Server URL"), get_config('system', 'directory_server'), t("Default directory server"), $dir_choices] : null),
'$proxyuser' => ['proxyuser', t("Proxy user"), get_config('system', 'proxyuser'), ""],
'$proxy' => ['proxy', t("Proxy URL"), get_config('system', 'proxy'), ""],
'$timeout' => ['timeout', t("Network fetch timeout"), (x(get_config('system', 'curl_timeout')) ? get_config('system', 'curl_timeout') : 60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")],
'$post_timeout' => ['post_timeout', t("Network post timeout"), (x(get_config('system', 'curl_post_timeout')) ? get_config('system', 'curl_post_timeout') : 90), t("Value is in seconds. Set to 0 for unlimited (not recommended).")],
'$delivery_interval' => ['delivery_interval', t("Delivery interval"), (x(get_config('system', 'delivery_interval')) ? get_config('system', 'delivery_interval') : 2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")],
'$delivery_batch_count' => ['delivery_batch_count', t('Deliveries per process'), (x(get_config('system', 'delivery_batch_count')) ? get_config('system', 'delivery_batch_count') : 3), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")],
'$force_queue' => ['force_queue', t("Queue Threshold"), get_config('system', 'force_queue_threshold', 3000), t("Always defer immediate delivery if queue contains more than this number of entries.")],
'$poll_interval' => ['poll_interval', t("Poll interval"), (x(get_config('system', 'poll_interval')) ? get_config('system', 'poll_interval') : 2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")],
'$imagick_path' => ['imagick_path', t("Path to ImageMagick convert program"), get_config('system', 'imagick_convert_path'), t("If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert")],
'$maxloadavg' => ['maxloadavg', t("Maximum Load Average"), ((intval(get_config('system', 'maxloadavg')) > 0) ? get_config('system', 'maxloadavg') : 50), t("Maximum system load before delivery and poll processes are deferred - default 50.")],
'$default_expire_days' => ['default_expire_days', t('Expiration period in days for imported streams and cached images'), intval(get_config('system', 'default_expire_days', 60)), t('0 for no expiration of imported content')],
'$active_expire_days' => ['active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system', 'active_expire_days', 7)), ''],
'$sellpage' => ['site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system', 'sellpage', ''), sprintf(t('Create this page first. Default is %s/register'), z_root())],
'$first_page' => ['first_page', t('Page to display after creating a new channel'), get_config('system', 'workflow_channel_next', 'profiles'), t('Default: profiles')],
'$location' => ['site_location', t('Site location'), get_config('system', 'site_location', ''), t('Region or country - shared with other sites')],
'$form_security_token' => get_form_security_token("admin_site"),
]);
}
}

View file

@ -8,222 +8,228 @@ use Michelf\MarkdownExtra;
/**
* @brief Admin area theme settings.
*/
class Themes {
class Themes
{
/**
* @brief
*
*/
function post() {
/**
* @brief
*
*/
public function post()
{
$theme = argv(2);
if (is_file("view/theme/$theme/php/config.php")){
require_once("view/theme/$theme/php/config.php");
/// @FIXME add parent theme if derived
if (function_exists('theme_admin_post')){
theme_admin_post($a);
}
}
info(t('Theme settings updated.'));
if(is_ajax())
return;
$theme = argv(2);
if (is_file("view/theme/$theme/php/config.php")) {
require_once("view/theme/$theme/php/config.php");
/// @FIXME add parent theme if derived
if (function_exists('theme_admin_post')) {
theme_admin_post($a);
}
}
info(t('Theme settings updated.'));
if (is_ajax())
return;
goaway(z_root() . '/admin/themes/' . $theme );
}
goaway(z_root() . '/admin/themes/' . $theme);
}
/**
* @brief Themes admin page.
*
* @return string with parsed HTML
*/
function get(){
$allowed_themes_str = get_config('system', 'allowed_themes');
$allowed_themes_raw = explode(',', $allowed_themes_str);
$allowed_themes = [];
if(count($allowed_themes_raw))
foreach($allowed_themes_raw as $x)
if(strlen(trim($x)))
$allowed_themes[] = trim($x);
/**
* @brief Themes admin page.
*
* @return string with parsed HTML
*/
public function get()
{
$allowed_themes_str = get_config('system', 'allowed_themes');
$allowed_themes_raw = explode(',', $allowed_themes_str);
$allowed_themes = [];
if (count($allowed_themes_raw))
foreach ($allowed_themes_raw as $x)
if (strlen(trim($x)))
$allowed_themes[] = trim($x);
$themes = [];
$files = glob('view/theme/*');
if($files) {
foreach($files as $file) {
$f = basename($file);
$is_experimental = intval(file_exists($file . '/.experimental'));
$is_supported = 1-(intval(file_exists($file . '/.unsupported'))); // Is not used yet
$is_allowed = intval(in_array($f,$allowed_themes));
$themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
}
}
$themes = [];
$files = glob('view/theme/*');
if ($files) {
foreach ($files as $file) {
$f = basename($file);
$is_experimental = intval(file_exists($file . '/.experimental'));
$is_supported = 1 - (intval(file_exists($file . '/.unsupported'))); // Is not used yet
$is_allowed = intval(in_array($f, $allowed_themes));
$themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
}
}
if(! count($themes)) {
notice( t('No themes found.'));
return '';
}
if (!count($themes)) {
notice(t('No themes found.'));
return '';
}
/*
* Single theme
*/
/*
* Single theme
*/
if (App::$argc == 3){
$theme = App::$argv[2];
if(! is_dir("view/theme/$theme")){
notice( t("Item not found.") );
return '';
}
if (App::$argc == 3) {
$theme = App::$argv[2];
if (!is_dir("view/theme/$theme")) {
notice(t("Item not found."));
return '';
}
if (x($_GET,"a") && $_GET['a']=="t"){
check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
if (x($_GET, "a") && $_GET['a'] == "t") {
check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
// Toggle theme status
// Toggle theme status
$this->toggle_theme($themes, $theme, $result);
$s = $this->rebuild_theme_table($themes);
if($result)
info( sprintf('Theme %s enabled.', $theme));
else
info( sprintf('Theme %s disabled.', $theme));
$this->toggle_theme($themes, $theme, $result);
$s = $this->rebuild_theme_table($themes);
if ($result)
info(sprintf('Theme %s enabled.', $theme));
else
info(sprintf('Theme %s disabled.', $theme));
set_config('system', 'allowed_themes', $s);
goaway(z_root() . '/admin/themes' );
}
set_config('system', 'allowed_themes', $s);
goaway(z_root() . '/admin/themes');
}
// display theme details
// display theme details
if ($this->theme_status($themes,$theme)) {
$status="on"; $action= t("Disable");
} else {
$status="off"; $action= t("Enable");
}
if ($this->theme_status($themes, $theme)) {
$status = "on";
$action = t("Disable");
} else {
$status = "off";
$action = t("Enable");
}
$readme=Null;
if (is_file("view/theme/$theme/README.md")){
$readme = file_get_contents("view/theme/$theme/README.md");
$readme = MarkdownExtra::defaultTransform($readme);
} else if (is_file("view/theme/$theme/README")){
$readme = '<pre>'. file_get_contents("view/theme/$theme/README") .'</pre>';
}
$readme = Null;
if (is_file("view/theme/$theme/README.md")) {
$readme = file_get_contents("view/theme/$theme/README.md");
$readme = MarkdownExtra::defaultTransform($readme);
} else if (is_file("view/theme/$theme/README")) {
$readme = '<pre>' . file_get_contents("view/theme/$theme/README") . '</pre>';
}
$admin_form = '';
if (is_file("view/theme/$theme/php/config.php")){
require_once("view/theme/$theme/php/config.php");
if(function_exists("theme_admin")){
$admin_form = theme_admin($a);
}
}
$admin_form = '';
if (is_file("view/theme/$theme/php/config.php")) {
require_once("view/theme/$theme/php/config.php");
if (function_exists("theme_admin")) {
$admin_form = theme_admin($a);
}
}
$screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
if(! stristr($screenshot[0],$theme))
$screenshot = null;
$screenshot = array(get_theme_screenshot($theme), t('Screenshot'));
if (!stristr($screenshot[0], $theme))
$screenshot = null;
$t = get_markup_template('admin_plugins_details.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Themes'),
'$toggle' => t('Toggle'),
'$settings' => t('Settings'),
'$baseurl' => z_root(),
$t = get_markup_template('admin_plugins_details.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Themes'),
'$toggle' => t('Toggle'),
'$settings' => t('Settings'),
'$baseurl' => z_root(),
'$plugin' => $theme,
'$status' => $status,
'$action' => $action,
'$info' => get_theme_info($theme),
'$function' => 'themes',
'$admin_form' => $admin_form,
'$str_author' => t('Author: '),
'$str_maintainer' => t('Maintainer: '),
'$screenshot' => $screenshot,
'$readme' => $readme,
'$plugin' => $theme,
'$status' => $status,
'$action' => $action,
'$info' => get_theme_info($theme),
'$function' => 'themes',
'$admin_form' => $admin_form,
'$str_author' => t('Author: '),
'$str_maintainer' => t('Maintainer: '),
'$screenshot' => $screenshot,
'$readme' => $readme,
'$form_security_token' => get_form_security_token('admin_themes'),
));
}
'$form_security_token' => get_form_security_token('admin_themes'),
));
}
/*
* List themes
*/
/*
* List themes
*/
$xthemes = [];
if($themes) {
foreach($themes as $th) {
$xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
}
}
$xthemes = [];
if ($themes) {
foreach ($themes as $th) {
$xthemes[] = array($th['name'], (($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
}
}
$t = get_markup_template('admin_plugins.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Themes'),
'$submit' => t('Submit'),
'$baseurl' => z_root(),
'$function' => 'themes',
'$plugins' => $xthemes,
'$experimental' => t('[Experimental]'),
'$unsupported' => t('[Unsupported]'),
'$form_security_token' => get_form_security_token('admin_themes'),
));
}
$t = get_markup_template('admin_plugins.tpl');
return replace_macros($t, array(
'$title' => t('Administration'),
'$page' => t('Themes'),
'$submit' => t('Submit'),
'$baseurl' => z_root(),
'$function' => 'themes',
'$plugins' => $xthemes,
'$experimental' => t('[Experimental]'),
'$unsupported' => t('[Unsupported]'),
'$form_security_token' => get_form_security_token('admin_themes'),
));
}
/**
* @brief Toggle a theme.
*
* @param array &$themes
* @param[in] string $th
* @param[out] int &$result
*/
function toggle_theme(&$themes, $th, &$result) {
for($x = 0; $x < count($themes); $x ++) {
if($themes[$x]['name'] === $th) {
if($themes[$x]['allowed']) {
$themes[$x]['allowed'] = 0;
$result = 0;
}
else {
$themes[$x]['allowed'] = 1;
$result = 1;
}
}
}
}
/**
* @brief Toggle a theme.
*
* @param array &$themes
* @param[in] string $th
* @param[out] int &$result
*/
public function toggle_theme(&$themes, $th, &$result)
{
for ($x = 0; $x < count($themes); $x++) {
if ($themes[$x]['name'] === $th) {
if ($themes[$x]['allowed']) {
$themes[$x]['allowed'] = 0;
$result = 0;
} else {
$themes[$x]['allowed'] = 1;
$result = 1;
}
}
}
}
/**
* @param array $themes
* @param string $th
* @return int
*/
function theme_status($themes, $th) {
for($x = 0; $x < count($themes); $x ++) {
if($themes[$x]['name'] === $th) {
if($themes[$x]['allowed']) {
return 1;
}
else {
return 0;
}
}
}
return 0;
}
/**
* @param array $themes
* @param string $th
* @return int
*/
public function theme_status($themes, $th)
{
for ($x = 0; $x < count($themes); $x++) {
if ($themes[$x]['name'] === $th) {
if ($themes[$x]['allowed']) {
return 1;
} else {
return 0;
}
}
}
return 0;
}
/**
* @param array $themes
* @return string
*/
function rebuild_theme_table($themes) {
$o = '';
if(count($themes)) {
foreach($themes as $th) {
if($th['allowed']) {
if(strlen($o))
$o .= ',';
$o .= $th['name'];
}
}
}
return $o;
}
/**
* @param array $themes
* @return string
*/
public function rebuild_theme_table($themes)
{
$o = '';
if (count($themes)) {
foreach ($themes as $th) {
if ($th['allowed']) {
if (strlen($o))
$o .= ',';
$o .= $th['name'];
}
}
}
return $o;
}
}

Some files were not shown because too many files have changed in this diff Show more