mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-20 06:55:19 +00:00
Merge remote-tracking branch 'upstream/dev' into doco
This commit is contained in:
commit
90ec3340e4
33 changed files with 906 additions and 66 deletions
47
Zotlabs/Daemon/Importfile.php
Normal file
47
Zotlabs/Daemon/Importfile.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Importfile {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
logger('Importfile: ' . print_r($argv,true));
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
$channel = channelx_by_n($argv[1]);
|
||||
if(! $channel)
|
||||
return;
|
||||
|
||||
$srcfile = $argv[2];
|
||||
$folder = (($argc > 3) ? $argv[3] : '');
|
||||
$dstname = (($argc > 4) ? $argv[4] : '');
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$arr = [
|
||||
'src' => $srcfile,
|
||||
'filename' => (($dstname) ? $dstname : basename($srcfile)),
|
||||
'hash' => $hash,
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid'],
|
||||
'preserve_original' => true,
|
||||
'replace' => true
|
||||
];
|
||||
|
||||
if($folder)
|
||||
$arr['folder'] = $folder;
|
||||
|
||||
attach_store($channel,$channel['channel_hash'],'import',$arr);
|
||||
|
||||
$sync = attach_export_data($channel,$hash);
|
||||
if($sync)
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -276,7 +276,7 @@ class Notifier {
|
|||
$deleted_item = true;
|
||||
}
|
||||
|
||||
if(intval($target_item['item_type']) != ITEM_TYPE_POST) {
|
||||
if(! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST ] )) {
|
||||
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -221,6 +221,7 @@ class Apps {
|
|||
static public function translate_system_apps(&$arr) {
|
||||
$apps = array(
|
||||
'Apps' => t('Apps'),
|
||||
'Cards' => t('Cards'),
|
||||
'Site Admin' => t('Site Admin'),
|
||||
'Report Bug' => t('Report Bug'),
|
||||
'View Bookmarks' => t('View Bookmarks'),
|
||||
|
|
|
@ -29,6 +29,7 @@ class ThreadItem {
|
|||
private $visiting = false;
|
||||
private $channel = null;
|
||||
private $display_mode = 'normal';
|
||||
private $reload = '';
|
||||
|
||||
|
||||
public function __construct($data) {
|
||||
|
@ -101,10 +102,13 @@ class ThreadItem {
|
|||
if($item['author']['xchan_network'] === 'rss')
|
||||
$shareable = true;
|
||||
|
||||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
$edlink = (($item['item_type'] == ITEM_TYPE_CARD) ? 'card_edit' : 'editpost');
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
|
||||
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
|
@ -480,6 +484,14 @@ class ThreadItem {
|
|||
return $this->threaded;
|
||||
}
|
||||
|
||||
public function set_reload($val) {
|
||||
$this->reload = $val;
|
||||
}
|
||||
|
||||
public function get_reload() {
|
||||
return $this->reload;
|
||||
}
|
||||
|
||||
public function set_commentable($val) {
|
||||
$this->commentable = $val;
|
||||
foreach($this->get_children() as $child)
|
||||
|
@ -716,7 +728,7 @@ class ThreadItem {
|
|||
$comment_box = replace_macros($template,array(
|
||||
'$return_path' => '',
|
||||
'$threaded' => $this->is_threaded(),
|
||||
'$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
|
||||
'$jsreload' => $conv->reload,
|
||||
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
||||
'$id' => $this->get_id(),
|
||||
'$parent' => $this->get_id(),
|
||||
|
|
|
@ -22,6 +22,7 @@ class ThreadStream {
|
|||
private $profile_owner = 0;
|
||||
private $preview = false;
|
||||
private $prepared_item = '';
|
||||
public $reload = '';
|
||||
private $cipher = 'aes256';
|
||||
|
||||
// $prepared_item is for use by alternate conversation structures such as photos
|
||||
|
@ -57,6 +58,11 @@ class ThreadStream {
|
|||
$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->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'display':
|
||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||
// pull some trickery which allows us to re-invoke this function afterward
|
||||
|
|
136
Zotlabs/Module/Card_edit.php
Normal file
136
Zotlabs/Module/Card_edit.php
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Card_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'CARD' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
|
||||
|
||||
$rp = 'cards/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x);
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Block'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
185
Zotlabs/Module/Cards.php
Normal file
185
Zotlabs/Module/Cards.php
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
|
||||
class Cards extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! \App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! feature_enabled(\App::$profile_uid,'cards')) {
|
||||
return;
|
||||
}
|
||||
|
||||
nav_set_selected(t('Cards'));
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = \App::$profile_uid;
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
);
|
||||
}
|
||||
else {
|
||||
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'is_owner' => true,
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner,'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
$editor = status_editor($a,$x);
|
||||
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_extra .= "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,6) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
|
||||
$parents_str = ids_to_querystr($r,'id');
|
||||
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE item.uid = %d $item_normal
|
||||
AND item.parent IN ( %s )
|
||||
$sql_extra $sql_extra2 ",
|
||||
intval(\App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($items) {
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items = conv_sort($items,'updated');
|
||||
}
|
||||
else
|
||||
$items = [];
|
||||
}
|
||||
|
||||
$mode = 'cards';
|
||||
|
||||
$content = conversation($items,$mode,false,'traditional');
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Cards'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($a,count($items))
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
|
@ -180,7 +180,12 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||
|
||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" title="oembed" />' . "\r\n";
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
|
|
|
@ -39,7 +39,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
$observer_is_owner = false;
|
||||
$updateable = false;
|
||||
|
||||
|
||||
|
||||
if(local_channel() && (! $update)) {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
@ -174,8 +174,13 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
'$verb' => '',
|
||||
'$mid' => $item_hash
|
||||
));
|
||||
|
||||
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
}
|
||||
|
||||
$observer_hash = get_observer_hash();
|
||||
|
@ -214,17 +219,17 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
if($r === null) {
|
||||
|
||||
// in case somebody turned off public access to sys channel content using permissions
|
||||
// make that content unsearchable by ensuring the owner_xchan can't match
|
||||
// make that content unsearchable by ensuring the owner uid can't match
|
||||
|
||||
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
||||
$sysid = 0;
|
||||
|
||||
|
||||
|
||||
$r = q("SELECT item.id as item_id from item
|
||||
WHERE mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
AND item.deny_gid = '' AND item_private = 0 )
|
||||
and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||
OR uid = %d )
|
||||
$sql_extra )
|
||||
$item_normal
|
||||
|
@ -232,7 +237,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
dbesc($target_item['parent_mid']),
|
||||
intval($sysid)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -735,6 +735,10 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
if($parent_item)
|
||||
$parent_mid = $parent_item['mid'];
|
||||
|
||||
if($webpage == ITEM_TYPE_CARD && $pagetitle) {
|
||||
$plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . $pagetitle;
|
||||
}
|
||||
|
||||
// Fallback so that we alway have a thr_parent
|
||||
|
||||
if(!$thr_parent)
|
||||
|
|
|
@ -95,7 +95,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
|
|||
echo $arr['text'];
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
if($process_oembed) {
|
||||
$x = oembed_process($url);
|
||||
if($x) {
|
||||
|
|
|
@ -41,6 +41,8 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
$arr = $this->oep_profile_reply($_REQUEST);
|
||||
elseif(fnmatch('*/profile/*',$url))
|
||||
$arr = $this->oep_profile_reply($_REQUEST);
|
||||
elseif(fnmatch('*/cards/*',$url))
|
||||
$arr = $this->oep_cards_reply($_REQUEST);
|
||||
|
||||
if($arr) {
|
||||
if($html) {
|
||||
|
@ -66,9 +68,9 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
$url = $args['url'];
|
||||
$maxwidth = intval($args['maxwidth']);
|
||||
$maxheight = intval($args['maxheight']);
|
||||
|
||||
if(preg_match('#//display/(.*?)(&|\?|$)#',$url,$matches)) {
|
||||
$res = $matches[1];
|
||||
logger('processing display');
|
||||
if(preg_match('#//(.*?)/display/(.*?)(&|\?|$)#',$url,$matches)) {
|
||||
$res = $matches[2];
|
||||
}
|
||||
|
||||
if(strpos($res,'b64.') === 0) {
|
||||
|
@ -78,7 +80,7 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
$item_normal = item_normal();
|
||||
|
||||
$p = q("select * from item where mid like '%s' limit 1",
|
||||
dbesc($res . '%'),
|
||||
dbesc($res . '%')
|
||||
);
|
||||
|
||||
if(! $p)
|
||||
|
@ -89,7 +91,10 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
|
||||
if(! ($c && $res))
|
||||
return;
|
||||
|
||||
|
||||
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_stream'))
|
||||
return;
|
||||
|
||||
$sql_extra = item_permissions_sql($c['channel_id']);
|
||||
|
||||
$p = q("select * from item where mid like '%s' and uid = %d $sql_extra $item_normal limit 1",
|
||||
|
@ -140,6 +145,91 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function oep_cards_reply($args) {
|
||||
|
||||
$ret = [];
|
||||
$url = $args['url'];
|
||||
$maxwidth = intval($args['maxwidth']);
|
||||
$maxheight = intval($args['maxheight']);
|
||||
|
||||
if(preg_match('#//(.*?)/cards/(.*?)/(.*?)(&|\?|$)#',$url,$matches)) {
|
||||
$nick = $matches[2];
|
||||
$res = $matches[3];
|
||||
}
|
||||
if(! ($nick && $res))
|
||||
return $ret;
|
||||
|
||||
$channel = channelx_by_nick($nick);
|
||||
|
||||
if(! $channel)
|
||||
return $ret;
|
||||
|
||||
|
||||
if(! perm_is_allowed($channel['channel_id'],get_observer_hash(),'view_pages'))
|
||||
return $ret;
|
||||
|
||||
$sql_extra = items_permissions_sql($channel['channel_id'],get_observer_hash());
|
||||
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1",
|
||||
dbesc($res)
|
||||
);
|
||||
if($r) {
|
||||
$sql_extra = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
else {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($channel['channel_id']),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,6) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$p = fetch_post_tags($r, true);
|
||||
}
|
||||
|
||||
$x = '2eGriplW^*Jmf4';
|
||||
|
||||
|
||||
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
|
||||
"' profile='".$p[0]['author']['xchan_url'] .
|
||||
"' avatar='".$p[0]['author']['xchan_photo_s'].
|
||||
"' link='".$p[0]['plink'].
|
||||
"' posted='".$p[0]['created'].
|
||||
"' message_id='".$p[0]['mid']."']";
|
||||
if($p[0]['title'])
|
||||
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
|
||||
|
||||
$o .= $x;
|
||||
$o .= "[/share]";
|
||||
$o = bbcode($o);
|
||||
|
||||
$o = str_replace($x,bbcode($p[0]['body']),$o);
|
||||
|
||||
$ret['type'] = 'rich';
|
||||
|
||||
$w = (($maxwidth) ? $maxwidth : 640);
|
||||
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
|
||||
|
||||
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
|
||||
|
||||
$ret['width'] = $w;
|
||||
$ret['height'] = $h;
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function oep_mid_reply($args) {
|
||||
|
||||
|
@ -161,6 +251,9 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
|
||||
if(! $c)
|
||||
return;
|
||||
|
||||
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_stream'))
|
||||
return;
|
||||
|
||||
$sql_extra = item_permissions_sql($c[0]['channel_id']);
|
||||
|
||||
|
@ -279,6 +372,9 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
if(! $c)
|
||||
return;
|
||||
|
||||
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_files'))
|
||||
return;
|
||||
|
||||
$sql_extra = permissions_sql($c[0]['channel_id']);
|
||||
|
||||
$p = q("select resource_id from photo where album = '%s' and uid = %d and imgscale = 0 $sql_extra order by created desc limit 1",
|
||||
|
@ -340,6 +436,9 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
if(! $c)
|
||||
return;
|
||||
|
||||
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_files'))
|
||||
return;
|
||||
|
||||
$sql_extra = permissions_sql($c[0]['channel_id']);
|
||||
|
||||
$p = q("select resource_id from photo where uid = %d and imgscale = 0 $sql_extra order by created desc limit 1",
|
||||
|
@ -400,7 +499,10 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
|
||||
if(! $c)
|
||||
return;
|
||||
|
||||
|
||||
if(! perm_is_allowed($c[0]['channel_id'],get_observer_hash(),'view_files'))
|
||||
return;
|
||||
|
||||
$sql_extra = permissions_sql($c[0]['channel_id']);
|
||||
|
||||
|
||||
|
|
|
@ -671,8 +671,13 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
*/
|
||||
|
||||
if($datatype === 'album') {
|
||||
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
if($x = photos_album_exists($owner_uid, get_observer_hash(), $datum)) {
|
||||
\App::set_pager_itemspage(60);
|
||||
|
|
|
@ -94,7 +94,6 @@ class Profile extends \Zotlabs\Web\Controller {
|
|||
echo \App::$profile['profile_vcard'];
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
|
||||
|
||||
|
@ -102,11 +101,14 @@ class Profile extends \Zotlabs\Web\Controller {
|
|||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
//$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
||||
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" title="oembed" />' . "\r\n";
|
||||
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
$o .= advanced_profile($a);
|
||||
call_hooks('profile_advanced',$o);
|
||||
return $o;
|
||||
|
|
|
@ -19,8 +19,8 @@ class Tasks extends \Zotlabs\Web\Controller {
|
|||
$arr['all'] = 1;
|
||||
|
||||
$x = tasks_fetch($arr);
|
||||
$x['html'] = '';
|
||||
if($x['tasks']) {
|
||||
$x['html'] = '';
|
||||
foreach($x['tasks'] as $y) {
|
||||
$x['html'] .= '<div class="tasklist-item"><input type="checkbox" onchange="taskComplete(' . $y['id'] . '); return false;" /> ' . $y['summary'] . '</div>';
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ class Tasks extends \Zotlabs\Web\Controller {
|
|||
if($x)
|
||||
$ret['success'] = true;
|
||||
}
|
||||
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
|
39
Zotlabs/Module/Update_cards.php
Normal file
39
Zotlabs/Module/Update_cards.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
* Module: update_profile
|
||||
* Purpose: AJAX synchronisation of profile page
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Update_cards extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body><section></section></body></html>\r\n";
|
||||
|
||||
killme();
|
||||
|
||||
|
||||
$mod = new Cards();
|
||||
|
||||
$text = $mod->get($profile_uid,$load);
|
||||
|
||||
/**
|
||||
* reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
|
||||
*/
|
||||
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -8,8 +8,13 @@ class Categories {
|
|||
|
||||
function widget($arr) {
|
||||
|
||||
$cards = ((array_key_exists('cards',$arr) && $arr['cards']) ? true : false);
|
||||
|
||||
if(($cards) && (! feature_enabled(\App::$profile['profile_uid'],'cards')))
|
||||
return '';
|
||||
|
||||
if((! \App::$profile['profile_uid'])
|
||||
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'view_stream'))) {
|
||||
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),(($cards) ? 'view_pages' : 'view_stream')))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -18,6 +23,10 @@ class Categories {
|
|||
$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
|
||||
$srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
|
||||
|
||||
return categories_widget($srchurl, $cat);
|
||||
if($cards)
|
||||
return cardcategories_widget($srchurl, $cat);
|
||||
else
|
||||
return categories_widget($srchurl, $cat);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
6
app/cards.apd
Normal file
6
app/cards.apd
Normal file
|
@ -0,0 +1,6 @@
|
|||
version: 1.1
|
||||
url: $baseurl/cards/$nick
|
||||
name: Cards
|
||||
requires: local_channel, cards
|
||||
photo: icon:list
|
||||
categories: Productivity
|
6
boot.php
6
boot.php
|
@ -256,7 +256,7 @@ define ( 'NETWORK_OSTATUS', 'stat'); // status.net, identi.ca, GNU-s
|
|||
define ( 'NETWORK_GNUSOCIAL', 'gnusoc'); // status.net, identi.ca, GNU-social, other OStatus implementations
|
||||
define ( 'NETWORK_FEED', 'rss'); // RSS/Atom feeds with no known "post/notify" protocol
|
||||
define ( 'NETWORK_DIASPORA', 'diaspora'); // Diaspora
|
||||
define ( 'NETWORK_ACTIVITYPUB', 'activitypub');
|
||||
define ( 'NETWORK_ACTIVITYPUB', 'activitypub');
|
||||
define ( 'NETWORK_MAIL', 'mail'); // IMAP/POP
|
||||
define ( 'NETWORK_MAIL2', 'mai2'); // extended IMAP/POP
|
||||
define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API
|
||||
|
@ -509,6 +509,7 @@ define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_ZOT . '/activity/profile' );
|
|||
define ( 'ACTIVITY_OBJ_THING', NAMESPACE_ZOT . '/activity/thing' );
|
||||
define ( 'ACTIVITY_OBJ_LOCATION',NAMESPACE_ZOT . '/activity/location' );
|
||||
define ( 'ACTIVITY_OBJ_FILE', NAMESPACE_ZOT . '/activity/file' );
|
||||
define ( 'ACTIVITY_OBJ_CARD', NAMESPACE_ZOT . '/activity/card' );
|
||||
|
||||
/**
|
||||
* Account Flags
|
||||
|
@ -547,6 +548,8 @@ define ( 'ITEM_PDL', 0x0200); // Page Description Language - e.g. Comanche
|
|||
define ( 'ITEM_BUG', 0x0400); // Is a bug, can be used by the internal bug tracker
|
||||
define ( 'ITEM_PENDING_REMOVE', 0x0800); // deleted, notification period has lapsed
|
||||
define ( 'ITEM_DOC', 0x1000); // hubzilla only, define here so that item import does the right thing
|
||||
define ( 'ITEM_CARD', 0x2000);
|
||||
|
||||
|
||||
define ( 'ITEM_TYPE_POST', 0 );
|
||||
define ( 'ITEM_TYPE_BLOCK', 1 );
|
||||
|
@ -554,6 +557,7 @@ define ( 'ITEM_TYPE_PDL', 2 );
|
|||
define ( 'ITEM_TYPE_WEBPAGE', 3 );
|
||||
define ( 'ITEM_TYPE_BUG', 4 );
|
||||
define ( 'ITEM_TYPE_DOC', 5 );
|
||||
define ( 'ITEM_TYPE_CARD', 6 );
|
||||
|
||||
define ( 'ITEM_IS_STICKY', 1000 );
|
||||
|
||||
|
|
|
@ -346,6 +346,19 @@ empty:
|
|||
1. After successful import (check!) delete your channel on the old RedMatrix Server.
|
||||
1. On the $Projectname server visit new.hub/locs and upgrade to your channel to a primary one. And when the old Redmatrix server is still listed delete them here as well. Press "Sync" to inform all other server in the grid.
|
||||
|
||||
### Administration
|
||||
|
||||
#### Site Administration
|
||||
|
||||
Administration of the website is commonly done through the admin webpage located at /admin on your website. In order to access this page you must have administration rights to the server. Administration rights are granted to the first account to register on your site, **provided** the email address of that account exactly matches the email address you provided as the administrator's email address during setup.
|
||||
|
||||
There are several ways that this can fail and leave the system without an administrator account, for instance if the first account that was created provided a different email address than the administrator email address that was supplied during setup.
|
||||
|
||||
For security reasons there is no web page or interface on the system which will give you administrator access. If you need to correct a situation where a system has no administrator account it **must** be done by editing the account table in the database. There is no other way. To do this, you will need to locate the entry in the account table which belongs to the desired administrator, and set 'account_roles' for that entry to 4096. You will then be able to access the admin page from your system's profile menu or directly via /admin .
|
||||
|
||||
A hub can have multiple admins and there is no limit to how administrators you can have. Repeat the above process for every account you wish to provide with administration rights.
|
||||
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Log files
|
||||
|
|
|
@ -460,6 +460,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
// By default remove $src when finished
|
||||
|
||||
$remove_when_processed = true;
|
||||
$import_replace = false;
|
||||
|
||||
if($options === 'import') {
|
||||
$src = $arr['src'];
|
||||
|
@ -476,6 +477,9 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
if($arr['preserve_original'])
|
||||
$remove_when_processed = false;
|
||||
|
||||
if($arr['replace'])
|
||||
$import_replace = true;
|
||||
|
||||
// if importing a directory, just do it now and go home - we're done.
|
||||
|
||||
if(array_key_exists('is_dir',$arr) && intval($arr['is_dir'])) {
|
||||
|
@ -617,8 +621,10 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
dbesc($folder_hash)
|
||||
);
|
||||
if($r) {
|
||||
$overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
|
||||
$overwrite = (($import_replace || get_pconfig($channel_id,'system','overwrite_dup_files')) ? true : false);
|
||||
if(($overwrite) || ($options === 'import')) {
|
||||
if(! array_key_exists('edited',$arr))
|
||||
$arr['edited'] = datetime_convert();
|
||||
$options = 'replace';
|
||||
$existing_id = $x[0]['id'];
|
||||
$existing_size = intval($x[0]['filesize']);
|
||||
|
|
|
@ -100,6 +100,49 @@ function categories_widget($baseurl,$selected = '') {
|
|||
return '';
|
||||
}
|
||||
|
||||
function cardcategories_widget($baseurl,$selected = '') {
|
||||
|
||||
if(! feature_enabled(App::$profile['profile_uid'],'categories'))
|
||||
return '';
|
||||
|
||||
$item_normal = "and item.item_hidden = 0 and item.item_type = 6 and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
$terms = array();
|
||||
$r = q("select distinct(term.term)
|
||||
from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
and term.otype = %d
|
||||
and item.owner_xchan = '%s'
|
||||
$item_normal
|
||||
order by term.term asc",
|
||||
intval(App::$profile['profile_uid']),
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_OBJ_POST),
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
);
|
||||
if($r && count($r)) {
|
||||
foreach($r as $rr)
|
||||
$terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : ''));
|
||||
|
||||
return replace_macros(get_markup_template('categories_widget.tpl'),array(
|
||||
'$title' => t('Categories'),
|
||||
'$desc' => '',
|
||||
'$sel_all' => (($selected == '') ? 'selected' : ''),
|
||||
'$all' => t('Everything'),
|
||||
'$terms' => $terms,
|
||||
'$base' => $baseurl,
|
||||
|
||||
));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
function common_friends_visitor_widget($profile_uid) {
|
||||
|
||||
if(local_channel() == $profile_uid)
|
||||
|
|
|
@ -464,6 +464,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
$profile_owner = 0;
|
||||
$page_writeable = false;
|
||||
$live_update_div = '';
|
||||
$jsreload = '';
|
||||
|
||||
$preview = (($page_mode === 'preview') ? true : false);
|
||||
$previewing = (($preview) ? ' preview ' : '');
|
||||
|
@ -517,6 +518,16 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
}
|
||||
}
|
||||
|
||||
elseif ($mode === 'cards') {
|
||||
$profile_owner = App::$profile['profile_uid'];
|
||||
$page_writeable = ($profile_owner == local_channel());
|
||||
$live_update_div = '<div id="live-cards"></div>' . "\r\n"
|
||||
. "<script> var profile_uid = " . App::$profile['profile_uid']
|
||||
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
|
||||
$jsreload = $_SESSION['return_url'];
|
||||
}
|
||||
|
||||
|
||||
elseif ($mode === 'display') {
|
||||
$profile_owner = local_channel();
|
||||
$page_writeable = false;
|
||||
|
@ -808,6 +819,10 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
$item_object->set_template('conv_list.tpl');
|
||||
$item_object->set_display_mode('list');
|
||||
}
|
||||
if($page_mode === 'cards') {
|
||||
$item_object->set_reload($jsreload);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1305,6 +1320,11 @@ function status_editor($a, $x, $popup = false) {
|
|||
if(! $cipher)
|
||||
$cipher = 'aes256';
|
||||
|
||||
if(array_key_exists('catsenabled',$x))
|
||||
$catsenabled = $x['catsenabled'];
|
||||
else
|
||||
$catsenabled = ((feature_enabled($x['profile_uid'], 'categories') && (! $webpage)) ? 'categories' : '');
|
||||
|
||||
// avoid illegal offset errors
|
||||
if(! array_key_exists('permissions',$x))
|
||||
$x['permissions'] = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
|
@ -1349,7 +1369,7 @@ function status_editor($a, $x, $popup = false) {
|
|||
'$clearloc' => $clearloc,
|
||||
'$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''),
|
||||
'$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')),
|
||||
'$catsenabled' => ((feature_enabled($x['profile_uid'], 'categories') && (! $webpage)) ? 'categories' : ''),
|
||||
'$catsenabled' => $catsenabled,
|
||||
'$category' => ((x($x, 'category')) ? $x['category'] : ''),
|
||||
'$placeholdercategory' => t('Categories (optional, comma-separated list)'),
|
||||
'$permset' => t('Permission settings'),
|
||||
|
@ -1456,6 +1476,8 @@ function conv_sort($arr, $order) {
|
|||
usort($parents,'sort_thr_created');
|
||||
elseif(stristr($order,'commented'))
|
||||
usort($parents,'sort_thr_commented');
|
||||
elseif(stristr($order,'updated'))
|
||||
usort($parents,'sort_thr_updated');
|
||||
elseif(stristr($order,'ascending'))
|
||||
usort($parents,'sort_thr_created_rev');
|
||||
|
||||
|
@ -1497,6 +1519,12 @@ function sort_thr_commented($a,$b) {
|
|||
return strcmp($b['commented'],$a['commented']);
|
||||
}
|
||||
|
||||
function sort_thr_updated($a,$b) {
|
||||
$indexa = (($a['changed'] > $a['edited']) ? $a['changed'] : $a['edited']);
|
||||
$indexb = (($b['changed'] > $b['edited']) ? $b['changed'] : $b['edited']);
|
||||
return strcmp($indexb,$indexa);
|
||||
}
|
||||
|
||||
function find_thread_parent_index($arr,$x) {
|
||||
foreach($arr as $k => $v)
|
||||
if($v['id'] == $x['parent'])
|
||||
|
@ -1835,7 +1863,8 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
|
|||
|
||||
require_once('include/menu.php');
|
||||
$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
|
||||
if ($is_owner && $has_bookmarks) {
|
||||
|
||||
if($is_owner && $has_bookmarks) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Bookmarks'),
|
||||
'url' => z_root() . '/bookmarks',
|
||||
|
@ -1846,6 +1875,17 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
|
|||
);
|
||||
}
|
||||
|
||||
if(feature_enabled($uid,'cards')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Cards'),
|
||||
'url' => z_root() . '/cards/' . $nickname,
|
||||
'sel' => ((argv(0) == 'cards') ? 'active' : ''),
|
||||
'title' => t('View Cards'),
|
||||
'id' => 'cards-tab',
|
||||
'icon' => 'list'
|
||||
);
|
||||
}
|
||||
|
||||
if($has_webpages && feature_enabled($uid,'webpages')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Webpages'),
|
||||
|
@ -1856,7 +1896,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
|
|||
'icon' => 'newspaper-o'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($p['view_wiki']) {
|
||||
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
|
||||
|
|
|
@ -117,6 +117,15 @@ function get_features($filtered = true) {
|
|||
feature_level('private_notes',1),
|
||||
],
|
||||
|
||||
[
|
||||
'cards',
|
||||
t('Cards'),
|
||||
t('Create personal planning cards'),
|
||||
false,
|
||||
get_config('feature_lock','cards'),
|
||||
feature_level('cards',1),
|
||||
],
|
||||
|
||||
[
|
||||
'nav_channel_select',
|
||||
t('Navigation Channel Select'),
|
||||
|
|
|
@ -4111,6 +4111,8 @@ function webpage_to_namespace($webpage) {
|
|||
$page_type = 'BUILDBLOCK';
|
||||
elseif($webpage == ITEM_TYPE_PDL)
|
||||
$page_type = 'PDL';
|
||||
elseif($webpage == ITEM_TYPE_CARD)
|
||||
$page_type = 'CARD';
|
||||
elseif($webpage == ITEM_TYPE_DOC)
|
||||
$page_type = 'docfile';
|
||||
else
|
||||
|
|
|
@ -434,6 +434,18 @@ function channel_apps($is_owner = false, $nickname = null) {
|
|||
];
|
||||
}
|
||||
|
||||
if($p['view_pages'] && feature_enabled($uid,'cards')) {
|
||||
$tabs[] = [
|
||||
'label' => t('Cards'),
|
||||
'url' => z_root() . '/cards/' . $nickname ,
|
||||
'sel' => ((argv(0) == 'cards') ? 'active' : ''),
|
||||
'title' => t('View Cards'),
|
||||
'id' => 'cards-tab',
|
||||
'icon' => 'list'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
if($has_webpages && feature_enabled($uid,'webpages')) {
|
||||
$tabs[] = [
|
||||
'label' => t('Webpages'),
|
||||
|
|
|
@ -199,6 +199,62 @@ function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $re
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_CATEGORY) {
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
if(! perm_is_allowed($uid,get_observer_hash(),'view_pages'))
|
||||
return array();
|
||||
|
||||
|
||||
$item_normal = item_normal();
|
||||
$sql_options = item_permissions_sql($uid);
|
||||
$count = intval($count);
|
||||
|
||||
if($flags) {
|
||||
if($flags === 'wall')
|
||||
$sql_options .= " and item_wall = 1 ";
|
||||
}
|
||||
|
||||
if($authors) {
|
||||
if(! is_array($authors))
|
||||
$authors = array($authors);
|
||||
|
||||
stringify_array_elms($authors,true);
|
||||
$sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
|
||||
}
|
||||
|
||||
if($owner) {
|
||||
$sql_options .= " and owner_xchan = '" . dbesc($owner) . "' ";
|
||||
}
|
||||
|
||||
|
||||
// Fetch tags
|
||||
$r = q("select term, count(term) as total from term left join item on term.oid = item.id
|
||||
where term.uid = %d and term.ttype = %d
|
||||
and otype = %d and item_type = %d and item_private = 0
|
||||
$sql_options $item_normal
|
||||
group by term order by total desc %s",
|
||||
intval($uid),
|
||||
intval($type),
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($restrict),
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return array();
|
||||
|
||||
return Zotlabs\Text\Tagadelic::calc($r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function dir_tagadelic($count = 0) {
|
||||
|
||||
$count = intval($count);
|
||||
|
@ -316,6 +372,26 @@ function catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restric
|
|||
return $o;
|
||||
}
|
||||
|
||||
function card_catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_CATEGORY) {
|
||||
$o = '';
|
||||
|
||||
$r = card_tagadelic($uid,$count,$authors,$owner,$flags,$restrict,$type);
|
||||
|
||||
if($r) {
|
||||
$c = q("select channel_address from channel where channel_id = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
$o = '<div class="tagblock widget"><h3>' . t('Categories') . '</h3><div class="tags" align="center">';
|
||||
foreach($r as $rr) {
|
||||
$o .= '<a href="cards/' . $c[0]['channel_address']. '?f=&cat=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ' . "\r\n";
|
||||
}
|
||||
$o .= '</div></div>';
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
function dir_tagblock($link,$r) {
|
||||
$o = '';
|
||||
|
|
|
@ -2965,8 +2965,6 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||
|
||||
logger('build_sync_packet');
|
||||
|
||||
if($packet)
|
||||
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
$keychange = (($packet && array_key_exists('keychange',$packet)) ? true : false);
|
||||
if($keychange) {
|
||||
|
@ -3033,6 +3031,9 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||
$env_recips = array();
|
||||
$env_recips[] = array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig']);
|
||||
|
||||
if($packet)
|
||||
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
$info = (($packet) ? $packet : array());
|
||||
$info['type'] = 'channel_sync';
|
||||
$info['encoding'] = 'red'; // note: not zot, this packet is very platform specific
|
||||
|
|
109
util/dcp
109
util/dcp
|
@ -15,15 +15,15 @@ cli_startup();
|
|||
|
||||
|
||||
if($argc <= 3) {
|
||||
echo "Usage: " . $argv[0] . ' source destination' . "\n";
|
||||
echo "Usage: " . $argv[0] . ' src dstdir' . "\n";
|
||||
echo 'Always run from the toplevel web directory.' . "\n";
|
||||
echo 'destination should begin with store/$nickname/desired/path or $nickname/desired/path' . "\n";
|
||||
echo 'Example: util/dcp /etc/motd store/joe/etc/motd' . "\n";
|
||||
echo 'Example: util/dcp /etc/motd store/joe/etc' . "\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$dstfile = $argv[$argc - 1];
|
||||
|
||||
$recursive = false;
|
||||
$dstfile = $argv[$argc - 1];
|
||||
|
||||
if(strpos($dstfile,'store/') === 0)
|
||||
$dstfile = substr($dstfile,6);
|
||||
|
@ -36,8 +36,20 @@ if($argc <= 3) {
|
|||
if(! $channel)
|
||||
return;
|
||||
|
||||
for($x = 1; $x < ($argc - 1); $x ++) {
|
||||
if(($argv[$x] === '-r') || ($argv[$x] === '-R')) {
|
||||
$recursive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$isadir = false;
|
||||
|
||||
if(($recursive) || ($argc > 3))
|
||||
$isadir = true;
|
||||
|
||||
|
||||
$r = q("select * from attach where display_path = '%s' and uid = %d limit 1",
|
||||
dbesc($dstfile),
|
||||
intval($channel['channel_id'])
|
||||
|
@ -45,11 +57,13 @@ if($argc <= 3) {
|
|||
|
||||
if($r && $r[0]['is_dir']) {
|
||||
$isadir = true;
|
||||
$basepath = $dstfile;
|
||||
$folder = $r[0]['hash'];
|
||||
}
|
||||
else {
|
||||
$pathname = (($isadir) ? $dstfile : dirname($dstfile));
|
||||
$arr = [
|
||||
'pathname' => dirname($dstfile),
|
||||
'pathname' => $pathname,
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
|
@ -57,36 +71,73 @@ if($argc <= 3) {
|
|||
];
|
||||
|
||||
$folder = '';
|
||||
if(dirname($dstfile)) {
|
||||
if($pathname && $isadir) {
|
||||
$x = attach_mkdirp($channel,$channel['channel_hash'],$arr);
|
||||
if($x['success'])
|
||||
$folder = $x['data']['hash'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for($x = 1; $x < ($argc - 1); $x ++) {
|
||||
$srcfile = $argv[$x];
|
||||
if(($argv[$x] === '-r') || ($argv[$x] === '-R')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$arr = [
|
||||
'src' => $srcfile,
|
||||
'filename' => basename($srcfile),
|
||||
'hash' => $hash,
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid'],
|
||||
'preserve_original' => true,
|
||||
];
|
||||
|
||||
if($folder)
|
||||
$arr['folder'] = $folder;
|
||||
|
||||
attach_store($channel,$channel['channel_hash'],'import',$arr);
|
||||
|
||||
$sync = attach_export_data($channel,$hash);
|
||||
if($sync)
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
if(is_dir($argv[$x])) {
|
||||
if($recursive) {
|
||||
dcp_recurse($channel,$argv[$x],$basepath,$folder);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$dstname = (($isadir) ? '' : basename($dstfile));
|
||||
$cmd = [ 'Importfile', $channel['channel_id'], $argv[$x], $folder, $dstname ];
|
||||
\Zotlabs\Daemon\Master::Summon($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function dcp_recurse($channel,$src,$basepath,$folder) {
|
||||
$dir = opendir($src);
|
||||
if($dir) {
|
||||
while(($entry = readdir($dir)) !== false) {
|
||||
if($entry === '.' || $entry === '..')
|
||||
continue;
|
||||
|
||||
$dstfile = $basepath . '/' . $entry;
|
||||
if(is_dir($src . '/' . $entry)) {
|
||||
$r = q("select * from attach where display_path = '%s' and uid = %d limit 1",
|
||||
dbesc($dstfile),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if($r && $r[0]['is_dir']) {
|
||||
$folder = $r[0]['hash'];
|
||||
}
|
||||
else {
|
||||
|
||||
$arr = [
|
||||
'pathname' => $dstfile,
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid'],
|
||||
];
|
||||
|
||||
$folder = '';
|
||||
$x = attach_mkdirp($channel,$channel['channel_hash'],$arr);
|
||||
if($x['success'])
|
||||
$folder = $x['data']['hash'];
|
||||
}
|
||||
dcp_recurse($channel,$src . '/' . $entry,$dstfile,$folder);
|
||||
}
|
||||
else {
|
||||
$cmd = [ 'Importfile', $channel['channel_id'], $src . '/' . $entry, $folder ];
|
||||
\Zotlabs\Daemon\Master::Summon($cmd);
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -380,8 +380,9 @@ function NavUpdate() {
|
|||
if($('#live-pubstream').length) { src = 'pubstream'; liveUpdate(); }
|
||||
if($('#live-display').length) { src = 'display'; liveUpdate(); }
|
||||
if($('#live-search').length) { src = 'search'; liveUpdate(); }
|
||||
// if($('#live-cards').length) { src = 'cards'; liveUpdate(); }
|
||||
|
||||
if($('#live-photos').length) {
|
||||
if($('#live-photos').length || $('#live-cards').length) {
|
||||
if(liking) {
|
||||
liking = 0;
|
||||
window.location.href=window.location.href;
|
||||
|
|
3
view/js/mod_cards.js
Normal file
3
view/js/mod_cards.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
$(document).ready( function() {
|
||||
$(".autotime").timeago();
|
||||
});
|
5
view/pdl/mod_cards.pdl
Normal file
5
view/pdl/mod_cards.pdl
Normal file
|
@ -0,0 +1,5 @@
|
|||
[region=aside]
|
||||
[widget=categories][var=cards]1[/var][/widget]
|
||||
[widget=tasklist][/widget]
|
||||
[widget=notes][/widget]
|
||||
[/region]
|
9
view/tpl/cards.tpl
Normal file
9
view/tpl/cards.tpl
Normal file
|
@ -0,0 +1,9 @@
|
|||
<div class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<h2>{{$title}}</h2>
|
||||
</div>
|
||||
<div id="live-cards"></div>
|
||||
{{$editor}}
|
||||
{{$content}}
|
||||
</div>
|
||||
{{$pager}}
|
Loading…
Reference in a new issue