mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-20 11:35:13 +00:00
Merge branch 'psr12' into dev
This commit is contained in:
commit
c5f213e9d8
706 changed files with 64245 additions and 63182 deletions
|
@ -5,5 +5,5 @@ self.addEventListener('install', function(e) {
|
|||
|
||||
self.addEventListener('fetch', function(e) {
|
||||
// nothing here yet
|
||||
return;
|
||||
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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($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 (! 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
||||
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';
|
||||
|
||||
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';
|
||||
|
||||
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_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;
|
||||
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';
|
||||
|
||||
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_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':
|
||||
$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 '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 '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 'repository':
|
||||
// Legacy settings to cover all channel_types previously in Libzot.php
|
||||
$ret['channel_type'] = 'group';
|
||||
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();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'repository':
|
||||
// Legacy settings to cover all channel_types previously in Libzot.php
|
||||
$ret['channel_type'] = 'group';
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
class Channel_purge {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
public static function run($argc, $argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
class Cron_weekly {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
public static function run($argc, $argv) {
|
||||
|
||||
/**
|
||||
* Cron Weekly
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
class Cronhooks {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
public static function run($argc, $argv){
|
||||
|
||||
logger('cronhooks: start');
|
||||
|
||||
|
|
|
@ -8,14 +8,16 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
// Handles expiration of stale cookies currently by deleting them and rewriting the file.
|
||||
|
||||
use App;
|
||||
|
||||
class CurlAuth {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
public static function run($argc, $argv) {
|
||||
|
||||
if($argc != 2)
|
||||
return;
|
||||
|
||||
\App::$session->start();
|
||||
App::$session->start();
|
||||
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['uid'] = $argv[1];
|
||||
|
@ -46,7 +48,7 @@ class CurlAuth {
|
|||
}
|
||||
}
|
||||
$t = time() + (24 * 3600);
|
||||
file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
|
||||
file_put_contents($f, $output . 'HttpOnly_' . App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
|
||||
|
||||
file_put_contents($c,$x);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
class Delxitems {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
public static function run($argc, $argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
use Zotlabs\Lib\Libzot;;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Libzotdir;
|
||||
use Zotlabs\Lib\Queue;
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
|
|||
|
||||
class Expire {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
public static function run($argc, $argv){
|
||||
|
||||
cli_startup();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]));
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
namespace Zotlabs\Identity;
|
||||
|
||||
|
||||
class OAuth2Storage extends \OAuth2\Storage\Pdo {
|
||||
use OAuth2\Storage\Pdo;
|
||||
|
||||
class OAuth2Storage extends Pdo {
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
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
|
||||
private $groups = null;
|
||||
private $members = null;
|
||||
private $contacts = null;
|
||||
|
||||
|
||||
$channel = import_channel($channel,$this->settings['account_id'],$this->settings['sieze'],$this->settings['newname']);
|
||||
if (! $channel) {
|
||||
logger('no channel');
|
||||
return;
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
// 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');
|
||||
}
|
||||
$channel = import_channel($channel, $this->settings['account_id'], $this->settings['sieze'], $this->settings['newname']);
|
||||
if (!$channel) {
|
||||
logger('no channel');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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';
|
||||
}
|
||||
// figure out channel permission roles
|
||||
|
||||
import_channel_photo($p['body'],$phototype,$account_id,$channel['channel_id']);
|
||||
}
|
||||
}
|
||||
$permissions_role = 'social';
|
||||
|
||||
$newuid = $channel['channel_id'];
|
||||
$pageflags = ((isset($this->data['user']['page-flags'])) ? intval($this->data['user']['page-flags']) : 0);
|
||||
|
||||
$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
|
||||
]
|
||||
);
|
||||
if ($pageflags === 2) {
|
||||
$permissions_role = 'forum';
|
||||
}
|
||||
if ($pageflags === 5) {
|
||||
$permissions_role = 'forum_restricted';
|
||||
}
|
||||
|
||||
$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 ($pageflags === 0 && isset($this->data['user']['allow_gid']) && $this->data['user']['allow_gid']) {
|
||||
$permissions_role = 'social_restricted';
|
||||
}
|
||||
|
||||
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'];
|
||||
}
|
||||
// Friendica folks only have PERMS_AUTHED and "just me"
|
||||
|
||||
$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
|
||||
]
|
||||
);
|
||||
$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');
|
||||
}
|
||||
|
||||
|
||||
$x = Permissions::serialise(Permissions::FilledPerms($myperms));
|
||||
set_abconfig($newuid,$channel['channel_hash'],'system','my_perms',$x);
|
||||
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';
|
||||
}
|
||||
|
||||
if(intval($channel['channel_account_id'])) {
|
||||
import_channel_photo($p['body'], $phototype, $account_id, $channel['channel_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Save our permissions role so we can perhaps call it up and modify it later.
|
||||
$newuid = $channel['channel_id'];
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
$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
|
||||
]
|
||||
);
|
||||
|
||||
// Create a group with yourself as a member. This allows somebody to use it
|
||||
// right away as a default group for new contacts.
|
||||
$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),
|
||||
]
|
||||
);
|
||||
|
||||
AccessList::add($newuid, t('Friends'));
|
||||
AccessList::member_add($newuid,t('Friends'),$ret['channel']['channel_hash']);
|
||||
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'];
|
||||
}
|
||||
|
||||
// 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');
|
||||
$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
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
// 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.
|
||||
$x = Permissions::serialise(Permissions::FilledPerms($myperms));
|
||||
set_abconfig($newuid, $channel['channel_hash'], 'system', 'my_perms', $x);
|
||||
|
||||
$accts = get_config('system','auto_follow');
|
||||
if(($accts) && (! $total_identities)) {
|
||||
if(! is_array($accts))
|
||||
$accts = array($accts);
|
||||
if (intval($channel['channel_account_id'])) {
|
||||
|
||||
foreach($accts as $acct) {
|
||||
if(trim($acct)) {
|
||||
$f = connect_and_sync($channel,trim($acct));
|
||||
if($f['success']) {
|
||||
// Save our permissions role so we can perhaps call it up and modify it later.
|
||||
|
||||
$can_view_stream = their_perms_contains($channel['channel_id'],$f['abook']['abook_xchan'],'view_stream');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// If we can view their stream, pull in some posts
|
||||
// Create a group with yourself as a member. This allows somebody to use it
|
||||
// right away as a default group for new contacts.
|
||||
|
||||
if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) {
|
||||
Run::Summon([ 'Onepoll',$f['abook']['abook_id'] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AccessList::add($newuid, t('Friends'));
|
||||
AccessList::member_add($newuid, t('Friends'), $ret['channel']['channel_hash']);
|
||||
|
||||
call_hooks('create_identity', $newuid);
|
||||
}
|
||||
// if our role_permissions indicate that we're using a default collection ACL, add it.
|
||||
|
||||
$this->groups = ((isset($this->data['group'])) ? $this->data['group'] : null);
|
||||
$this->members = ((isset($this->data['group_member'])) ? $this->data['group_member'] : null);
|
||||
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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// import contacts
|
||||
set_pconfig($channel['channel_id'], 'system', 'photo_path', '%Y/%Y-%m');
|
||||
set_pconfig($channel['channel_id'], 'system', 'attach_path', '%Y/%Y-%m');
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
|
||||
// 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.
|
||||
$accts = get_config('system', 'auto_follow');
|
||||
if (($accts) && (!$total_identities)) {
|
||||
if (!is_array($accts))
|
||||
$accts = array($accts);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($accts as $acct) {
|
||||
if (trim($acct)) {
|
||||
$f = connect_and_sync($channel, trim($acct));
|
||||
if ($f['success']) {
|
||||
|
||||
change_channel($channel['channel_id']);
|
||||
notice( t('Import complete.') . EOL);
|
||||
$can_view_stream = their_perms_contains($channel['channel_id'], $f['abook']['abook_xchan'], 'view_stream');
|
||||
|
||||
goaway(z_root() . '/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');
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
class ASCollection {
|
||||
$this->channel = $channel;
|
||||
$this->direction = $direction;
|
||||
$this->limit = $limit;
|
||||
|
||||
private $channel = null;
|
||||
private $nextpage = null;
|
||||
private $limit = 0;
|
||||
private $direction = 0; // 0 = forward, 1 = reverse
|
||||
private $data = [];
|
||||
private $history = [];
|
||||
if (is_array($obj)) {
|
||||
$data = $obj;
|
||||
}
|
||||
|
||||
if (is_string($obj)) {
|
||||
$data = Activity::fetch($obj, $channel);
|
||||
$this->history[] = $obj;
|
||||
}
|
||||
|
||||
function __construct($obj, $channel = null, $direction = 0, $limit = 0) {
|
||||
if (!is_array($data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->channel = $channel;
|
||||
$this->direction = $direction;
|
||||
$this->limit = $limit;
|
||||
|
||||
if (is_array($obj)) {
|
||||
$data = $obj;
|
||||
}
|
||||
if (!in_array($data['type'], ['Collection', 'OrderedCollection'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($obj)) {
|
||||
$data = Activity::fetch($obj,$channel);
|
||||
$this->history[] = $obj;
|
||||
}
|
||||
|
||||
if (! is_array($data)) {
|
||||
return;
|
||||
}
|
||||
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 (! in_array($data['type'], ['Collection','OrderedCollection'])) {
|
||||
return false;
|
||||
}
|
||||
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->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 ($limit) {
|
||||
if (count($this->data) > $limit) {
|
||||
$this->data = array_slice($this->data, 0, $limit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
do {
|
||||
$x = $this->next();
|
||||
} while ($x);
|
||||
}
|
||||
|
||||
if ($limit) {
|
||||
if (count($this->data) > $limit) {
|
||||
$this->data = array_slice($this->data,0,$limit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
public function get()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
do {
|
||||
$x = $this->next();
|
||||
} while ($x);
|
||||
}
|
||||
public function next()
|
||||
{
|
||||
|
||||
function get() {
|
||||
return $this->data;
|
||||
}
|
||||
if (!$this->nextpage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (is_array($this->nextpage)) {
|
||||
$data = $this->nextpage;
|
||||
}
|
||||
|
||||
if (! $this->nextpage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($this->nextpage)) {
|
||||
$data = $this->nextpage;
|
||||
}
|
||||
|
||||
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 (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 (! is_array($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! in_array($data['type'], ['CollectionPage','OrderedCollectionPage'])) {
|
||||
return false;
|
||||
}
|
||||
if (!is_array($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setnext($data);
|
||||
if (!in_array($data['type'], ['CollectionPage', 'OrderedCollectionPage'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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']));
|
||||
}
|
||||
$this->setnext($data);
|
||||
|
||||
if ($limit) {
|
||||
if (count($this->data) > $limit) {
|
||||
$this->data = array_slice($this->data,0,$limit);
|
||||
$this->nextpage = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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']));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if ($limit) {
|
||||
if (count($this->data) > $limit) {
|
||||
$this->data = array_slice($this->data, 0, $limit);
|
||||
$this->nextpage = false;
|
||||
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);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -5,460 +5,470 @@ namespace Zotlabs\Lib;
|
|||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class AccessList {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
class AccessList
|
||||
{
|
||||
|
||||
$ret = false;
|
||||
if ($uid && $name) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
if ($r !== false) {
|
||||
public static function add($uid, $name, $public = 0)
|
||||
{
|
||||
|
||||
// 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.
|
||||
$ret = false;
|
||||
if ($uid && $name) {
|
||||
$r = self::byname($uid, $name); // check for dups
|
||||
if ($r !== false) {
|
||||
|
||||
$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;
|
||||
}
|
||||
// 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.
|
||||
|
||||
$hash = new_uuid();
|
||||
$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;
|
||||
}
|
||||
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname, rule )
|
||||
$hash = new_uuid();
|
||||
|
||||
$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);
|
||||
|
||||
return (($ret) ? $hash : $ret);
|
||||
}
|
||||
Libsync::build_sync_packet($uid, null, true);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// 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 ($change) {
|
||||
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
|
||||
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'
|
||||
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.
|
||||
|
||||
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;
|
||||
}
|
||||
// returns the integer id of an access group owned by $uid and named $name
|
||||
// or false.
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (intval($gid)) {
|
||||
if ($total) {
|
||||
$r = q("SELECT count(xchan) as total FROM pgrp_member
|
||||
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
|
||||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
intval($gid),
|
||||
intval($uid),
|
||||
intval($uid)
|
||||
);
|
||||
if ($r) {
|
||||
return $r[0]['total'];
|
||||
}
|
||||
}
|
||||
|
||||
$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 = '') {
|
||||
|
||||
$grps = [];
|
||||
public static function select($uid, $group = '')
|
||||
{
|
||||
|
||||
$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' : '') ];
|
||||
}
|
||||
$grps = [];
|
||||
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('group_selection.tpl'), [
|
||||
'$label' => t('Add new connections to this access list'),
|
||||
'$groups' => $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' : '')];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 ($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),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
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'),
|
||||
]);
|
||||
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;
|
||||
}
|
||||
|
||||
$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'),
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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 ($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;
|
||||
}
|
||||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
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'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
$ret = [];
|
||||
if ($r) {
|
||||
foreach ($r as $rv)
|
||||
$ret[] = $rv['gid'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public function __construct($string, $hub = null, $client = null)
|
||||
{
|
||||
|
||||
$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);
|
||||
}
|
||||
$this->raw = $string;
|
||||
$this->hub = $hub;
|
||||
|
||||
if ($this->data) {
|
||||
if (is_array($string)) {
|
||||
$this->data = $string;
|
||||
$this->raw = json_encode($string, JSON_UNESCAPED_SLASHES);
|
||||
} else {
|
||||
$this->data = json_decode($string, true);
|
||||
}
|
||||
|
||||
// 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 ($this->data) {
|
||||
|
||||
// This indicates only that we have sucessfully decoded JSON.
|
||||
$this->valid = true;
|
||||
// verify and unpack JSalmon signature if present
|
||||
// This will only be the case for Zot6 packets
|
||||
|
||||
// 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 (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;
|
||||
|
||||
// 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');
|
||||
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
|
||||
// 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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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']);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if this is a followup or response activity
|
||||
|
||||
$this->parent_id = $this->get_property_obj('inReplyTo');
|
||||
// Attempt to assemble an Activity from what we were given.
|
||||
|
||||
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->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');
|
||||
|
||||
/**
|
||||
* @brief Return if instantiated ActivityStream is valid.
|
||||
*
|
||||
* @return boolean Return true if the JSON string could be decoded.
|
||||
*/
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
|
||||
function is_valid() {
|
||||
return $this->valid;
|
||||
}
|
||||
// Implied create activity required by C2S specification if no object is present
|
||||
|
||||
function set_recips($arr) {
|
||||
$this->saved_recips = $arr;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collects all recipients.
|
||||
*
|
||||
* @param string $base
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return array
|
||||
*/
|
||||
function collect_recips($base = '', $namespace = '') {
|
||||
$x = [];
|
||||
// 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']);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Determine if this is a followup or response activity
|
||||
|
||||
$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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if instantiated ActivityStream is valid.
|
||||
*
|
||||
* @return bool Return true if the JSON string could be decoded.
|
||||
*/
|
||||
|
||||
public function is_valid()
|
||||
{
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
public 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 = [];
|
||||
|
||||
$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
|
||||
*/
|
||||
|
||||
function get_namespace($base, $namespace) {
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param array $base
|
||||
* @param string $namespace if not set return empty string
|
||||
* @return string|NULL
|
||||
*/
|
||||
|
||||
if (! $namespace) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$key = null;
|
||||
public function get_namespace($base, $namespace)
|
||||
{
|
||||
|
||||
foreach ( [ $this->data, $base ] as $b ) {
|
||||
if (! $b) {
|
||||
continue;
|
||||
}
|
||||
if (!$namespace) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
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 = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$key = null;
|
||||
|
||||
return $key;
|
||||
}
|
||||
foreach ([$this->data, $base] as $b) {
|
||||
if (!$b) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
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 = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$base = (($base) ? $base : $this->data);
|
||||
$propname = (($prefix) ? $prefix . ':' : '') . $property;
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (! is_array($base)) {
|
||||
btlogger('not an array: ' . print_r($base,true));
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $property
|
||||
* @param array $base (optional)
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
|
||||
return ((array_key_exists($propname, $base)) ? $base[$propname] : 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;
|
||||
|
||||
if (!is_array($base)) {
|
||||
btlogger('not an array: ' . print_r($base, true));
|
||||
return 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;
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
// 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 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
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
public static function is_as_request()
|
||||
{
|
||||
|
||||
// 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];
|
||||
}
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
2675
Zotlabs/Lib/Apps.php
2675
Zotlabs/Lib/Apps.php
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
use App;
|
||||
|
||||
class Config {
|
||||
|
||||
/**
|
||||
|
@ -14,20 +16,20 @@ class Config {
|
|||
* @param string $family
|
||||
* The category of the configuration value
|
||||
*/
|
||||
static public function Load($family) {
|
||||
if(! array_key_exists($family, \App::$config))
|
||||
\App::$config[$family] = [];
|
||||
public static function Load($family) {
|
||||
if(! array_key_exists($family, App::$config))
|
||||
App::$config[$family] = [];
|
||||
|
||||
if(! array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
if(! array_key_exists('config_loaded', App::$config[$family])) {
|
||||
$r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
|
||||
if($r !== false) {
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
\App::$config[$family][$k] = $rr['v'];
|
||||
App::$config[$family][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
\App::$config[$family]['config_loaded'] = true;
|
||||
App::$config[$family]['config_loaded'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,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);
|
||||
|
@ -58,7 +60,7 @@ class Config {
|
|||
dbesc($dbvalue)
|
||||
);
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
return $ret;
|
||||
|
@ -71,7 +73,7 @@ class Config {
|
|||
);
|
||||
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
|
||||
|
@ -96,15 +98,15 @@ 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) {
|
||||
if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
|
||||
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);
|
||||
|
||||
if(array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
if(! array_key_exists($key, \App::$config[$family])) {
|
||||
if(array_key_exists('config_loaded', App::$config[$family])) {
|
||||
if(! array_key_exists($key, App::$config[$family])) {
|
||||
return $default;
|
||||
}
|
||||
return unserialise(\App::$config[$family][$key]);
|
||||
return unserialise(App::$config[$family][$key]);
|
||||
}
|
||||
|
||||
return $default;
|
||||
|
@ -122,12 +124,12 @@ class Config {
|
|||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
static public function Delete($family, $key) {
|
||||
public static function Delete($family, $key) {
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
|
||||
unset(\App::$config[$family][$key]);
|
||||
if(array_key_exists($family, App::$config) && array_key_exists($key, App::$config[$family]))
|
||||
unset(App::$config[$family][$key]);
|
||||
|
||||
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
|
||||
dbesc($family),
|
||||
|
@ -150,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)
|
||||
|
|
|
@ -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
|
||||
|
||||
if ($r) {
|
||||
// we may have nulled out this record so check again
|
||||
|
||||
// Check the site table to see if we should have a zot6 hubloc,
|
||||
// If so, clear the xchan and start fresh
|
||||
if ($r) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
// Now start processing the new connection
|
||||
if ($r['xchan_network'] === 'activitypub') {
|
||||
if (!$ap_allowed) {
|
||||
$result['message'] = t('Protocol not supported');
|
||||
return $result;
|
||||
}
|
||||
$singleton = true;
|
||||
}
|
||||
|
||||
$aid = $channel['channel_account_id'];
|
||||
$hash = $channel['channel_hash'];
|
||||
$default_group = $channel['channel_default_group'];
|
||||
// Now start processing the new connection
|
||||
|
||||
if ($hash === $xchan_hash) {
|
||||
$result['message'] = t('Cannot connect to yourself.');
|
||||
return $result;
|
||||
}
|
||||
$aid = $channel['channel_account_id'];
|
||||
$hash = $channel['channel_hash'];
|
||||
$default_group = $channel['channel_default_group'];
|
||||
|
||||
$p = Permissions::connect_perms($uid);
|
||||
if ($hash === $xchan_hash) {
|
||||
$result['message'] = t('Cannot connect to yourself.');
|
||||
return $result;
|
||||
}
|
||||
|
||||
// parent channels have unencumbered write permission
|
||||
$p = Permissions::connect_perms($uid);
|
||||
|
||||
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;
|
||||
}
|
||||
// parent channels have unencumbered write permission
|
||||
|
||||
$my_perms = Permissions::serialise($p['perms']);
|
||||
|
||||
$profile_assign = get_pconfig($uid,'system','profile_assign','');
|
||||
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;
|
||||
}
|
||||
|
||||
// See if we are already connected by virtue of having an abook record
|
||||
$my_perms = Permissions::serialise($p['perms']);
|
||||
|
||||
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
|
||||
$profile_assign = get_pconfig($uid, 'system', 'profile_assign', '');
|
||||
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
|
|
|
@ -3,112 +3,114 @@
|
|||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class DB_Upgrade {
|
||||
use App;
|
||||
|
||||
public $config_name = '';
|
||||
public $func_prefix = '';
|
||||
class DB_Upgrade
|
||||
{
|
||||
|
||||
function __construct($db_revision) {
|
||||
public $config_name = '';
|
||||
public $func_prefix = '';
|
||||
|
||||
$this->config_name = 'db_version';
|
||||
$this->func_prefix = '_';
|
||||
public function __construct($db_revision)
|
||||
{
|
||||
|
||||
$build = get_config('system', 'db_version', 0);
|
||||
if(! intval($build))
|
||||
$build = set_config('system', 'db_version', $db_revision);
|
||||
$this->config_name = 'db_version';
|
||||
$this->func_prefix = '_';
|
||||
|
||||
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);
|
||||
$build = get_config('system', 'db_version', 0);
|
||||
if (!intval($build))
|
||||
$build = set_config('system', 'db_version', $db_revision);
|
||||
|
||||
if($stored < $current) {
|
||||
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;
|
||||
}
|
||||
|
||||
// The last update we performed was $stored.
|
||||
// Start at $stored + 1 and continue until we have completed $current
|
||||
$current = intval($db_revision);
|
||||
|
||||
for($x = $stored + 1; $x <= $current; $x ++) {
|
||||
$s = '_' . $x;
|
||||
$cls = '\\Zotlabs\Update\\' . $s ;
|
||||
if(! class_exists($cls)) {
|
||||
return;
|
||||
}
|
||||
if ($stored < $current) {
|
||||
|
||||
// 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.
|
||||
// The last update we performed was $stored.
|
||||
// Start at $stored + 1 and continue until we have completed $current
|
||||
|
||||
// If the update fails or times-out completely you may need to
|
||||
// delete the config entry to try again.
|
||||
for ($x = $stored + 1; $x <= $current; $x++) {
|
||||
$s = '_' . $x;
|
||||
$cls = '\\Zotlabs\Update\\' . $s;
|
||||
if (!class_exists($cls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Config::Load('database');
|
||||
// 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(get_config('database', $s))
|
||||
break;
|
||||
set_config('database',$s, '1');
|
||||
|
||||
// If the update fails or times-out completely you may need to
|
||||
// delete the config entry to try again.
|
||||
|
||||
$c = new $cls();
|
||||
Config::Load('database');
|
||||
|
||||
$retval = $c->run();
|
||||
|
||||
if($retval != UPDATE_SUCCESS) {
|
||||
if (get_config('database', $s))
|
||||
break;
|
||||
set_config('database', $s, '1');
|
||||
|
||||
|
||||
$source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php');
|
||||
|
||||
$c = new $cls();
|
||||
|
||||
// Prevent sending hundreds of thousands of emails by creating
|
||||
// a lockfile.
|
||||
$retval = $c->run();
|
||||
|
||||
$lockfile = 'cache/mailsent';
|
||||
if ($retval != UPDATE_SUCCESS) {
|
||||
|
||||
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
|
||||
]
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
//try the logger
|
||||
logger('CRITICAL: Update Failed: ' . $x);
|
||||
pop_lang();
|
||||
}
|
||||
else {
|
||||
set_config('database',$s, 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
set_config('system', 'db_version', $db_revision);
|
||||
}
|
||||
}
|
||||
$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.
|
||||
|
||||
$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);
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 = '';
|
||||
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* Description of ExtendedZip
|
||||
*
|
||||
* @author andrew
|
||||
*/
|
||||
class ExtendedZip extends \ZipArchive {
|
||||
class ExtendedZip extends ZipArchive {
|
||||
|
||||
// Member function to add a whole file system subtree to the archive
|
||||
public function addTree($dirname, $localname = '') {
|
||||
|
|
|
@ -27,30 +27,31 @@ namespace Zotlabs\Lib;
|
|||
* see also: boot.php:os_mkdir() - here we provide the equivalent of mkdir -p with permissions of 770.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
class Hashpath
|
||||
{
|
||||
|
||||
do {
|
||||
$slug = substr($hash,$start,$slice);
|
||||
$prefix .= '/' . $slug;
|
||||
$start += $slice;
|
||||
$sluglen -= $slice;
|
||||
}
|
||||
while ($sluglen);
|
||||
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;
|
||||
|
||||
if ($mkdir) {
|
||||
os_mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
|
||||
}
|
||||
|
||||
return $prefix . '/' . $hash;
|
||||
}
|
||||
do {
|
||||
$slug = substr($hash, $start, $slice);
|
||||
$prefix .= '/' . $slug;
|
||||
$start += $slice;
|
||||
$sluglen -= $slice;
|
||||
} while ($sluglen);
|
||||
|
||||
if ($mkdir) {
|
||||
os_mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
|
||||
}
|
||||
|
||||
return $prefix . '/' . $hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 function get_filename($url, $prefix = '.') {
|
||||
return Hashpath::path($url,$prefix);
|
||||
}
|
||||
static public $cache_life = 18600 * 7;
|
||||
|
||||
// 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 get_filename($url, $prefix = '.')
|
||||
{
|
||||
return Hashpath::path($url, $prefix);
|
||||
}
|
||||
|
||||
if (strpos($url,z_root()) !== false) {
|
||||
return false;
|
||||
}
|
||||
// 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
|
||||
|
||||
$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
|
||||
|
||||
Run::Summon( [ 'Cache_image', $url, $path ] );
|
||||
return false;
|
||||
}
|
||||
public static function check($url, $prefix = '.')
|
||||
{
|
||||
|
||||
static function url_to_cache($url,$file) {
|
||||
if (strpos($url, z_root()) !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = fopen($file,'wb');
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $fp) {
|
||||
logger('failed to open storage file: ' . $file,LOGGER_NORMAL,LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
// Cache_image invokes url_to_cache() as a background task
|
||||
|
||||
// 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 ]);
|
||||
Run::Summon(['Cache_image', $url, $path]);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
public static function url_to_cache($url, $file)
|
||||
{
|
||||
|
||||
// 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.
|
||||
$fp = fopen($file, 'wb');
|
||||
|
||||
file_put_contents($file, EMPTY_STR);
|
||||
logger('cache failed from ' . $url);
|
||||
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.
|
||||
|
||||
$redirects = 0;
|
||||
$x = z_fetch_url($url, true, $redirects, ['filep' => $fp, 'novalidate' => true, 'timeout' => 120]);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
$fname = basename($url);
|
||||
$resolution = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
public static function getLocalFileSize($url)
|
||||
{
|
||||
|
||||
$fname = basename($url);
|
||||
$resolution = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,131 +2,139 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Exception;
|
||||
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');
|
||||
|
||||
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));
|
||||
}
|
||||
jsonld_set_document_loader('jsonld_document_loader');
|
||||
|
||||
return $d;
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
static function salmon_sign($data,$channel) {
|
||||
return $d;
|
||||
}
|
||||
|
||||
$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));
|
||||
public static function salmon_sign($data, $channel)
|
||||
{
|
||||
|
||||
$data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$data);
|
||||
$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));
|
||||
|
||||
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||
$data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $data);
|
||||
|
||||
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||
|
||||
$signature = base64url_encode(Crypto::sign($data . $precomputed,$channel['channel_prvkey']));
|
||||
$precomputed = '.' . base64url_encode($data_type, false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||
|
||||
return ([
|
||||
'id' => $arr['id'],
|
||||
'meData' => $data,
|
||||
'meDataType' => $data_type,
|
||||
'meEncoding' => $encoding,
|
||||
'meAlgorithm' => $algorithm,
|
||||
'meCreator' => channel_url($channel),
|
||||
'meSignatureValue' => $signature
|
||||
]);
|
||||
$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
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
||||
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;
|
||||
}
|
||||
// This limits the number of DB queries for fetch_by_entity to once per page load.
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$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 (!$arr['block_entity']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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'];
|
||||
}
|
||||
}
|
||||
$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'])) {
|
||||
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'])) {
|
||||
$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'];
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
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 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 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 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 [];
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
public static function fetch($channel_id, $type = false)
|
||||
{
|
||||
if (!intval($channel_id)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
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
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Webfinger;
|
||||
use Zotlabs\Lib\Zotfinger;
|
||||
|
@ -9,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) {
|
||||
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
$profile = [];
|
||||
$profile['encoding'] = 'zot';
|
||||
|
||||
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['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 ($tags)
|
||||
$profile['keywords'] = $tags;
|
||||
}
|
||||
|
||||
$hidden = (1 - intval($p[0]['publish']));
|
||||
|
||||
// logger('hidden: ' . $hidden);
|
||||
|
||||
$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'])
|
||||
);
|
||||
}
|
||||
|
||||
$arr = [ 'channel_id' => $uid, 'hash' => $hash, 'profile' => $profile ];
|
||||
call_hooks('local_dir_update', $arr);
|
||||
|
||||
$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)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$ud_hash = random_string() . '@' . \App::get_hostname();
|
||||
self::update_modtime($hash, $ud_hash, channel_reddress($p[0]),(($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
|
||||
}
|
||||
public static function local_dir_update($uid, $force)
|
||||
{
|
||||
|
||||
|
||||
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
$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)
|
||||
);
|
||||
|
||||
static function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0) {
|
||||
$profile = [];
|
||||
$profile['encoding'] = 'zot';
|
||||
|
||||
logger('import_directory_profile', LOGGER_DEBUG);
|
||||
if (! $hash)
|
||||
return false;
|
||||
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['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 ($tags)
|
||||
$profile['keywords'] = $tags;
|
||||
}
|
||||
|
||||
$hidden = (1 - intval($p[0]['publish']));
|
||||
|
||||
// logger('hidden: ' . $hidden);
|
||||
|
||||
$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'])
|
||||
);
|
||||
}
|
||||
|
||||
$arr = ['channel_id' => $uid, 'hash' => $hash, 'profile' => $profile];
|
||||
call_hooks('local_dir_update', $arr);
|
||||
|
||||
$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)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$ud_hash = random_string() . '@' . App::get_hostname();
|
||||
self::update_modtime($hash, $ud_hash, channel_reddress($p[0]), (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
|
||||
}
|
||||
|
||||
|
||||
$maxlen = get_max_import_size();
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
if($maxlen && mb_strlen($profile['about']) > $maxlen) {
|
||||
$profile['about'] = mb_substr($profile['about'],0,$maxlen,'UTF-8');
|
||||
}
|
||||
public static function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0)
|
||||
{
|
||||
|
||||
$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) : '');
|
||||
|
||||
$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);
|
||||
|
||||
// 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".
|
||||
logger('import_directory_profile', LOGGER_DEBUG);
|
||||
if (!$hash)
|
||||
return false;
|
||||
|
||||
|
||||
if(in_arrayi('nsfw',$clean) || in_arrayi('adult',$clean)) {
|
||||
q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
$maxlen = get_max_import_size();
|
||||
|
||||
$r = q("select * from xprof where xprof_hash = '%s' limit 1",
|
||||
dbesc($hash)
|
||||
);
|
||||
if ($maxlen && mb_strlen($profile['about']) > $maxlen) {
|
||||
$profile['about'] = mb_substr($profile['about'], 0, $maxlen, 'UTF-8');
|
||||
}
|
||||
|
||||
if ($arr['xprof_age'] > 150)
|
||||
$arr['xprof_age'] = 150;
|
||||
if ($arr['xprof_age'] < 0)
|
||||
$arr['xprof_age'] = 0;
|
||||
$arr = [];
|
||||
|
||||
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
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
$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".
|
||||
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
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
|
||||
xprof_desc = '%s',
|
||||
xprof_dob = '%s',
|
||||
xprof_age = %d,
|
||||
|
@ -351,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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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("
","\r",$s);
|
||||
$s = str_replace("
\n>","",$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\#])/','#$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('#','#',$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;
|
||||
}
|
||||
|
||||
static function use_zrl_cb_img_x($match) {
|
||||
$res = '';
|
||||
$is_zid = is_matrix_url(trim($match[3]));
|
||||
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("
", "\r", $s);
|
||||
$s = str_replace("
\n>", "", $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\#])/', '#$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('#', '#', $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]));
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
static public function from_bbcode_share($match) {
|
||||
public static 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];
|
||||
|
||||
if(! $message_id) {
|
||||
preg_match("/guid='(.*?)'/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];
|
||||
}
|
||||
|
||||
$reldate = datetime_convert('UTC', date_default_timezone_get(), $posted, 'r');
|
||||
|
||||
$headline = '';
|
||||
$reldate = datetime_convert('UTC', date_default_timezone_get(), $posted, 'r');
|
||||
|
||||
if ($avatar != "")
|
||||
$headline .= '[url=' . zid($profile) . '][img]' . $avatar . '[/img][/url]';
|
||||
$headline = '';
|
||||
|
||||
// Bob Smith wrote the following post 2 hours ago
|
||||
if ($avatar != "")
|
||||
$headline .= '[url=' . zid($profile) . '][img]' . $avatar . '[/img][/url]';
|
||||
|
||||
$fmt = sprintf( t('%1$s wrote the following %2$s %3$s'),
|
||||
'[url=' . zid($profile) . ']' . $author . '[/url]',
|
||||
'[url=' . zid($link) . ']' . t('post') . '[/url]',
|
||||
$reldate
|
||||
);
|
||||
// Bob Smith wrote the following post 2 hours ago
|
||||
|
||||
$headline .= $fmt . "\n\n";
|
||||
$fmt = sprintf(t('%1$s wrote the following %2$s %3$s'),
|
||||
'[url=' . zid($profile) . ']' . $author . '[/url]',
|
||||
'[url=' . zid($link) . ']' . t('post') . '[/url]',
|
||||
$reldate
|
||||
);
|
||||
|
||||
$text = $headline . trim($match[2]);
|
||||
$headline .= $fmt . "\n\n";
|
||||
|
||||
return $text;
|
||||
}
|
||||
$text = $headline . trim($match[2]);
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
static public function from_bbcode($Text, $options = []) {
|
||||
/**
|
||||
* @brief Convert bbcode to Markdown.
|
||||
*
|
||||
* @param string $Text The message as bbcode
|
||||
* @param array $options default empty
|
||||
* @return string The message converted to Markdown
|
||||
*/
|
||||
|
||||
/*
|
||||
* Transform #tags, strip off the [url] and replace spaces with underscore
|
||||
*/
|
||||
public static function from_bbcode($Text, $options = [])
|
||||
{
|
||||
|
||||
$Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i',
|
||||
create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $Text);
|
||||
/*
|
||||
* Transform #tags, strip off the [url] and replace spaces with underscore
|
||||
*/
|
||||
|
||||
$Text = preg_replace('/#\^\[([zu])rl\=(.*?)\](.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
|
||||
$Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i',
|
||||
create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $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('/#\^\[([zu])rl\=(.*?)\](.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
|
||||
|
||||
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", [ '\\Zotlabs\\Lib\\Markdown', 'from_bbcode_share'], $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);
|
||||
|
||||
$x = [ 'bbcode' => $Text, 'options' => $options ];
|
||||
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", ['\\Zotlabs\\Lib\\Markdown', 'from_bbcode_share'], $Text);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
$x = ['bbcode' => $Text, 'options' => $options];
|
||||
|
||||
$Text = $x['bbcode'];
|
||||
/**
|
||||
* @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);
|
||||
|
||||
// Convert it to HTML - don't try oembed
|
||||
$Text = bbcode($Text, [ 'tryoembed' => false ]);
|
||||
$Text = $x['bbcode'];
|
||||
|
||||
// Now convert HTML to Markdown
|
||||
// Convert it to HTML - don't try oembed
|
||||
$Text = bbcode($Text, ['tryoembed' => false]);
|
||||
|
||||
$Text = self::from_html($Text);
|
||||
// Now convert HTML to Markdown
|
||||
|
||||
//html2markdown adds backslashes infront of hashes after a new line. remove them
|
||||
$Text = str_replace("\n\#", "\n#", $Text);
|
||||
$Text = self::from_html($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);
|
||||
|
||||
// Remove empty zrl links
|
||||
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $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);
|
||||
|
||||
$Text = trim($Text);
|
||||
// Remove empty zrl links
|
||||
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
|
||||
|
||||
/**
|
||||
* @hooks bb_to_markdown
|
||||
* * \e string - The already converted message as bbcode and what will get returned
|
||||
*/
|
||||
call_hooks('bb_to_markdown', $Text);
|
||||
$Text = trim($Text);
|
||||
|
||||
return $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
static public function from_html($html,$options = []) {
|
||||
$markdown = '';
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
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);
|
||||
public static function from_html($html, $options = [])
|
||||
{
|
||||
$markdown = '';
|
||||
|
||||
try {
|
||||
$markdown = $converter->convert($html);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
logger("Invalid HTML. HTMLToMarkdown library threw an exception.");
|
||||
}
|
||||
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 '+'
|
||||
];
|
||||
}
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
$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.");
|
||||
}
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
}
|
||||
|
||||
// Tables are not an official part of the markdown specification.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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']) {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
|
||||
/**
|
||||
* @brief Class for handling channel specific configurations.
|
||||
*
|
||||
|
@ -28,19 +30,19 @@ 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;
|
||||
|
||||
if(! is_array(\App::$config)) {
|
||||
if(! is_array(App::$config)) {
|
||||
btlogger('App::$config not an array');
|
||||
}
|
||||
|
||||
if(! array_key_exists($uid, \App::$config)) {
|
||||
\App::$config[$uid] = [];
|
||||
if(! array_key_exists($uid, App::$config)) {
|
||||
App::$config[$uid] = [];
|
||||
}
|
||||
|
||||
if(! is_array(\App::$config[$uid])) {
|
||||
if(! is_array(App::$config[$uid])) {
|
||||
btlogger('App::$config[$uid] not an array: ' . $uid);
|
||||
}
|
||||
|
||||
|
@ -52,11 +54,11 @@ class PConfig {
|
|||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
$c = $rr['cat'];
|
||||
if(! array_key_exists($c, \App::$config[$uid])) {
|
||||
\App::$config[$uid][$c] = [];
|
||||
\App::$config[$uid][$c]['config_loaded'] = true;
|
||||
if(! array_key_exists($c, App::$config[$uid])) {
|
||||
App::$config[$uid][$c] = [];
|
||||
App::$config[$uid][$c]['config_loaded'] = true;
|
||||
}
|
||||
\App::$config[$uid][$c][$k] = $rr['v'];
|
||||
App::$config[$uid][$c][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,18 +82,18 @@ 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;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
if(! array_key_exists($uid, App::$config))
|
||||
self::Load($uid);
|
||||
|
||||
if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
|
||||
if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family])))
|
||||
return $default;
|
||||
|
||||
return unserialise(\App::$config[$uid][$family][$key]);
|
||||
return unserialise(App::$config[$uid][$family][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,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)
|
||||
|
@ -128,10 +130,10 @@ class PConfig {
|
|||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(self::Get($uid, $family, $key) === false) {
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
\App::$config[$uid] = [];
|
||||
if(! array_key_exists($family, \App::$config[$uid]))
|
||||
\App::$config[$uid][$family] = [];
|
||||
if(! array_key_exists($uid, App::$config))
|
||||
App::$config[$uid] = [];
|
||||
if(! array_key_exists($family, App::$config[$uid]))
|
||||
App::$config[$uid][$family] = [];
|
||||
|
||||
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
|
||||
intval($uid),
|
||||
|
@ -154,13 +156,13 @@ class PConfig {
|
|||
// set in the life of this page. We need this to
|
||||
// synchronise channel clones.
|
||||
|
||||
if(! array_key_exists('transient', \App::$config[$uid]))
|
||||
\App::$config[$uid]['transient'] = [];
|
||||
if(! array_key_exists($family, \App::$config[$uid]['transient']))
|
||||
\App::$config[$uid]['transient'][$family] = [];
|
||||
if(! array_key_exists('transient', App::$config[$uid]))
|
||||
App::$config[$uid]['transient'] = [];
|
||||
if(! array_key_exists($family, App::$config[$uid]['transient']))
|
||||
App::$config[$uid]['transient'][$family] = [];
|
||||
|
||||
\App::$config[$uid][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
App::$config[$uid][$family][$key] = $value;
|
||||
App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
|
@ -183,18 +185,18 @@ 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;
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($uid,\App::$config)
|
||||
&& is_array(\App::$config['uid'])
|
||||
&& array_key_exists($family,\App::$config['uid'])
|
||||
&& array_key_exists($key, \App::$config[$uid][$family]))
|
||||
unset(\App::$config[$uid][$family][$key]);
|
||||
if(array_key_exists($uid, App::$config)
|
||||
&& is_array(App::$config['uid'])
|
||||
&& array_key_exists($family, App::$config['uid'])
|
||||
&& array_key_exists($key, App::$config[$uid][$family]))
|
||||
unset(App::$config[$uid][$family][$key]);
|
||||
|
||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||
intval($uid),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\Permissions;
|
||||
|
||||
require_once("include/permissions.php");
|
||||
require_once("include/language.php");
|
||||
require_once("include/text.php");
|
||||
|
@ -51,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) {
|
||||
|
@ -80,11 +84,11 @@ class PermissionDescription {
|
|||
|
||||
$result = null;
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
$global_perms = Permissions::Perms();
|
||||
|
||||
if(array_key_exists($permname, $global_perms)) {
|
||||
|
||||
$channelPerm = \Zotlabs\Access\PermissionLimits::Get(\App::$channel['channel_id'], $permname);
|
||||
$channelPerm = PermissionLimits::Get(App::$channel['channel_id'], $permname);
|
||||
|
||||
$result = new PermissionDescription('', $channelPerm);
|
||||
} else {
|
||||
|
@ -107,7 +111,7 @@ class PermissionDescription {
|
|||
case 0: return t('Only me');
|
||||
case PERMS_PUBLIC: return t('Public');
|
||||
case PERMS_NETWORK: return t('Anybody in the $Projectname network');
|
||||
case PERMS_SITE: return sprintf(t('Any account on %s'), \App::get_hostname());
|
||||
case PERMS_SITE: return sprintf(t('Any account on %s'), App::get_hostname());
|
||||
case PERMS_CONTACTS: return t('Any of my connections');
|
||||
case PERMS_SPECIFIC: return t('Only connections I specifically allow');
|
||||
case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)');
|
||||
|
|
|
@ -6,486 +6,483 @@ use Zotlabs\Lib\Libzot;
|
|||
use Zotlabs\Web\HTTPSig;
|
||||
use Zotlabs\Lib\Activity;
|
||||
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.
|
||||
|
||||
$x = q("select outq_created, outq_hash, outq_posturl from outq where outq_hash = '%s' limit 1",
|
||||
dbesc($id)
|
||||
);
|
||||
if (! $x) {
|
||||
return;
|
||||
}
|
||||
// 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.
|
||||
|
||||
$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)
|
||||
);
|
||||
$x = q("select outq_created, outq_hash, outq_posturl from outq where outq_hash = '%s' limit 1",
|
||||
dbesc($id)
|
||||
);
|
||||
if (!$x) {
|
||||
return;
|
||||
}
|
||||
|
||||
// swap them
|
||||
|
||||
if ($g) {
|
||||
$x = $g;
|
||||
}
|
||||
|
||||
$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
|
||||
|
||||
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'])
|
||||
);
|
||||
|
||||
$since = datetime_convert('UTC','UTC',$y[0]['earliest']);
|
||||
$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'])
|
||||
);
|
||||
|
||||
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');
|
||||
}
|
||||
$since = datetime_convert('UTC', 'UTC', $y[0]['earliest']);
|
||||
|
||||
q("UPDATE outq SET outq_updated = '%s',
|
||||
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',
|
||||
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) . " " : '');
|
||||
|
||||
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
|
||||
dbesc($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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static function remove_by_posturl($posturl) {
|
||||
logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
|
||||
|
||||
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
|
||||
dbesc($posturl)
|
||||
);
|
||||
}
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
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'])
|
||||
);
|
||||
|
||||
$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 (!$immediate) {
|
||||
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
|
||||
dbesc($outq['outq_posturl'])
|
||||
);
|
||||
|
||||
if ($outq['outq_driver'] === 'asfetch') {
|
||||
$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;
|
||||
}
|
||||
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
if (! $channel) {
|
||||
logger('missing channel: ' . $outq['outq_channel']);
|
||||
return;
|
||||
}
|
||||
if ($outq['outq_driver'] === 'asfetch') {
|
||||
|
||||
if (! ActivityStreams::is_url($outq['outq_posturl'])) {
|
||||
logger('fetch item is not url: ' . $outq['outq_posturl']);
|
||||
self::remove($outq['outq_hash']);
|
||||
return;
|
||||
}
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
if (!$channel) {
|
||||
logger('missing channel: ' . $outq['outq_channel']);
|
||||
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']);
|
||||
if (!ActivityStreams::is_url($outq['outq_posturl'])) {
|
||||
logger('fetch item is not url: ' . $outq['outq_posturl']);
|
||||
self::remove($outq['outq_hash']);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
$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']);
|
||||
|
||||
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'])
|
||||
);
|
||||
// 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.
|
||||
|
||||
$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 (!$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($outq['outq_driver'] === 'activitypub') {
|
||||
$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;
|
||||
}
|
||||
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
if (! $channel) {
|
||||
logger('missing channel: ' . $outq['outq_channel']);
|
||||
return;
|
||||
}
|
||||
if ($outq['outq_driver'] === 'activitypub') {
|
||||
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
if (!$channel) {
|
||||
logger('missing channel: ' . $outq['outq_channel']);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$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']);
|
||||
$retries = 0;
|
||||
$m = parse_url($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']);
|
||||
}
|
||||
$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']);
|
||||
|
||||
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg'],$retries,[ 'headers' => $xhead ]);
|
||||
$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']);
|
||||
}
|
||||
|
||||
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']);
|
||||
$result = z_post_url($outq['outq_posturl'], $outq['outq_msg'], $retries, ['headers' => $xhead]);
|
||||
|
||||
// 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 ($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(! $immediate) {
|
||||
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
|
||||
dbesc($outq['outq_posturl'])
|
||||
);
|
||||
// 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.
|
||||
|
||||
$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;
|
||||
}
|
||||
if (!$immediate) {
|
||||
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
|
||||
dbesc($outq['outq_posturl'])
|
||||
);
|
||||
|
||||
// normal zot delivery
|
||||
$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;
|
||||
}
|
||||
|
||||
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
// normal zot delivery
|
||||
|
||||
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
|
||||
|
||||
if($outq['outq_posturl'] === z_root() . '/zot') {
|
||||
// local delivery
|
||||
$zot = new \Zotlabs\Zot6\Receiver(new \Zotlabs\Zot6\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'])
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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'],
|
||||
];
|
||||
|
||||
function __construct() {
|
||||
$this->xmlDoc = new DOMDocument('1.0','UTF-8');
|
||||
$this->xmlDoc->preserveWhiteSpace = false;
|
||||
libxml_use_internal_errors(true);
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->xmlDoc = new DOMDocument('1.0', 'UTF-8');
|
||||
$this->xmlDoc->preserveWhiteSpace = false;
|
||||
libxml_use_internal_errors(true);
|
||||
}
|
||||
|
||||
// load XML SVG
|
||||
function load($file) {
|
||||
$this->xmlDoc->load($file);
|
||||
}
|
||||
// load XML SVG
|
||||
public function load($file)
|
||||
{
|
||||
$this->xmlDoc->load($file);
|
||||
}
|
||||
|
||||
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 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 sanitize()
|
||||
{
|
||||
// all elements in xml doc
|
||||
$allElements = $this->xmlDoc->getElementsByTagName('*');
|
||||
public function sanitize()
|
||||
{
|
||||
// all elements in xml doc
|
||||
$allElements = $this->xmlDoc->getElementsByTagName('*');
|
||||
|
||||
// loop through all elements
|
||||
for($i = 0; $i < $allElements->length; $i++)
|
||||
{
|
||||
$this->removedattrs = [];
|
||||
|
||||
$currentNode = $allElements->item($i);
|
||||
// loop through all elements
|
||||
for ($i = 0; $i < $allElements->length; $i++) {
|
||||
$this->removedattrs = [];
|
||||
|
||||
// logger('current_node: ' . print_r($currentNode,true));
|
||||
$currentNode = $allElements->item($i);
|
||||
|
||||
// array of allowed attributes in specific element
|
||||
$allowlist_attr_arr = self::$allowlist[$currentNode->tagName];
|
||||
// logger('current_node: ' . print_r($currentNode,true));
|
||||
|
||||
// does element exist in allowlist?
|
||||
if(isset($allowlist_attr_arr)) {
|
||||
$total = $currentNode->attributes->length;
|
||||
|
||||
for($x = 0; $x < $total; $x++) {
|
||||
// array of allowed attributes in specific element
|
||||
$allowlist_attr_arr = self::$allowlist[$currentNode->tagName];
|
||||
|
||||
// get attributes name
|
||||
$attrName = $currentNode->attributes->item($x)->nodeName;
|
||||
// does element exist in allowlist?
|
||||
if (isset($allowlist_attr_arr)) {
|
||||
$total = $currentNode->attributes->length;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
for ($x = 0; $x < $total; $x++) {
|
||||
|
||||
}
|
||||
// get attributes name
|
||||
$attrName = $currentNode->attributes->item($x)->nodeName;
|
||||
|
||||
// else remove element
|
||||
else {
|
||||
logger('remove_node: ' . print_r($currentNode,true));
|
||||
$currentNode->parentNode->removeChild($currentNode);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// logger('checking: ' . print_r($currentNode->attributes->item($x),true));
|
||||
$matches = false;
|
||||
|
||||
function saveSVG() {
|
||||
$this->xmlDoc->formatOutput = true;
|
||||
return($this->xmlDoc->saveXML());
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
public function saveSVG()
|
||||
{
|
||||
$this->xmlDoc->formatOutput = true;
|
||||
return ($this->xmlDoc->saveXML());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -521,8 +521,8 @@ class ThreadItem {
|
|||
$additional_mentions = [];
|
||||
foreach ($item['term'] as $t) {
|
||||
if ($t['ttype'] == TERM_MENTION) {
|
||||
$additional_mentions[] = ((($position = strpos($t['url'],'url=')) !== false) ? urldecode(substr($t['url'],$position + 4)) : $t['url']);;
|
||||
}
|
||||
$additional_mentions[] = ((($position = strpos($t['url'],'url=')) !== false) ? urldecode(substr($t['url'],$position + 4)) : $t['url']);
|
||||
}
|
||||
}
|
||||
if ($additional_mentions) {
|
||||
$r = q("select hubloc_addr, hubloc_id_url, hubloc_hash from hubloc where hubloc_id_url in (" . protect_sprintf(stringify_array($additional_mentions, true)) . ") ");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
|
||||
require_once('boot.php');
|
||||
require_once('include/text.php');
|
||||
|
||||
|
@ -45,7 +47,7 @@ class ThreadStream {
|
|||
if($this->get_mode() == $mode)
|
||||
return;
|
||||
|
||||
$this->observer = \App::get_observer();
|
||||
$this->observer = App::get_observer();
|
||||
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
|
||||
|
||||
switch($mode) {
|
||||
|
@ -62,16 +64,16 @@ class ThreadStream {
|
|||
$this->writable = true;
|
||||
break;
|
||||
case 'channel':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->profile_owner = App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
case 'cards':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->profile_owner = App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'articles':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->profile_owner = App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
|
@ -83,7 +85,7 @@ class ThreadStream {
|
|||
$this->uploadable = perm_is_allowed($this->profile_owner,$ob_hash,'write_storage');
|
||||
break;
|
||||
case 'page':
|
||||
$this->profile_owner = \App::$profile['uid'];
|
||||
$this->profile_owner = App::$profile['uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
if ($m['host'] !== punify($m['host'])) {
|
||||
$url = str_replace($m['host'],punify($m['host']),$url);
|
||||
$m['host'] = punify($m['host']);
|
||||
}
|
||||
$m = parse_url($resource);
|
||||
|
||||
$data = json_encode([ 'zot_token' => random_string() ]);
|
||||
if ($m['host'] !== punify($m['host'])) {
|
||||
$url = str_replace($m['host'], punify($m['host']), $url);
|
||||
$m['host'] = punify($m['host']);
|
||||
}
|
||||
|
||||
if ($channel && $m) {
|
||||
$data = json_encode(['zot_token' => random_string()]);
|
||||
|
||||
$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 = [];
|
||||
if ($channel && $m) {
|
||||
|
||||
$redirects = 0;
|
||||
$x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] );
|
||||
$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'];
|
||||
}
|
||||
|
||||
if ($x['success']) {
|
||||
$result = [];
|
||||
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
}
|
||||
|
||||
$result['data'] = json_decode($x['body'],true);
|
||||
$redirects = 0;
|
||||
$x = z_post_url($resource, $data, $redirects, ['headers' => $h]);
|
||||
|
||||
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 ($x['success']) {
|
||||
|
||||
return $result;
|
||||
}
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
$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);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
||||
function init() {
|
||||
public 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.
|
||||
|
||||
|
||||
// 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 ( (! local_channel()) && (! in_array($type, [ 'x', 'c', 'f' ]))) {
|
||||
killme();
|
||||
}
|
||||
|
||||
$permitted = [];
|
||||
|
||||
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.
|
||||
|
||||
$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');
|
||||
}
|
||||
// $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.
|
||||
|
||||
|
||||
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) ? "%@%'" : "%'")) . ") ";
|
||||
// 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 ((!local_channel()) && (!in_array($type, ['x', 'c', 'f']))) {
|
||||
killme();
|
||||
}
|
||||
|
||||
$permitted = [];
|
||||
|
||||
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.
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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, ";
|
||||
|
||||
$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) . "%'") . ") ";
|
||||
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) ? "%@%'" : "%'")) . ") ";
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = $sql_extra4 = "";
|
||||
}
|
||||
|
||||
|
||||
$groups = [];
|
||||
$contacts = [];
|
||||
|
||||
if ($type == '' || $type == 'g') {
|
||||
// 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)).
|
||||
|
||||
// Normal privacy groups
|
||||
$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, ";
|
||||
|
||||
$r = q("SELECT pgrp.id, pgrp.hash, pgrp.gname
|
||||
$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) . "%'") . ") ";
|
||||
|
||||
|
||||
} else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = $sql_extra4 = "";
|
||||
}
|
||||
|
||||
|
||||
$groups = [];
|
||||
$contacts = [];
|
||||
|
||||
if ($type == '' || $type == 'g') {
|
||||
|
||||
// Normal privacy groups
|
||||
|
||||
$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 ($type == '' || $type == 'c' || $type === 'f') {
|
||||
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" => ''
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Getting info from the abook is better for local users because it contains info about permissions
|
||||
if (local_channel()) {
|
||||
if ($type == '' || $type == 'c' || $type === 'f') {
|
||||
|
||||
// add connections
|
||||
// Getting info from the abook is better for local users because it contains info about permissions
|
||||
if (local_channel()) {
|
||||
|
||||
$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
|
||||
// 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
|
||||
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())
|
||||
);
|
||||
|
||||
}
|
||||
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');
|
||||
}
|
||||
}
|
||||
WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc limit $count",
|
||||
dbesc(get_observer_hash())
|
||||
);
|
||||
|
||||
}
|
||||
elseif ($type == 'm') {
|
||||
}
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
$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
|
||||
} 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
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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
|
||||
intval(local_channel())
|
||||
);
|
||||
if ($z) {
|
||||
foreach ($z as $zz) {
|
||||
if (in_array($zz['hash'], $permitted)) {
|
||||
$r[] = $zz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} 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
|
||||
WHERE abook_channel = %d
|
||||
and xchan_deleted = 0
|
||||
$sql_extra3
|
||||
ORDER BY xchan_name ASC ",
|
||||
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
|
||||
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
|
||||
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 = [];
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $g) {
|
||||
|
||||
if (isset($g['network']) && in_array($g['network'],['rss','anon','unknown']) && ($type != 'a')) {
|
||||
continue;
|
||||
}
|
||||
$o = [
|
||||
'start' => $start,
|
||||
'count' => $count,
|
||||
'items' => $contacts,
|
||||
];
|
||||
json_return_and_die($o);
|
||||
} else {
|
||||
$r = [];
|
||||
}
|
||||
|
||||
// 'z' (activity_filter autocomplete) requires an un-encoded hash to prevent double encoding
|
||||
|
||||
if ($type !== 'z') {
|
||||
$g['hash'] = urlencode($g['hash']);
|
||||
}
|
||||
|
||||
if (! $g['nick']) {
|
||||
$g['nick'] = $g['url'];
|
||||
}
|
||||
if ($r) {
|
||||
foreach ($r as $g) {
|
||||
|
||||
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);
|
||||
|
||||
$o = [
|
||||
'start' => $start,
|
||||
'count' => $count,
|
||||
'items' => $items,
|
||||
];
|
||||
if (isset($g['network']) && in_array($g['network'], ['rss', 'anon', 'unknown']) && ($type != 'a')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_return_and_die($o);
|
||||
}
|
||||
// 'z' (activity_filter autocomplete) requires an un-encoded hash to prevent double encoding
|
||||
|
||||
if ($type !== 'z') {
|
||||
$g['hash'] = urlencode($g['hash']);
|
||||
}
|
||||
|
||||
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" => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$items = array_merge($groups, $contacts);
|
||||
|
||||
$o = [
|
||||
'start' => $start,
|
||||
'count' => $count,
|
||||
'items' => $items,
|
||||
];
|
||||
|
||||
json_return_and_die($o);
|
||||
}
|
||||
|
||||
|
||||
function navbar_complete() {
|
||||
|
||||
// logger('navbar_complete');
|
||||
|
||||
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 [];
|
||||
}
|
||||
|
||||
$star = false;
|
||||
$address = false;
|
||||
|
||||
if (substr($search,0,1) === '@') {
|
||||
$search = substr($search,1);
|
||||
}
|
||||
|
||||
if (substr($search,0,1) === '*') {
|
||||
$star = true;
|
||||
$search = substr($search,1);
|
||||
}
|
||||
public function navbar_complete()
|
||||
{
|
||||
|
||||
if (strpos($search,'@') !== false) {
|
||||
$address = true;
|
||||
}
|
||||
// logger('navbar_complete');
|
||||
|
||||
|
||||
$url = z_root() . '/dirsearch';
|
||||
if (observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$results = [];
|
||||
$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 [];
|
||||
}
|
||||
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
||||
$star = false;
|
||||
$address = false;
|
||||
|
||||
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;
|
||||
}
|
||||
if (substr($search, 0, 1) === '@') {
|
||||
$search = substr($search, 1);
|
||||
}
|
||||
|
||||
if (substr($search, 0, 1) === '*') {
|
||||
$star = true;
|
||||
$search = substr($search, 1);
|
||||
}
|
||||
|
||||
if (strpos($search, '@') !== false) {
|
||||
$address = true;
|
||||
}
|
||||
|
||||
|
||||
$url = z_root() . '/dirsearch';
|
||||
|
||||
|
||||
$results = [];
|
||||
|
||||
$count = (x($_REQUEST, 'count') ? $_REQUEST['count'] : 100);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 (! $item_id) {
|
||||
return;
|
||||
}
|
||||
if (ActivityStreams::is_as_request()) {
|
||||
$item_id = argv(1);
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$item_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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 ($ob_authorize) {
|
||||
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
|
||||
}
|
||||
else {
|
||||
$sql_extra = item_permissions_sql(0);
|
||||
}
|
||||
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
|
||||
// Give ocap tokens priority
|
||||
|
||||
$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 ($ob_authorize) {
|
||||
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
|
||||
} else {
|
||||
$sql_extra = item_permissions_sql(0);
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
$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) {
|
||||
http_status_exit(403, 'Forbidden');
|
||||
}
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
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)
|
||||
);
|
||||
|
||||
xchan_query($r,true);
|
||||
$items = fetch_post_tags($r,false);
|
||||
if ($r) {
|
||||
http_status_exit(403, 'Forbidden');
|
||||
}
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
xchan_query($r, true);
|
||||
$items = fetch_post_tags($r, false);
|
||||
|
||||
$channel = channelx_by_n($items[0]['uid']);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
as_return_and_die(ZlibActivity::encode_activity($items[0],true),$channel);
|
||||
$channel = channelx_by_n($items[0]['uid']);
|
||||
|
||||
}
|
||||
as_return_and_die(ZlibActivity::encode_activity($items[0], true), $channel);
|
||||
|
||||
if (Libzot::is_zot_request()) {
|
||||
}
|
||||
|
||||
$item_id = argv(1);
|
||||
if (Libzot::is_zot_request()) {
|
||||
|
||||
if (! $item_id) {
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
$portable_id = EMPTY_STR;
|
||||
$item_id = argv(1);
|
||||
|
||||
$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' ) ";
|
||||
if (!$item_id) {
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
$i = null;
|
||||
$portable_id = EMPTY_STR;
|
||||
|
||||
// do we have the item (at all)?
|
||||
$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' ) ";
|
||||
|
||||
$r = q("select * from item where mid = '%s' $item_normal limit 1",
|
||||
dbesc(z_root() . '/activity/' . $item_id)
|
||||
);
|
||||
$i = null;
|
||||
|
||||
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');
|
||||
}
|
||||
// do we have the item (at all)?
|
||||
|
||||
// process an authenticated fetch
|
||||
$r = q("select * from item where mid = '%s' $item_normal limit 1",
|
||||
dbesc(z_root() . '/activity/' . $item_id)
|
||||
);
|
||||
|
||||
$sigdata = HTTPSig::verify(EMPTY_STR);
|
||||
if($sigdata['portable_id'] && $sigdata['header_valid']) {
|
||||
$portable_id = $sigdata['portable_id'];
|
||||
observer_auth($portable_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');
|
||||
}
|
||||
|
||||
// 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
|
||||
// process an authenticated fetch
|
||||
|
||||
$x = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($sigdata['portable_id'])
|
||||
);
|
||||
$sigdata = HTTPSig::verify(EMPTY_STR);
|
||||
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
|
||||
$portable_id = $sigdata['portable_id'];
|
||||
observer_auth($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'])
|
||||
);
|
||||
// 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
|
||||
|
||||
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'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$x = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($sigdata['portable_id'])
|
||||
);
|
||||
|
||||
// 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 ($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'])
|
||||
);
|
||||
|
||||
$sql_extra = item_permissions_sql(0);
|
||||
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 (! $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 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)
|
||||
|
||||
$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'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$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'])
|
||||
);
|
||||
}
|
||||
|
||||
$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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
function __construct() {
|
||||
$this->sm = new SubModule();
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->sm = new SubModule();
|
||||
}
|
||||
|
||||
function init() {
|
||||
public function init()
|
||||
{
|
||||
|
||||
logger('admin_init', LOGGER_DEBUG);
|
||||
logger('admin_init', LOGGER_DEBUG);
|
||||
|
||||
if (! is_site_admin()) {
|
||||
logger('admin denied.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc() > 1) {
|
||||
$this->sm->call('init');
|
||||
}
|
||||
}
|
||||
if (!is_site_admin()) {
|
||||
logger('admin denied.');
|
||||
return;
|
||||
}
|
||||
|
||||
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 (argc() > 1) {
|
||||
$this->sm->call('post');
|
||||
}
|
||||
if (!is_site_admin()) {
|
||||
logger('admin denied.');
|
||||
return;
|
||||
}
|
||||
|
||||
// goaway(z_root() . '/admin' );
|
||||
}
|
||||
if (argc() > 1) {
|
||||
$this->sm->call('post');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
// goaway(z_root() . '/admin' );
|
||||
}
|
||||
|
||||
function get() {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
logger('admin_content', LOGGER_DEBUG);
|
||||
public function get()
|
||||
{
|
||||
|
||||
if (! is_site_admin()) {
|
||||
logger('admin denied.');
|
||||
return login(false);
|
||||
}
|
||||
logger('admin_content', LOGGER_DEBUG);
|
||||
|
||||
/*
|
||||
* Page content
|
||||
*/
|
||||
if (!is_site_admin()) {
|
||||
logger('admin denied.');
|
||||
return login(false);
|
||||
}
|
||||
|
||||
nav_set_selected('Admin');
|
||||
/*
|
||||
* Page content
|
||||
*/
|
||||
|
||||
$o = '';
|
||||
nav_set_selected('Admin');
|
||||
|
||||
if (argc() > 1) {
|
||||
$o = $this->sm->call('get');
|
||||
if ($o === false) {
|
||||
notice( t('Item not found.') );
|
||||
}
|
||||
}
|
||||
else {
|
||||
$o = $this->admin_page_summary();
|
||||
}
|
||||
$o = '';
|
||||
|
||||
if (is_ajax()) {
|
||||
echo $o;
|
||||
killme();
|
||||
}
|
||||
else {
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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')
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -4,199 +4,202 @@ namespace Zotlabs\Module\Admin;
|
|||
|
||||
use App;
|
||||
|
||||
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.
|
||||
*
|
||||
*/
|
||||
class Accounts
|
||||
{
|
||||
|
||||
function post() {
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
*/
|
||||
|
||||
$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');
|
||||
|
||||
public function post()
|
||||
{
|
||||
|
||||
// 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)) );
|
||||
}
|
||||
$pending = (x($_POST, 'pending') ? $_POST['pending'] : []);
|
||||
$users = (x($_POST, 'user') ? $_POST['user'] : []);
|
||||
$blocked = (x($_POST, 'blocked') ? $_POST['blocked'] : []);
|
||||
|
||||
// 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 deny button was submitted
|
||||
if (x($_POST, 'page_accounts_deny')) {
|
||||
foreach ($pending as $hash) {
|
||||
account_deny($hash);
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/admin/accounts' );
|
||||
}
|
||||
check_form_security_token_redirectOnErr('/admin/accounts', '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
|
||||
*/
|
||||
|
||||
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' );
|
||||
}
|
||||
|
||||
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
|
||||
|
||||
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' 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;
|
||||
}
|
||||
|
||||
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 accounts */
|
||||
|
||||
$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']) . "' " : '');
|
||||
// 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)));
|
||||
}
|
||||
|
||||
$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');
|
||||
// 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)));
|
||||
}
|
||||
|
||||
$users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked,
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
|
||||
|
||||
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' 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;
|
||||
}
|
||||
|
||||
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 accounts */
|
||||
|
||||
$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']) . "' " : '');
|
||||
|
||||
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
|
||||
$dir = 'asc';
|
||||
if (array_key_exists('dir', $_REQUEST)) {
|
||||
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
|
||||
}
|
||||
|
||||
$base = z_root() . '/admin/accounts?f=';
|
||||
$odir = (($dir === 'asc') ? '0' : '1');
|
||||
|
||||
$users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked,
|
||||
(SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac
|
||||
where true $serviceclass 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,
|
||||
]);
|
||||
|
||||
$o .= paginate($a);
|
||||
|
||||
return $o;
|
||||
}
|
||||
$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);
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,479 +2,483 @@
|
|||
|
||||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
use \Zotlabs\Storage\GitRepo;
|
||||
use \Michelf\MarkdownExtra;
|
||||
use App;
|
||||
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 (\PHPGit\Exception\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'])));
|
||||
}
|
||||
|
||||
}
|
|
@ -9,175 +9,183 @@ use Zotlabs\Daemon\Run;
|
|||
* @brief Admin Module for Channels.
|
||||
*
|
||||
*/
|
||||
|
||||
class Channels {
|
||||
class Channels
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Handle POST actions on channels admin page.
|
||||
*
|
||||
*/
|
||||
function post() {
|
||||
/**
|
||||
* @brief Handle POST actions on channels admin page.
|
||||
*
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public 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);
|
||||
}; break;
|
||||
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);
|
||||
}; break;
|
||||
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);
|
||||
}; break;
|
||||
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;
|
||||
|
||||
$channels[$x]['channel_link'] = z_root() . '/channel/' . $channels[$x]['channel_address'];
|
||||
}
|
||||
}
|
||||
if ($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE)
|
||||
$channels[$x]['allowcode'] = true;
|
||||
else
|
||||
$channels[$x]['allowcode'] = false;
|
||||
|
||||
call_hooks('admin_channels',$channels);
|
||||
$channels[$x]['channel_link'] = z_root() . '/channel/' . $channels[$x]['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' ]),
|
||||
call_hooks('admin_channels', $channels);
|
||||
|
||||
'$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?'),
|
||||
$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']),
|
||||
|
||||
'$form_security_token' => get_form_security_token('admin_channels'),
|
||||
'$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?'),
|
||||
|
||||
// values //
|
||||
'$baseurl' => z_root(),
|
||||
'$channels' => $channels,
|
||||
]);
|
||||
$o .= paginate($a);
|
||||
'$form_security_token' => get_form_security_token('admin_channels'),
|
||||
|
||||
return $o;
|
||||
}
|
||||
// values //
|
||||
'$baseurl' => z_root(),
|
||||
'$channels' => $channels,
|
||||
]);
|
||||
$o .= paginate($a);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
class Cover_photo {
|
||||
$srcX = intval($_POST['xstart']);
|
||||
$srcY = intval($_POST['ystart']);
|
||||
$srcW = intval($_POST['xfinal']) - $srcX;
|
||||
$srcH = intval($_POST['yfinal']) - $srcY;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$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'])
|
||||
);
|
||||
|
||||
|
||||
$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) {
|
||||
$scaled_width = $g[0]['width'];
|
||||
$scaled_height = $g[0]['height'];
|
||||
|
||||
$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'])) {
|
||||
if ((!$scaled_width) || (!$scaled_height)) {
|
||||
logger('potential divide by zero scaling cover photo');
|
||||
return;
|
||||
}
|
||||
|
||||
$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']));
|
||||
}
|
||||
// unset all other cover photos
|
||||
|
||||
$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);
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_COVER),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$im->doScaleImage(850,310);
|
||||
$p['imgscale'] = 8;
|
||||
$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'];
|
||||
|
||||
$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;
|
||||
$im->cropImageRect(1200, 435, $orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
$aid = get_account_id();
|
||||
|
||||
if ($partial) {
|
||||
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
|
||||
$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']
|
||||
];
|
||||
|
||||
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));
|
||||
$p['imgscale'] = 7;
|
||||
$p['photo_usage'] = PHOTO_COVER;
|
||||
|
||||
$_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']
|
||||
];
|
||||
}
|
||||
}
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
|
||||
|
||||
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Cover Photos'), 'hash' => $hash));
|
||||
|
||||
logger('attach_store: ' . print_r($res,true),LOGGER_DEBUG);
|
||||
$im->doScaleImage(850, 310);
|
||||
$p['imgscale'] = 8;
|
||||
|
||||
json_return_and_die([ 'message' => $hash ]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
$newuser = false;
|
||||
|
||||
if (argc() == 3 && argv(1) === 'new')
|
||||
$newuser = true;
|
||||
$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');
|
||||
|
||||
}
|
||||
|
||||
|
||||
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'])
|
||||
);
|
||||
}
|
||||
$hash = photo_new_resource();
|
||||
$smallest = 0;
|
||||
|
||||
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);
|
||||
|
||||
$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'])
|
||||
|
||||
);
|
||||
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']);
|
||||
}
|
||||
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->cover_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
|
||||
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'),
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
]);
|
||||
|
||||
call_hooks('cover_photo_content_end', $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
$filename = App::$data['imagecrop'] . '-3';
|
||||
$resolution = 3;
|
||||
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]);
|
||||
|
||||
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);
|
||||
|
||||
json_return_and_die(['message' => $hash]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public function get()
|
||||
{
|
||||
|
||||
if (!is_site_admin()) {
|
||||
notice(t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
// check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
|
||||
|
||||
$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 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 (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'])
|
||||
);
|
||||
|
||||
if ($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach ($i as $ii) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->cover_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
|
||||
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'),
|
||||
|
||||
]);
|
||||
|
||||
call_hooks('cover_photo_content_end', $o);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $a Current application
|
||||
* @param $ph Photo-Factory
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
public function cover_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);
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
$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
|
||||
*
|
||||
*/
|
||||
|
||||
function cover_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);
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,111 +3,101 @@
|
|||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
|
||||
|
||||
class Dbsync {
|
||||
|
||||
|
||||
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) === '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);
|
||||
|
||||
return $o;
|
||||
class Dbsync
|
||||
{
|
||||
|
||||
|
||||
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) === '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);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
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' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Logs admin page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function post()
|
||||
{
|
||||
if (x($_POST, 'page_logs')) {
|
||||
check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
|
||||
|
||||
function get() {
|
||||
|
||||
$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');
|
||||
|
||||
$f = get_config('system', 'logfile');
|
||||
|
||||
$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
|
||||
$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);
|
||||
}
|
||||
|
||||
info(t('Log settings updated.'));
|
||||
goaway(z_root() . '/admin/logs');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Logs admin page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
public function get()
|
||||
{
|
||||
|
||||
$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');
|
||||
|
||||
$f = get_config('system', 'logfile');
|
||||
|
||||
$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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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'),
|
||||
));
|
||||
}
|
||||
|
||||
} 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'),
|
||||
|
||||
// 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'),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -19,516 +19,513 @@ require_once('include/photo_factory.php');
|
|||
require_once('include/photos.php');
|
||||
|
||||
|
||||
class Profile_photo {
|
||||
|
||||
|
||||
/* @brief Initalize the profile-photo edit view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if(! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
Libprofile::load($channel['channel_address']);
|
||||
|
||||
}
|
||||
|
||||
/* @brief Evaluate posted values
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
if ((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
|
||||
// logger('crop: ' . print_r($_POST,true));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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) {
|
||||
|
||||
$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->cropImage(300,$srcX,$srcY,$srcW,$srcH);
|
||||
|
||||
$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['imgscale'] = PHOTO_RES_PROFILE_300;
|
||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
|
||||
|
||||
$im->scaleImage(80);
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_80;
|
||||
|
||||
$r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
|
||||
|
||||
$im->scaleImage(48);
|
||||
$p['imgscale'] = 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;
|
||||
}
|
||||
class Profile_photo
|
||||
{
|
||||
|
||||
|
||||
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
|
||||
/* @brief Initalize the profile-photo edit view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
public function init()
|
||||
{
|
||||
|
||||
if (!is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
Libprofile::load($channel['channel_address']);
|
||||
|
||||
}
|
||||
|
||||
/* @brief Evaluate posted values
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
public function post()
|
||||
{
|
||||
|
||||
if (!is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
if ((array_key_exists('cropfinal', $_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
|
||||
// logger('crop: ' . print_r($_POST,true));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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) {
|
||||
|
||||
$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->cropImage(300, $srcX, $srcY, $srcW, $srcH);
|
||||
|
||||
$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['imgscale'] = PHOTO_RES_PROFILE_300;
|
||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
|
||||
|
||||
$im->scaleImage(80);
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_80;
|
||||
|
||||
$r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
|
||||
|
||||
$im->scaleImage(48);
|
||||
$p['imgscale'] = 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;
|
||||
}
|
||||
|
||||
|
||||
$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'])
|
||||
);
|
||||
|
||||
// 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'
|
||||
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.
|
||||
|
||||
$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);
|
||||
|
||||
}
|
||||
else {
|
||||
notice( t('Unable to process image') . EOL);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$importing = false;
|
||||
$smallest = 0;
|
||||
|
||||
info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||
|
||||
if ($_REQUEST['importfile']) {
|
||||
$hash = $_REQUEST['importfile'];
|
||||
$importing = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
notice(t('Unable to process image') . EOL);
|
||||
}
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
goaway(z_root() . '/admin');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// A new photo was uploaded. Store it and save some important details
|
||||
// in App::$data for use in the cropping function
|
||||
|
||||
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));
|
||||
$hash = photo_new_resource();
|
||||
$importing = false;
|
||||
$smallest = 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('Profile Photos'), 'hash' => $hash));
|
||||
|
||||
logger('attach_store: ' . print_r($res,true), LOGGER_DEBUG);
|
||||
if ($_REQUEST['importfile']) {
|
||||
$hash = $_REQUEST['importfile'];
|
||||
$importing = true;
|
||||
} else {
|
||||
|
||||
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 (! $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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
// 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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
$pf = 0;
|
||||
$newuser = false;
|
||||
|
||||
if (argc() == 3 && argv(2) === 'new') {
|
||||
$newuser = 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 (argv(2) === 'reset') {
|
||||
Config::Delete('system','site_icon_url');
|
||||
}
|
||||
if ($partial) {
|
||||
$x = save_chunk($channel, $matches[1], $matches[2], $matches[3]);
|
||||
|
||||
if (argv(2) === 'use') {
|
||||
if (argc() < 4) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
};
|
||||
|
||||
$resource_id = argv(3);
|
||||
|
||||
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 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));
|
||||
|
||||
$c = q("select id, is_default from profile where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
$_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']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$multi_profiles = true;
|
||||
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Profile Photos'), 'hash' => $hash));
|
||||
|
||||
if (($c) && (count($c) === 1) && (intval($c[0]['is_default']))) {
|
||||
$_REQUEST['profile'] = $c[0]['id'];
|
||||
$multi_profiles = false;
|
||||
}
|
||||
else {
|
||||
$_REQUEST['profile'] = $pf;
|
||||
}
|
||||
logger('attach_store: ' . print_r($res, true), LOGGER_DEBUG);
|
||||
|
||||
$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
|
||||
|
||||
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 xchan set xchan_photo_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
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'])
|
||||
|
||||
);
|
||||
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']);
|
||||
}
|
||||
|
||||
$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 ($multi_profiles) {
|
||||
App::$data['importfile'] = $resource_id;
|
||||
}
|
||||
else {
|
||||
$this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
}
|
||||
json_return_and_die(['message' => $hash]);
|
||||
}
|
||||
|
||||
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
|
||||
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'])
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// present an upload form
|
||||
if (!$i) {
|
||||
notice(t('Image upload failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
$os_storage = false;
|
||||
|
||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
|
||||
$ph = photo_factory($imagedata, $filetype);
|
||||
|
||||
$importing = ((array_key_exists('importfile',App::$data)) ? true : false);
|
||||
|
||||
if (! array_key_exists('imagecrop', App::$data)) {
|
||||
|
||||
$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'),
|
||||
]);
|
||||
|
||||
call_hooks('profile_photo_content_end', $o);
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
if (!$ph->is_valid()) {
|
||||
notice(t('Unable to process image.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
// present a cropping form
|
||||
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
|
||||
$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
|
||||
*
|
||||
*/
|
||||
|
||||
function profile_photo_crop_ui_head($ph, $hash, $smallest) {
|
||||
$max_length = get_config('system','max_image_length', MAX_IMAGE_LENGTH);
|
||||
// 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
|
||||
}
|
||||
|
||||
if ($max_length > 0) {
|
||||
$ph->scaleImage($max_length);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public function get()
|
||||
{
|
||||
|
||||
if (!is_site_admin()) {
|
||||
notice(t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
$pf = 0;
|
||||
$newuser = false;
|
||||
|
||||
if (argc() == 3 && argv(2) === 'new') {
|
||||
$newuser = true;
|
||||
}
|
||||
|
||||
if (argv(2) === 'reset') {
|
||||
Config::Delete('system', 'site_icon_url');
|
||||
}
|
||||
|
||||
if (argv(2) === 'use') {
|
||||
if (argc() < 4) {
|
||||
notice(t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$resource_id = argv(3);
|
||||
|
||||
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0);
|
||||
|
||||
$c = q("select id, is_default from profile where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
$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
|
||||
|
||||
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 xchan set xchan_photo_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
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'])
|
||||
|
||||
);
|
||||
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']);
|
||||
}
|
||||
|
||||
$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 ($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
|
||||
|
||||
}
|
||||
|
||||
// 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'])
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
if (!array_key_exists('imagecrop', App::$data)) {
|
||||
|
||||
$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'),
|
||||
]);
|
||||
|
||||
call_hooks('profile_photo_content_end', $o);
|
||||
return $o;
|
||||
} else {
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $ph Photo-Factory
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,188 +3,187 @@
|
|||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
|
||||
class Profs {
|
||||
class Profs
|
||||
{
|
||||
|
||||
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);
|
||||
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('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');
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
goaway(z_root() . '/admin/profs');
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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) && 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')
|
||||
));
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
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'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add to chosen array basic or advanced
|
||||
|
||||
goaway(z_root() . '/admin/profs');
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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) && 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')
|
||||
));
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue