aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Cron.php3
-rw-r--r--Zotlabs/Lib/Config.php2
-rw-r--r--Zotlabs/Lib/DB_Upgrade.php119
-rw-r--r--Zotlabs/Lib/Enotify.php4
-rw-r--r--Zotlabs/Lib/MarkdownSoap.php96
-rw-r--r--Zotlabs/Lib/NativeWikiPage.php60
-rw-r--r--Zotlabs/Lib/PConfig.php2
-rw-r--r--Zotlabs/Lib/System.php13
-rw-r--r--Zotlabs/Lib/ThreadItem.php1
-rw-r--r--Zotlabs/Module/Admin/Site.php15
-rw-r--r--Zotlabs/Module/Cloud.php2
-rw-r--r--Zotlabs/Module/Connections.php4
-rw-r--r--Zotlabs/Module/Connedit.php3
-rw-r--r--Zotlabs/Module/Cover_photo.php64
-rw-r--r--Zotlabs/Module/Directory.php1
-rw-r--r--Zotlabs/Module/Editblock.php7
-rw-r--r--Zotlabs/Module/Editlayout.php1
-rw-r--r--Zotlabs/Module/Editwebpage.php6
-rw-r--r--Zotlabs/Module/Filestorage.php2
-rw-r--r--Zotlabs/Module/Hcard.php10
-rw-r--r--Zotlabs/Module/Impel.php14
-rw-r--r--Zotlabs/Module/Item.php30
-rw-r--r--Zotlabs/Module/Layouts.php1
-rw-r--r--Zotlabs/Module/Photos.php239
-rw-r--r--Zotlabs/Module/Profile_photo.php12
-rw-r--r--Zotlabs/Module/Setup.php7
-rw-r--r--Zotlabs/Module/Suggest.php4
-rw-r--r--Zotlabs/Module/Wiki.php25
-rw-r--r--Zotlabs/Render/Comanche.php17
-rw-r--r--Zotlabs/Storage/Directory.php62
-rw-r--r--Zotlabs/Storage/File.php12
-rw-r--r--Zotlabs/Web/WebServer.php17
-rw-r--r--Zotlabs/Widget/Activity.php61
-rw-r--r--Zotlabs/Widget/Admin.php68
-rw-r--r--Zotlabs/Widget/Affinity.php60
-rw-r--r--Zotlabs/Widget/Album.php106
-rw-r--r--Zotlabs/Widget/Appcategories.php49
-rw-r--r--Zotlabs/Widget/Appcloud.php13
-rw-r--r--Zotlabs/Widget/Archive.php55
-rw-r--r--Zotlabs/Widget/Bookmarkedchats.php28
-rw-r--r--Zotlabs/Widget/Catcloud_wall.php19
-rw-r--r--Zotlabs/Widget/Categories.php23
-rw-r--r--Zotlabs/Widget/Chatroom_list.php24
-rw-r--r--Zotlabs/Widget/Chatroom_members.php15
-rw-r--r--Zotlabs/Widget/Clock.php63
-rw-r--r--Zotlabs/Widget/Collections.php51
-rw-r--r--Zotlabs/Widget/Conversations.php74
-rw-r--r--Zotlabs/Widget/Cover_photo.php59
-rw-r--r--Zotlabs/Widget/Design_tools.php21
-rw-r--r--Zotlabs/Widget/Dirsort.php11
-rw-r--r--Zotlabs/Widget/Dirtags.php13
-rw-r--r--Zotlabs/Widget/Eventstools.php19
-rw-r--r--Zotlabs/Widget/Filer.php36
-rw-r--r--Zotlabs/Widget/Findpeople.php12
-rw-r--r--Zotlabs/Widget/Follow.php37
-rw-r--r--Zotlabs/Widget/Forums.php97
-rw-r--r--Zotlabs/Widget/Fullprofile.php16
-rw-r--r--Zotlabs/Widget/Helpindex.php45
-rw-r--r--Zotlabs/Widget/Item.php54
-rw-r--r--Zotlabs/Widget/Mailmenu.php36
-rw-r--r--Zotlabs/Widget/Menu_preview.php16
-rw-r--r--Zotlabs/Widget/Notes.php23
-rw-r--r--Zotlabs/Widget/Photo.php55
-rw-r--r--Zotlabs/Widget/Photo_albums.php25
-rw-r--r--Zotlabs/Widget/Photo_rand.php66
-rw-r--r--Zotlabs/Widget/Profile.php13
-rw-r--r--Zotlabs/Widget/Pubsites.php16
-rw-r--r--Zotlabs/Widget/Random_block.php46
-rw-r--r--Zotlabs/Widget/Rating.php67
-rw-r--r--Zotlabs/Widget/Savedsearch.php91
-rw-r--r--Zotlabs/Widget/Settings_menu.php137
-rw-r--r--Zotlabs/Widget/Shortprofile.php18
-rw-r--r--Zotlabs/Widget/Sitesearch.php38
-rw-r--r--Zotlabs/Widget/Suggestedchats.php37
-rw-r--r--Zotlabs/Widget/Suggestions.php58
-rw-r--r--Zotlabs/Widget/Tagcloud.php33
-rw-r--r--Zotlabs/Widget/Tagcloud_wall.php20
-rw-r--r--Zotlabs/Widget/Tasklist.php30
-rw-r--r--Zotlabs/Widget/Vcard.php12
-rw-r--r--Zotlabs/Widget/Website_portation_tools.php22
-rw-r--r--Zotlabs/Widget/Wiki_list.php23
-rw-r--r--Zotlabs/Widget/Wiki_page_history.php27
-rw-r--r--Zotlabs/Widget/Wiki_pages.php66
-rw-r--r--Zotlabs/Widget/Zcard.php11
84 files changed, 2637 insertions, 333 deletions
diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php
index 350dda7a0..c84708ba4 100644
--- a/Zotlabs/Daemon/Cron.php
+++ b/Zotlabs/Daemon/Cron.php
@@ -121,6 +121,9 @@ class Cron {
}
}
+ require_once('include/attach.php');
+ attach_upgrade();
+
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
diff --git a/Zotlabs/Lib/Config.php b/Zotlabs/Lib/Config.php
index 5625a3f79..6e042feba 100644
--- a/Zotlabs/Lib/Config.php
+++ b/Zotlabs/Lib/Config.php
@@ -53,7 +53,7 @@ class Config {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
- if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
+ if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) {
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),
diff --git a/Zotlabs/Lib/DB_Upgrade.php b/Zotlabs/Lib/DB_Upgrade.php
new file mode 100644
index 000000000..55c69bcca
--- /dev/null
+++ b/Zotlabs/Lib/DB_Upgrade.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+
+class DB_Upgrade {
+
+ public $config_name = '';
+ public $func_prefix = '';
+
+ function __construct($db_revision) {
+
+ $update_file = 'install/' . PLATFORM_NAME . '/update.php';
+ if(! file_exists($update_file)) {
+ $update_file = 'install/update.php';
+ $this->config_name = 'db_version';
+ $this->func_prefix = 'update_r';
+ }
+ else {
+ $this->config_name = PLATFORM_NAME . '_db_version';
+ $this->func_prefix = PLATFORM_NAME . '_update_';
+ }
+
+ $build = get_config('system', $this->config_name, 0);
+ if(! intval($build))
+ $build = set_config('system', $this->config_name, $db_revision);
+
+ if($build == $db_revision) {
+ // Nothing to be done.
+ return;
+ }
+ else {
+ $stored = intval($build);
+ if(! $stored) {
+ logger('Critical: check_config unable to determine database schema version');
+ return;
+ }
+
+ $current = intval($db_revision);
+
+ if(($stored < $current) && file_exists($update_file)) {
+
+ Config::Load('database');
+
+ // We're reporting a different version than what is currently installed.
+ // Run any existing update scripts to bring the database up to current.
+
+ require_once($update_file);
+
+ // make sure that boot.php and update.php are the same release, we might be
+ // updating from git right this very second and the correct version of the update.php
+ // file may not be here yet. This can happen on a very busy site.
+
+ if($db_revision == UPDATE_VERSION) {
+ for($x = $stored; $x < $current; $x ++) {
+ $func = $this->func_prefix . $x;
+ if(function_exists($func)) {
+ // There could be a lot of processes running or about to run.
+ // We want exactly one process to run the update command.
+ // So store the fact that we're taking responsibility
+ // after first checking to see if somebody else already has.
+
+ // If the update fails or times-out completely you may need to
+ // delete the config entry to try again.
+
+ if(get_config('database', $func))
+ break;
+ set_config('database',$func, '1');
+ // call the specific update
+
+ $retval = $func();
+ if($retval) {
+
+ // Prevent sending hundreds of thousands of emails by creating
+ // a lockfile.
+
+ $lockfile = 'store/[data]/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)
+ ]
+ )
+ ]
+ );
+
+ //try the logger
+ logger('CRITICAL: Update Failed: ' . $x);
+ pop_lang();
+ }
+ else {
+ set_config('database',$func, 'success');
+ }
+ }
+ }
+ set_config('system', $this->config_name, $db_revision);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 257687567..5db5fb42d 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -67,7 +67,7 @@ class Enotify {
$sender_name = $product;
$hostname = \App::get_hostname();
if(strpos($hostname,':'))
- $hostname = substr($hostname,0,strpos($hostname,':'));
+ $hostname = substr($hostname,0,strpos($hostname,':'));
// Do not translate 'noreply' as it must be a legal 7-bit email address
@@ -77,7 +77,7 @@ class Enotify {
$sender_email = get_config('system','from_email');
if(! $sender_email)
- $sender_email = 'Administrator' . '@' . \App::get_hostname();
+ $sender_email = 'Administrator' . '@' . $hostname;
$sender_name = get_config('system','from_email_name');
if(! $sender_name)
diff --git a/Zotlabs/Lib/MarkdownSoap.php b/Zotlabs/Lib/MarkdownSoap.php
new file mode 100644
index 000000000..a0214bbe4
--- /dev/null
+++ b/Zotlabs/Lib/MarkdownSoap.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+/**
+ * MarkdownSoap
+ * Purify Markdown for storage
+ * $x = new MarkdownSoap($string_to_be_cleansed);
+ * $text = $x->clean();
+ *
+ * What this does:
+ * 1. extracts code blocks and privately escapes them from processing
+ * 2. Run html purifier on the content
+ * 3. put back the code blocks
+ * 4. run htmlspecialchars on the entire content for safe storage
+ *
+ * At render time:
+ * $markdown = \Zotlabs\Lib\MarkdownSoap::unescape($text);
+ * $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
+ */
+
+
+
+class MarkdownSoap {
+
+ private $token;
+
+ private $str;
+
+ function __construct($s) {
+ $this->str = $s;
+ $this->token = random_string(20);
+ }
+
+
+ function clean() {
+
+ $x = $this->extract_code($this->str);
+
+ $x = $this->purify($x);
+
+ $x = $this->putback_code($x);
+
+ $x = $this->escape($x);
+
+ return $x;
+ }
+
+ function extract_code($s) {
+
+ $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
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ [ $this , 'encode_code' ], $s);
+
+ return $text;
+ }
+
+ function encode_code($matches) {
+ return $this->token . ';' . base64_encode($matches[0]) . ';' ;
+ }
+
+ function decode_code($matches) {
+ return base64_decode($matches[1]);
+ }
+
+ function putback_code($s) {
+ $text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm',[ $this, 'decode_code' ], $s);
+ return $text;
+ }
+
+ function purify($s) {
+// $s = str_replace("\n",'<br>',$s);
+// $s = str_replace("\t",'&nbsp;&nbsp;&nbsp;&nbsp;',$s);
+// $s = str_replace(' ','&nbsp;',$s);
+ $s = purify_html($s);
+// $s = str_replace(['&nbsp;', mb_convert_encoding('&#x00a0;','UTF-8','HTML-ENTITIES')], [ ' ', ' ' ],$s);
+// $s = str_replace(['<br>','<br />', '&lt;', '&gt;' ],["\n","\n", '<', '>'],$s);
+ return $s;
+ }
+
+ function escape($s) {
+ return htmlspecialchars($s,ENT_QUOTES);
+ }
+
+ static public function unescape($s) {
+ return htmlspecialchars_decode($s,ENT_QUOTES);
+ }
+}
diff --git a/Zotlabs/Lib/NativeWikiPage.php b/Zotlabs/Lib/NativeWikiPage.php
index 941ade90c..960fe014e 100644
--- a/Zotlabs/Lib/NativeWikiPage.php
+++ b/Zotlabs/Lib/NativeWikiPage.php
@@ -156,7 +156,7 @@ class NativeWikiPage {
$content = $item['body'];
return [
- 'content' => json_encode($content),
+ 'content' => $content,
'mimeType' => $w['mimeType'],
'message' => '',
'success' => true
@@ -307,34 +307,6 @@ class NativeWikiPage {
return null;
}
-
-
- static public function prepare_content($s) {
-
- $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
- .*\n+
- )+
- )
- ((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
- }xm',
- 'self::nwiki_prepare_content_callback', $s);
-
- return $text;
- }
-
- static public function nwiki_prepare_content_callback($matches) {
- $codeblock = $matches[1];
-
- $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES, UTF8, false);
- return "\n\n" . $codeblock ;
- }
-
-
-
static public function save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
@@ -351,12 +323,6 @@ class NativeWikiPage {
}
$mimetype = $w['mimeType'];
- if($mimetype === 'text/markdown') {
- $content = purify_html(Zlib\NativeWikiPage::prepare_content($content));
- }
- else {
- $content = escape_tags($content);
- }
// fetch the most recently saved revision.
@@ -375,6 +341,7 @@ class NativeWikiPage {
$item['author_xchan'] = $observer_hash;
$item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
$item['edited'] = datetime_convert();
+ $item['mimetype'] = $mimetype;
if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
@@ -542,6 +509,29 @@ class NativeWikiPage {
}
return $s;
}
+
+ static public function render_page_history($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
+
+ $pageHistory = self::page_history([
+ 'channel_id' => \App::$profile_uid,
+ 'observer_hash' => get_observer_hash(),
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName
+ ]);
+
+ return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
+ '$pageHistory' => $pageHistory['history'],
+ '$permsWrite' => $arr['permsWrite'],
+ '$name_lbl' => t('Name'),
+ '$msg_label' => t('Message','wiki_history')
+ ));
+
+ }
+
+
/**
* Replace the instances of the string [toc] with a list element that will be populated by
diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php
index d70697fbc..25478e764 100644
--- a/Zotlabs/Lib/PConfig.php
+++ b/Zotlabs/Lib/PConfig.php
@@ -119,7 +119,7 @@ class PConfig {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
- if(get_pconfig($uid, $family, $key) === false) {
+ if(self::Get($uid, $family, $key) === false) {
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
if(! array_key_exists($family, \App::$config[$uid]))
diff --git a/Zotlabs/Lib/System.php b/Zotlabs/Lib/System.php
index 306c90f4a..3d5b18506 100644
--- a/Zotlabs/Lib/System.php
+++ b/Zotlabs/Lib/System.php
@@ -54,12 +54,8 @@ class System {
return 'https://github.com/redmatrix/hubzilla';
}
-
-
static public function get_server_role() {
- if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
- return \App::$config['system']['server_role'];
- return 'standard';
+ return 'pro';
}
static public function get_std_version() {
@@ -72,11 +68,8 @@ class System {
if(get_directory_realm() != DIRECTORY_REALM)
return true;
-
- foreach(['hubzilla','zap'] as $t) {
- if(stristr($p,$t))
- return true;
- }
+ if(in_array(strtolower($p),['hubzilla','zap','red']))
+ return true;
return false;
}
}
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index c3464b86b..5910ea672 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -338,7 +338,6 @@ class ThreadItem {
'profile_url' => $profile_link,
'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
- 'item_photo_menu' => item_photo_menu($item),
'dreport' => $dreport,
'name' => $profile_name,
'thumb' => $profile_avatar,
diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php
index b71e63030..d05e70aa9 100644
--- a/Zotlabs/Module/Admin/Site.php
+++ b/Zotlabs/Module/Admin/Site.php
@@ -48,6 +48,10 @@ class Site {
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
$default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0);
+ $reply_address = ((array_key_exists('reply_address',$_POST) && trim($_POST['reply_address'])) ? trim($_POST['reply_address']) : 'noreply@' . \App::get_hostname());
+ $from_email = ((array_key_exists('from_email',$_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . \App::get_hostname());
+ $from_email_name = ((array_key_exists('from_email_name',$_POST) && trim($_POST['from_email_name'])) ? trim($_POST['from_email_name']) : \Zotlabs\Lib\System::get_site_name());
+
$verifyssl = ((x($_POST,'verifyssl')) ? True : False);
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
$proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
@@ -77,8 +81,15 @@ class Site {
set_config('system', 'enable_context_help', $enable_context_help);
set_config('system', 'verify_email', $verify_email);
set_config('system', 'default_expire_days', $default_expire_days);
+ set_config('system', 'reply_address', $reply_address);
+ set_config('system', 'from_email', $from_email);
+ set_config('system', 'from_email_name' , $from_email_name);
+
+
set_config('system', 'techlevel_lock', $techlevel_lock);
+
+
if(! is_null($techlevel))
set_config('system', 'techlevel', $techlevel);
@@ -304,6 +315,10 @@ class Site {
'$login_on_homepage' => array('login_on_homepage', t("Login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")),
'$enable_context_help' => array('enable_context_help', t("Enable context help"),((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0) , t("Display contextual help for the current page when the help button is pressed.")),
+ '$reply_address' => [ 'reply_address', t('Reply-to email address for system generated email.'), get_config('system','reply_address','noreply@' . \App::get_hostname()),'' ],
+ '$from_email' => [ 'from_email', t('Sender (From) email address for system generated email.'), get_config('system','from_email','Administrator@' . \App::get_hostname()),'' ],
+ '$from_email_name' => [ 'from_email_name', t('Name of email sender for system generated email.'), get_config('system','from_email_name',\Zotlabs\Lib\System::get_site_name()),'' ],
+
'$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null),
'$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php
index 2b6d7bcbe..7370eeda3 100644
--- a/Zotlabs/Module/Cloud.php
+++ b/Zotlabs/Module/Cloud.php
@@ -60,11 +60,9 @@ class Cloud extends \Zotlabs\Web\Controller {
$_SERVER['QUERY_STRING'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['QUERY_STRING']);
$_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']);
- $_SERVER['QUERY_STRING'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['QUERY_STRING']);
$_SERVER['REQUEST_URI'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['REQUEST_URI']);
$_SERVER['REQUEST_URI'] = strip_zids($_SERVER['REQUEST_URI']);
- $_SERVER['REQUEST_URI'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['REQUEST_URI']);
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php
index e8a92e8b7..b079ae860 100644
--- a/Zotlabs/Module/Connections.php
+++ b/Zotlabs/Module/Connections.php
@@ -5,10 +5,6 @@ namespace Zotlabs\Module;
require_once('include/socgraph.php');
require_once('include/selectors.php');
require_once('include/group.php');
-require_once('include/contact_widgets.php');
-require_once('include/zot.php');
-require_once('include/widgets.php');
-
class Connections extends \Zotlabs\Web\Controller {
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index 5b7c23028..72bd3e86e 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -11,9 +11,6 @@ namespace Zotlabs\Module;
require_once('include/socgraph.php');
require_once('include/selectors.php');
require_once('include/group.php');
-require_once('include/contact_widgets.php');
-require_once('include/zot.php');
-require_once('include/widgets.php');
require_once('include/photos.php');
diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php
index 72ec1020d..47bce6c2b 100644
--- a/Zotlabs/Module/Cover_photo.php
+++ b/Zotlabs/Module/Cover_photo.php
@@ -23,19 +23,17 @@ require_once('include/channel.php');
class Cover_photo extends \Zotlabs\Web\Controller {
function init() {
-
if(! local_channel()) {
return;
}
$channel = \App::get_channel();
- profile_load($channel['channel_address']);
-
+ profile_load($channel['channel_address']);
}
- /* @brief Evaluate posted values
+ /**
+ * @brief Evaluate posted values
*
- * @param $a Current application
* @return void
*
*/
@@ -130,8 +128,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$aid = get_account_id();
- $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
- 'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
+ $p = [
+ 'aid' => $aid,
+ 'uid' => local_channel(),
+ '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']
+ ];
$p['imgscale'] = 7;
$p['photo_usage'] = PHOTO_COVER;
@@ -195,11 +200,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$os_storage = false;
foreach($i as $ii) {
- $smallest = intval($ii['imgscale']);
+ $smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
- $imagedata = $ii['content'];
- $filetype = $ii['mimetype'];
-
+ $imagedata = $ii['content'];
+ $filetype = $ii['mimetype'];
}
}
@@ -263,10 +267,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
- /* @brief Generate content of profile-photo view
+ /**
+ * @brief Generate content of profile-photo view
*
- * @param $a Current application
- * @return void
+ * @return string
*
*/
@@ -350,15 +354,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$tpl = get_markup_template('cover_photo.tpl');
$o .= replace_macros($tpl,array(
- '$user' => \App::$channel['channel_address'],
- '$lbl_upfile' => t('Upload File:'),
- '$lbl_profiles' => t('Select a profile:'),
- '$title' => t('Upload Cover Photo'),
- '$submit' => t('Upload'),
- '$profiles' => $profiles,
+ '$user' => \App::$channel['channel_address'],
+ '$lbl_upfile' => t('Upload File:'),
+ '$lbl_profiles' => t('Select a profile:'),
+ '$title' => t('Upload Cover Photo'),
+ '$submit' => t('Upload'),
+ '$profiles' => $profiles,
'$form_security_token' => get_form_security_token("cover_photo"),
- // FIXME - yuk
- '$select' => sprintf('%s %s', t('or'), ($newuser) ? '<a href="' . z_root() . '">' . t('skip this step') . '</a>' : '<a href="'. z_root() . '/photos/' . \App::$channel['channel_address'] . '">' . t('select a photo from your photo albums') . '</a>')
+ /// @FIXME - yuk
+ '$select' => sprintf('%s %s', t('or'), ($newuser) ? '<a href="' . z_root() . '">' . t('skip this step') . '</a>' : '<a href="'. z_root() . '/photos/' . \App::$channel['channel_address'] . '">' . t('select a photo from your photo albums') . '</a>')
));
call_hooks('cover_photo_content_end', $o);
@@ -370,14 +374,14 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$resolution = 3;
$tpl = get_markup_template("cropcover.tpl");
$o .= replace_macros($tpl,array(
- '$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.'),
+ '$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')
+ '$done' => t('Done Editing')
));
return $o;
}
@@ -393,8 +397,6 @@ class Cover_photo extends \Zotlabs\Web\Controller {
*
*/
-
-
function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
$max_length = get_config('system','max_image_length');
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index 59ae88857..edcf43cd6 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
require_once('include/socgraph.php');
require_once('include/dir_fns.php');
-require_once('include/widgets.php');
require_once('include/bbcode.php');
diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php
index 654e2251d..8a7e87a09 100644
--- a/Zotlabs/Module/Editblock.php
+++ b/Zotlabs/Module/Editblock.php
@@ -98,6 +98,11 @@ class Editblock extends \Zotlabs\Web\Controller {
$mimetype = $itm[0]['mimetype'];
+ $content = $itm[0]['body'];
+ if($itm[0]['mimetype'] === 'text/markdown')
+ $content = \Zotlabs\Lib\MarkdownSoap::unescape($itm[0]['body']);
+
+
$rp = 'blocks/' . $channel['channel_address'];
$x = array(
@@ -117,7 +122,7 @@ class Editblock extends \Zotlabs\Web\Controller {
'ptyp' => $itm[0]['type'],
'mimeselect' => true,
'mimetype' => $itm[0]['mimetype'],
- 'body' => undo_post_tagging($itm[0]['body']),
+ 'body' => undo_post_tagging($content),
'post_id' => $post_id,
'visitor' => true,
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php
index ea637fcba..3d6a79507 100644
--- a/Zotlabs/Module/Editlayout.php
+++ b/Zotlabs/Module/Editlayout.php
@@ -119,6 +119,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
'hide_weblink' => true,
'hide_attach' => true,
'hide_preview' => true,
+ 'disable_comments' => true,
'ptyp' => $itm[0]['obj_type'],
'body' => undo_post_tagging($itm[0]['body']),
'post_id' => $post_id,
diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php
index 97f4a32ff..03b2aeab9 100644
--- a/Zotlabs/Module/Editwebpage.php
+++ b/Zotlabs/Module/Editwebpage.php
@@ -129,6 +129,10 @@ class Editwebpage extends \Zotlabs\Web\Controller {
}
$layout = $itm[0]['layout_mid'];
+
+ $content = $itm[0]['body'];
+ if($itm[0]['mimetype'] === 'text/markdown')
+ $content = \Zotlabs\Lib\MarkdownSoap::unescape($itm[0]['body']);
$rp = 'webpages/' . $which;
@@ -145,7 +149,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
'hide_location' => true,
'hide_voting' => true,
'ptyp' => $itm[0]['type'],
- 'body' => undo_post_tagging($itm[0]['body']),
+ 'body' => undo_post_tagging($content),
'post_id' => $post_id,
'visitor' => ($is_owner) ? true : false,
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php
index 874445145..785dff394 100644
--- a/Zotlabs/Module/Filestorage.php
+++ b/Zotlabs/Module/Filestorage.php
@@ -130,7 +130,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
$f = $r[0];
$channel = \App::get_channel();
- $cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : '');
+ $cloudpath = get_cloudpath($f);
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
$aclselect_e = populate_acl($f, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage'));
diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php
index ec9181f6a..13097939e 100644
--- a/Zotlabs/Module/Hcard.php
+++ b/Zotlabs/Module/Hcard.php
@@ -59,12 +59,10 @@ class Hcard extends \Zotlabs\Web\Controller {
}
- function get() {
-
- require_once('include/widgets.php');
- return widget_profile(array());
-
-
+ function get() {
+
+ $x = new \Zotlabs\Widget\Profile();
+ return $x->widget(array());
}
diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php
index 197d9f859..77f488d26 100644
--- a/Zotlabs/Module/Impel.php
+++ b/Zotlabs/Module/Impel.php
@@ -144,18 +144,8 @@ class Impel extends \Zotlabs\Web\Controller {
// Verify ability to use html or php!!!
- $execflag = false;
-
- if($arr['mimetype'] === 'application/x-php') {
- $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
- intval(local_channel())
- );
-
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- $execflag = true;
- }
- }
-
+ $execflag = ((intval($channel['channel_id']) == intval(local_channel()) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
+
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval(local_channel())
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 6f54d3bb1..71f410b2a 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -471,24 +471,16 @@ class Item extends \Zotlabs\Web\Controller {
if(! $mimetype)
$mimetype = 'text/bbcode';
+
+ $execflag = ((intval($uid) == intval($profile_uid)
+ && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
+
if($preview) {
- $body = z_input_filter($profile_uid,$body,$mimetype);
+ $body = z_input_filter($body,$mimetype,$execflag);
}
-
// Verify ability to use html or php!!!
- $execflag = false;
-
- $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
- intval($profile_uid)
- );
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- if($uid && (get_account_id() == $z[0]['account_id'])) {
- $execflag = true;
- }
- }
-
$gacl = $acl->get();
$str_contact_allow = $gacl['allow_cid'];
$str_group_allow = $gacl['allow_gid'];
@@ -852,18 +844,6 @@ class Item extends \Zotlabs\Web\Controller {
if(mb_strlen($datarray['title']) > 255)
$datarray['title'] = mb_substr($datarray['title'],0,255);
- if(array_key_exists('item_private',$datarray) && $datarray['item_private']) {
-
- $datarray['body'] = trim(z_input_filter($datarray['uid'],$datarray['body'],$datarray['mimetype']));
-
- if($uid) {
- if($channel['channel_hash'] === $datarray['author_xchan']) {
- $datarray['sig'] = base64url_encode(rsa_sign($datarray['body'],$channel['channel_prvkey']));
- $datarray['item_verified'] = 1;
- }
- }
- }
-
if($webpage) {
Zlib\IConfig::Set($datarray,'system', webpage_to_namespace($webpage),
(($pagetitle) ? $pagetitle : substr($datarray['mid'],0,16)),true);
diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php
index c07f65ce1..34d754029 100644
--- a/Zotlabs/Module/Layouts.php
+++ b/Zotlabs/Module/Layouts.php
@@ -125,6 +125,7 @@ class Layouts extends \Zotlabs\Web\Controller {
'hide_weblink' => true,
'hide_attach' => true,
'hide_preview' => true,
+ 'disable_comments' => true,
'ptlabel' => t('Layout Name'),
'profile_uid' => intval($owner),
'expanded' => true,
diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php
index 34fedb14e..d993c481e 100644
--- a/Zotlabs/Module/Photos.php
+++ b/Zotlabs/Module/Photos.php
@@ -15,13 +15,10 @@ class Photos extends \Zotlabs\Web\Controller {
function init() {
-
if(observer_prohibited()) {
return;
}
- $o = '';
-
if(argc() > 1) {
$nick = argv(1);
@@ -54,7 +51,6 @@ class Photos extends \Zotlabs\Web\Controller {
logger('mod-photos: photos_post: begin' , LOGGER_DEBUG);
-
logger('mod_photos: REQUEST ' . print_r($_REQUEST,true), LOGGER_DATA);
logger('mod_photos: FILES ' . print_r($_FILES,true), LOGGER_DATA);
@@ -92,14 +88,9 @@ class Photos extends \Zotlabs\Web\Controller {
if((argc() > 3) && (argv(2) === 'album')) {
- $album = hex2bin(argv(3));
-
- if($album === t('Profile Photos')) {
- // not allowed
- goaway(z_root() . '/' . $_SESSION['photo_return']);
- }
-
- if(! photos_album_exists($page_owner_uid,$album)) {
+ $album = argv(3);
+
+ if(! photos_album_exists($page_owner_uid, get_observer_hash(), $album)) {
notice( t('Album not found.') . EOL);
goaway(z_root() . '/' . $_SESSION['photo_return']);
}
@@ -121,7 +112,7 @@ class Photos extends \Zotlabs\Web\Controller {
$folder_hash = '';
- $r = q("select * from attach where is_dir = 1 and uid = %d and filename = '%s'",
+ $r = q("select * from attach where is_dir = 1 and uid = %d and hash = '%s'",
intval($page_owner_uid),
dbesc($album)
);
@@ -129,14 +120,7 @@ class Photos extends \Zotlabs\Web\Controller {
notice( t('Album not found.') . EOL);
return;
}
- if(count($r) > 1) {
- notice( t('Multiple storage folders exist with this album name, but within different directories. Please remove the desired folder or folders using the Files manager') . EOL);
- return;
- }
- else {
- $folder_hash = $r[0]['hash'];
- }
-
+ $folder_hash = $r[0]['hash'];
$res = array();
@@ -468,7 +452,7 @@ class Photos extends \Zotlabs\Web\Controller {
* default post action - upload a photo
*/
- $channel = \App::$data['channel'];
+ $channel = \App::$data['channel'];
$observer = \App::$data['observer'];
$_REQUEST['source'] = 'photos';
@@ -485,12 +469,10 @@ class Photos extends \Zotlabs\Web\Controller {
if(! $r['success']) {
notice($r['message'] . EOL);
+ goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
-
- if($_REQUEST['newalbum'])
- goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($_REQUEST['newalbum']));
- else
- goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex(datetime_convert('UTC',date_default_timezone_get(),'now', 'Y')));
+
+ goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $r['data']['folder']);
}
@@ -569,7 +551,9 @@ class Photos extends \Zotlabs\Web\Controller {
return;
}
- $sql_extra = permissions_sql($owner_uid);
+ $sql_item = item_permissions_sql($owner_uid,get_observer_hash());
+ $sql_extra = permissions_sql($owner_uid,get_observer_hash(),'photo');
+ $sql_attach = permissions_sql($owner_uid,get_observer_hash(),'attach');
$o = "";
@@ -628,8 +612,14 @@ class Photos extends \Zotlabs\Web\Controller {
if(! $aclselect) {
$aclselect = '<input id="group_allow" type="hidden" name="allow_gid[]" value="" /><input id="contact_allow" type="hidden" name="allow_cid[]" value="" /><input id="group_deny" type="hidden" name="deny_gid[]" value="" /><input id="contact_deny" type="hidden" name="deny_cid[]" value="" />';
}
-
- $selname = (($datum) ? hex2bin($datum) : '');
+
+ $selname = '';
+
+ if($datum) {
+ $h = attach_by_hash_nodata($datum,get_observer_hash());
+ $selname = $h['data']['display_path'];
+ }
+
$albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
@@ -680,29 +670,13 @@ class Photos extends \Zotlabs\Web\Controller {
if($datatype === 'album') {
- if(strlen($datum)) {
- if((strlen($datum) & 1) || (! ctype_xdigit($datum))) {
- notice( t('Album name could not be decoded') . EOL);
- logger('mod_photos: illegal album encoding: ' . $datum);
- $datum = '';
- goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
- }
- }
-
- $album = (($datum) ? hex2bin($datum) : '');
-
\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";
- //check if the album exists and if we have perms
- $r = q("SELECT album FROM photo WHERE uid = %d AND album = '%s' and is_nsfw = %d $sql_extra LIMIT 1",
- intval($owner_uid),
- dbesc($album),
- intval($unsafe)
- );
-
- if($r) {
+ if($x = photos_album_exists($owner_uid, get_observer_hash(), $datum)) {
\App::set_pager_itemspage(60);
- } else {
+ $album = $x['display_path'];
+ }
+ else {
goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
@@ -712,26 +686,26 @@ class Photos extends \Zotlabs\Web\Controller {
$order = 'DESC';
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
- (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id) ph
+ (SELECT resource_id, max(imgscale) imgscale FROM photo left join attach on folder = '%s' and photo.resource_id = attach.hash WHERE attach.uid = %d AND imgscale <= 4 AND photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id) ph
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
ORDER BY created $order LIMIT %d OFFSET %d",
+ dbesc($datum),
intval($owner_uid),
- dbesc($album),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe),
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
);
-
- //edit album name
+
+ // edit album name
$album_edit = null;
- if(($album !== t('Profile Photos')) && ($album !== 'Profile Photos') && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
- if($can_post) {
- $album_e = $album;
- $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
+
+ if($can_post) {
+ $album_e = $album;
+ $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
- // @fixme - syncronise actions with DAV
+ // @fixme - syncronise actions with DAV
// $edit_tpl = get_markup_template('album_edit.tpl');
// $album_edit = replace_macros($edit_tpl,array(
@@ -745,13 +719,12 @@ class Photos extends \Zotlabs\Web\Controller {
// '$dropsubmit' => t('Delete Album')
// ));
- }
}
if($_GET['order'] === 'posted')
- $order = array(t('Show Newest First'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($album));
+ $order = array(t('Show Newest First'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $datum);
else
- $order = array(t('Show Oldest First'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($album) . '?f=&order=posted');
+ $order = array(t('Show Oldest First'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $datum . '?f=&order=posted');
$photos = array();
if(count($r)) {
@@ -805,10 +778,10 @@ class Photos extends \Zotlabs\Web\Controller {
$o .= replace_macros($tpl, array(
'$photos' => $photos,
'$album' => $album,
- '$album_id' => bin2hex($album),
+ '$album_id' => $datum,
'$album_edit' => array(t('Edit Album'), $album_edit),
'$can_post' => $can_post,
- '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/upload/' . bin2hex($album)),
+ '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/upload/' . $datum),
'$order' => $order,
'$upload_form' => $upload_form,
'$usage' => $usage_message
@@ -822,8 +795,6 @@ class Photos extends \Zotlabs\Web\Controller {
killme();
}
- // $o .= paginate($a);
-
return $o;
}
@@ -836,6 +807,11 @@ class Photos extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
+ $x = q("select folder from attach where hash = '%s' and uid = %d $sql_attach limit 1",
+ dbesc($datum),
+ intval($owner_uid)
+ );
+
// fetch image, item containing image, then comments
$ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,description,album,filename,mimetype,height,width,filesize,imgscale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM photo WHERE uid = %d AND resource_id = '%s'
@@ -844,7 +820,7 @@ class Photos extends \Zotlabs\Web\Controller {
dbesc($datum)
);
- if(! $ph) {
+ if(! ($ph && $x)) {
/* Check again - this time without specifying permissions */
@@ -869,16 +845,16 @@ class Photos extends \Zotlabs\Web\Controller {
else
$order = 'DESC';
-
- $prvnxt = q("SELECT resource_id FROM photo WHERE album = '%s' AND uid = %d AND imgscale = 0
- $sql_extra ORDER BY created $order ",
- dbesc($ph[0]['album']),
+
+ $prvnxt = q("SELECT hash FROM attach WHERE folder = '%s' AND uid = %d AND is_photo = 1
+ $sql_attach ORDER BY created $order ",
+ dbesc($x[0]['folder']),
intval($owner_uid)
);
-
+
if(count($prvnxt)) {
for($z = 0; $z < count($prvnxt); $z++) {
- if($prvnxt[$z]['resource_id'] == $ph[0]['resource_id']) {
+ if($prvnxt[$z]['hash'] == $ph[0]['resource_id']) {
$prv = $z - 1;
$nxt = $z + 1;
if($prv < 0)
@@ -889,8 +865,8 @@ class Photos extends \Zotlabs\Web\Controller {
}
}
- $prevlink = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $prvnxt[$prv]['resource_id'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
- $nextlink = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $prvnxt[$nxt]['resource_id'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
+ $prevlink = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $prvnxt[$prv]['hash'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
+ $nextlink = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $prvnxt[$nxt]['hash'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
}
@@ -907,7 +883,7 @@ class Photos extends \Zotlabs\Web\Controller {
}
}
- $album_link = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($ph[0]['album']);
+ $album_link = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $x[0]['folder'];
$tools = Null;
$lock = Null;
@@ -947,7 +923,7 @@ class Photos extends \Zotlabs\Web\Controller {
// Do we have an item for this photo?
$linked_items = q("SELECT * FROM item WHERE resource_id = '%s' and resource_type = 'photo'
- $sql_extra LIMIT 1",
+ $sql_item LIMIT 1",
dbesc($datum)
);
@@ -962,7 +938,7 @@ class Photos extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
$r = q("select * from item where parent_mid = '%s'
- $item_normal and uid = %d $sql_extra ",
+ $item_normal and uid = %d $sql_item ",
dbesc($link_item['mid']),
intval($link_item['uid'])
@@ -1008,13 +984,6 @@ class Photos extends \Zotlabs\Web\Controller {
$edit = null;
if($can_post) {
- $m = q("select folder from attach where hash = '%s' and uid = %d limit 1",
- dbesc($ph[0]['resource_id']),
- intval($ph[0]['uid'])
- );
- if($m)
- $album_hash = $m[0]['folder'];
-
$album_e = $ph[0]['album'];
$caption_e = $ph[0]['description'];
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
@@ -1024,35 +993,35 @@ class Photos extends \Zotlabs\Web\Controller {
$folder_list = attach_folder_select_list($ph[0]['uid']);
- $edit = array(
+ $edit = [
'edit' => t('Edit photo'),
'id' => $link_item['id'],
- 'rotatecw' => t('Rotate CW (right)'),
- 'rotateccw' => t('Rotate CCW (left)'),
- 'albums' => $albums['albums'],
- 'album' => $album_e,
- 'album_select' => [ 'move_to_album', t('Move photo to album'), $album_hash, '', $folder_list ],
- 'newalbum_label' => t('Enter a new album name'),
+ 'rotatecw' => t('Rotate CW (right)'),
+ 'rotateccw' => t('Rotate CCW (left)'),
+ 'albums' => $albums['albums'],
+ 'album' => $album_e,
+ 'album_select' => [ 'move_to_album', t('Move photo to album'), $x[0]['folder'], '', $folder_list ],
+ 'newalbum_label' => t('Enter a new album name'),
'newalbum_placeholder' => t('or select an existing one (doubleclick)'),
- 'nickname' => \App::$data['channel']['channel_address'],
- 'resource_id' => $ph[0]['resource_id'],
- 'capt_label' => t('Caption'),
- 'caption' => $caption_e,
- 'tag_label' => t('Add a Tag'),
- 'permissions' => t('Permissions'),
- 'aclselect' => $aclselect_e,
- 'allow_cid' => acl2json($ph[0]['allow_cid']),
- 'allow_gid' => acl2json($ph[0]['allow_gid']),
- 'deny_cid' => acl2json($ph[0]['deny_cid']),
- 'deny_gid' => acl2json($ph[0]['deny_gid']),
- 'lockstate' => $lockstate[0],
- 'help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com'),
- 'item_id' => ((count($linked_items)) ? $link_item['id'] : 0),
- 'adult_enabled' => feature_enabled($owner_uid,'adult_photo_flagging'),
- 'adult' => array('adult',t('Flag as adult in album view'), intval($ph[0]['is_nsfw']),''),
- 'submit' => t('Submit'),
- 'delete' => t('Delete Photo')
- );
+ 'nickname' => \App::$data['channel']['channel_address'],
+ 'resource_id' => $ph[0]['resource_id'],
+ 'capt_label' => t('Caption'),
+ 'caption' => $caption_e,
+ 'tag_label' => t('Add a Tag'),
+ 'permissions' => t('Permissions'),
+ 'aclselect' => $aclselect_e,
+ 'allow_cid' => acl2json($ph[0]['allow_cid']),
+ 'allow_gid' => acl2json($ph[0]['allow_gid']),
+ 'deny_cid' => acl2json($ph[0]['deny_cid']),
+ 'deny_gid' => acl2json($ph[0]['deny_gid']),
+ 'lockstate' => $lockstate[0],
+ 'help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com'),
+ 'item_id' => ((count($linked_items)) ? $link_item['id'] : 0),
+ 'adult_enabled' => feature_enabled($owner_uid,'adult_photo_flagging'),
+ 'adult' => array('adult',t('Flag as adult in album view'), intval($ph[0]['is_nsfw']),''),
+ 'submit' => t('Submit'),
+ 'delete' => t('Delete Photo')
+ ];
}
if(count($linked_items)) {
@@ -1066,13 +1035,13 @@ class Photos extends \Zotlabs\Web\Controller {
$likebuttons = '';
if($can_post || $can_comment) {
- $likebuttons = array(
- 'id' => $link_item['id'],
+ $likebuttons = [
+ 'id' => $link_item['id'],
'likethis' => t("I like this \x28toggle\x29"),
- 'nolike' => t("I don't like this \x28toggle\x29"),
- 'share' => t('Share'),
- 'wait' => t('Please wait')
- );
+ 'nolike' => t("I don't like this \x28toggle\x29"),
+ 'share' => t('Share'),
+ 'wait' => t('Please wait')
+ ];
}
$comments = '';
@@ -1277,25 +1246,13 @@ class Photos extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
- /*
- $r = q("SELECT resource_id, max(imgscale) AS imgscale FROM photo WHERE uid = %d
- and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id",
- intval(\App::$data['channel']['channel_id']),
- intval(PHOTO_NORMAL),
- intval(PHOTO_PROFILE),
- intval($unsafe)
- );
- if($r) {
- \App::set_pager_total(count($r));
- \App::set_pager_itemspage(60);
- }
- */
\App::set_pager_itemspage(60);
- $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p
+ $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created, p.display_path
+ FROM photo p
INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo
- WHERE uid = %d AND photo_usage IN ( %d, %d )
+ WHERE photo.uid = %d AND photo_usage IN ( %d, %d )
AND is_nsfw = %d $sql_extra group by resource_id ) ph
ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale)
ORDER by p.created DESC LIMIT %d OFFSET %d",
@@ -1313,21 +1270,19 @@ class Photos extends \Zotlabs\Web\Controller {
if($r) {
$twist = 'rotright';
foreach($r as $rr) {
+
+ if(! attach_can_view_folder(\App::$data['channel']['channel_id'],get_observer_hash(),$rr['resource_id']))
+ continue;
+
if($twist == 'rotright')
$twist = 'rotleft';
else
$twist = 'rotright';
$ext = $phototypes[$rr['mimetype']];
- if(\App::get_template_engine() === 'internal') {
- $alt_e = template_escape($rr['filename']);
- $name_e = template_escape($rr['album']);
- }
- else {
- $alt_e = $rr['filename'];
- $name_e = $rr['album'];
- }
-
+ $alt_e = $rr['filename'];
+ $name_e = dirname($rr['display_path']);
+
$photos[] = array(
'id' => $rr['id'],
'twist' => ' ' . $twist . rand(2,4),
@@ -1336,9 +1291,7 @@ class Photos extends \Zotlabs\Web\Controller {
'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . ((($rr['imgscale']) == 6) ? 4 : $rr['imgscale']) . '.' . $ext,
'alt' => $alt_e,
'album' => array(
- 'link' => z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($rr['album']),
'name' => $name_e,
- 'alt' => t('View Album'),
),
);
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 438580917..e8f0e5186 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -108,11 +108,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$aid = get_account_id();
$p = [
- 'aid' => $aid,
- 'uid' => local_channel(),
- 'resource_id' => $base_image['resource_id'],
- 'filename' => $base_image['filename'],
- 'album' => t('Profile Photos')
+ 'aid' => $aid,
+ 'uid' => local_channel(),
+ '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']
];
$p['imgscale'] = PHOTO_RES_PROFILE_300;
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index 9c688af01..e114dfc0b 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -324,11 +324,6 @@ class Setup extends \Zotlabs\Web\Controller {
$siteurl = trim($_POST['siteurl']);
$timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
- $server_roles = [
- 'basic' => t('Basic/Minimal Social Networking'),
- 'standard' => t('Standard Configuration (default)'),
- 'pro' => t('Professional')
- ];
$tpl = get_markup_template('install_settings.tpl');
$o .= replace_macros($tpl, array(
@@ -348,8 +343,6 @@ class Setup extends \Zotlabs\Web\Controller {
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
- '$server_role' => array('server_role', t("Server Configuration/Role"), 'standard','',$server_roles),
-
'$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()),
'$baseurl' => z_root(),
diff --git a/Zotlabs/Module/Suggest.php b/Zotlabs/Module/Suggest.php
index 367308d90..2a69145ed 100644
--- a/Zotlabs/Module/Suggest.php
+++ b/Zotlabs/Module/Suggest.php
@@ -3,8 +3,6 @@ namespace Zotlabs\Module;
require_once('include/socgraph.php');
require_once('include/contact_widgets.php');
-require_once('include/widgets.php');
-
class Suggest extends \Zotlabs\Web\Controller {
@@ -23,7 +21,7 @@ class Suggest extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
$o = '';
if(! local_channel()) {
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
index 948c67c09..1d166cb57 100644
--- a/Zotlabs/Module/Wiki.php
+++ b/Zotlabs/Module/Wiki.php
@@ -238,13 +238,16 @@ class Wiki extends \Zotlabs\Web\Controller {
$rawContent = htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT);
+ $rawContent = $p['content'];
+
$content = ($p['content'] !== '' ? $rawContent : '"# New page\n"');
// Render the Markdown-formatted page content in HTML
if($mimeType == 'text/bbcode') {
$renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
else {
- $html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(MarkdownExtra::defaultTransform(Zlib\NativeWikiPage::bbcode($content)))));
+ $content = Zlib\MarkdownSoap::unescape($content);
+ $html = Zlib\NativeWikiPage::generate_toc(zidify_text(MarkdownExtra::defaultTransform(Zlib\NativeWikiPage::bbcode($content))));
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
$showPageControls = $wiki_editor;
@@ -253,6 +256,7 @@ class Wiki extends \Zotlabs\Web\Controller {
goaway('/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName);
}
+
$wikiModalID = random_string(3);
$wikiModal = replace_macros(get_markup_template('generic_modal.tpl'), array(
@@ -328,8 +332,13 @@ class Wiki extends \Zotlabs\Web\Controller {
$html = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))),$wikiURL);
}
else {
- $content = Zlib\NativeWikiPage::bbcode($content);
- $html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(MarkdownExtra::defaultTransform($content))));
+
+ $bb = Zlib\NativeWikiPage::bbcode($content);
+ $x = new ZLib\MarkdownSoap($bb);
+ $md = $x->clean();
+ $md = ZLib\MarkdownSoap::unescape($md);
+ $html = MarkdownExtra::defaultTransform($md);
+ $html = Zlib\NativeWikiPage::generate_toc(zidify_text($html));
$html = Zlib\NativeWikiPage::convert_links($html,$wikiURL);
}
json_return_and_die(array('html' => $html, 'success' => true));
@@ -454,7 +463,11 @@ class Wiki extends \Zotlabs\Web\Controller {
json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
}
- $page_list_html = widget_wiki_pages(array(
+ // @FIXME - we shouldn't invoke this if it isn't in the PDL or has been over-ridden
+
+ $x = new \Zotlabs\Widget\Wiki_pages();
+
+ $page_list_html = $x->widget(array(
'resource_id' => $resource_id,
'refresh' => true,
'channel' => argv(1)));
@@ -512,7 +525,6 @@ class Wiki extends \Zotlabs\Web\Controller {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
-
// Determine if observer has permission to read content
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
@@ -521,11 +533,12 @@ class Wiki extends \Zotlabs\Web\Controller {
json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
}
- $historyHTML = widget_wiki_page_history(array(
+ $historyHTML = \Zotlabs\Lib\NativeWikiPage::render_page_history(array(
'resource_id' => $resource_id,
'pageUrlName' => $pageUrlName,
'permsWrite' => $perms['write']
));
+
json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
}
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index 5826063fd..5c1ca7d10 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -4,8 +4,6 @@ namespace Zotlabs\Render;
require_once('include/security.php');
require_once('include/menu.php');
-require_once('include/widgets.php');
-
class Comanche {
@@ -410,6 +408,21 @@ class Comanche {
}
}
+ $clsname = ucfirst($name);
+ $nsname = "\\Zotlabs\\Widget\\" . $clsname;
+
+ if(file_exists('Zotlabs/SiteWidget/' . $clsname . '.php'))
+ require_once('Zotlabs/SiteWidget/' . $clsname . '.php');
+ elseif(file_exists('Zotlabs/Widget/' . $clsname . '.php'))
+ require_once('Zotlabs/Widget/' . $clsname . '.php');
+ if(class_exists($nsname)) {
+ $x = new $nsname;
+ $f = 'widget';
+ if(method_exists($x,$f)) {
+ return $x->$f($vars);
+ }
+ }
+
$func = 'widget_' . trim($name);
if(! function_exists($func)) {
diff --git a/Zotlabs/Storage/Directory.php b/Zotlabs/Storage/Directory.php
index 51540735c..0ed7a3c68 100644
--- a/Zotlabs/Storage/Directory.php
+++ b/Zotlabs/Storage/Directory.php
@@ -49,7 +49,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @param BasicAuth &$auth_plugin
*/
public function __construct($ext_path, &$auth_plugin) {
-// $ext_path = urldecode($ext_path);
+ // $ext_path = urldecode($ext_path);
logger('directory ' . $ext_path, LOGGER_DATA);
$this->ext_path = $ext_path;
// remove "/cloud" from the beginning of the path
@@ -167,6 +167,14 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
intval($this->auth->owner_id)
);
+ $x = attach_syspaths($this->auth->owner_id,$this->folder_hash);
+
+ $y = q("update attach set display_path = '%s where hash = '%s' and uid = %d",
+ dbesc($x['path']),
+ dbesc($this->folder_hash),
+ intval($this->auth->owner_id)
+ );
+
$ch = channelx_by_n($this->auth->owner_id);
if ($ch) {
$sync = attach_export_data($ch, $this->folder_hash);
@@ -260,14 +268,18 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
dbesc($f),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
- '', //TODO: use os_path
- '', //TODO: use display_path
+ '',
+ '',
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
dbesc($deny_gid)
);
+ // fetch the actual storage paths
+
+ $xpath = attach_syspaths($this->auth->owner_id, $hash);
+
// returns the number of bytes that were written to the file, or FALSE on failure
$size = file_put_contents($f, $data);
// delete attach entry if file_put_contents() failed
@@ -281,15 +293,17 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$edited = datetime_convert();
$is_photo = 0;
- $x = @getimagesize($f);
- logger('getimagesize: ' . print_r($x,true), LOGGER_DATA);
- if (($x) && ($x[2] === IMAGETYPE_GIF || $x[2] === IMAGETYPE_JPEG || $x[2] === IMAGETYPE_PNG)) {
+ $gis = @getimagesize($f);
+ logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
+ if (($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
$is_photo = 1;
}
// updates entry with filesize and timestamp
- $d = q("UPDATE attach SET filesize = '%s', is_photo = %d, edited = '%s' WHERE hash = '%s' AND uid = %d",
+ $d = q("UPDATE attach SET filesize = '%s', os_path = '%s', display_path = '%s', is_photo = %d, edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc($size),
+ dbesc($xpath['os_path']),
+ dbesc($xpath['display_path']),
intval($is_photo),
dbesc($edited),
dbesc($hash),
@@ -312,29 +326,29 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
// check against service class quota
$limit = engr_units_to_bytes(service_class_fetch($c[0]['channel_id'], 'attach_upload_limit'));
if ($limit !== false) {
- $x = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d ",
+ $z = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d ",
intval($c[0]['channel_account_id'])
);
- if (($x) && ($x[0]['total'] + $size > $limit)) {
- logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . userReadableSize($limit));
+ if (($z) && ($z[0]['total'] + $size > $limit)) {
+ logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $z[0]['total'] . ' limit is ' . userReadableSize($limit));
attach_delete($c[0]['channel_id'], $hash);
return;
}
}
- if ($is_photo) {
+ if($is_photo) {
$album = '';
if ($this->folder_hash) {
- $f1 = q("select filename from attach WHERE hash = '%s' AND uid = %d",
+ $f1 = q("select filename, display_path from attach WHERE hash = '%s' AND uid = %d",
dbesc($this->folder_hash),
intval($c[0]['channel_id'])
);
if ($f1)
- $album = $f1[0]['filename'];
+ $album = (($f1[0]['display_path']) ? $f1[0]['display_path'] : $f1[0]['filename']);
}
require_once('include/photos.php');
- $args = array( 'resource_id' => $hash, 'album' => $album, 'os_path' => $f, 'filename' => $name, 'getimagesize' => $x, 'directory' => $direct);
+ $args = array( 'resource_id' => $hash, 'album' => $album, 'os_syspath' => $f, 'os_path' => $xpath['os_path'], 'display_path' => $xpath['path'], 'filename' => $name, 'getimagesize' => $gis, 'directory' => $direct);
$p = photo_upload($c[0], \App::get_observer(), $args);
}
@@ -646,20 +660,24 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
logger("Path mismatch: $path !== /$file");
return NULL;
}
- if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
- $prefix = 'DISTINCT ON (filename)';
- $suffix = 'ORDER BY filename';
- }
- else {
- $prefix = '';
- $suffix = 'GROUP BY filename';
- }
+
+ $prefix = '';
+ $suffix = '';
+
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
dbesc($folder),
intval($channel_id)
);
foreach ($r as $rr) {
+
+ // @FIXME I don't think we use revisions currently in attach structures.
+ // In case we see any in the wild provide a unique filename. This
+ // name may or may not be accessible
+
+ if($rr['revision'])
+ $rr['filename'] .= '-' . $rr['revision'];
+
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
if (intval($rr['is_dir'])) {
$ret[] = new Directory($path . '/' . $rr['filename'], $auth);
diff --git a/Zotlabs/Storage/File.php b/Zotlabs/Storage/File.php
index d2bca3964..1475241ab 100644
--- a/Zotlabs/Storage/File.php
+++ b/Zotlabs/Storage/File.php
@@ -85,13 +85,23 @@ class File extends DAV\Node implements DAV\IFile {
intval($this->data['id'])
);
+ $x = attach_syspaths($this->auth->owner_id,$this->data['hash']);
+
+ $y = q("update attach set display_path = '%s where hash = '%s' and uid = %d",
+ dbesc($x['path']),
+ dbesc($this->data['hash']),
+ intval($this->auth->owner_id)
+ );
+
if($this->data->is_photo) {
- $r = q("update photo set filename = '%s' where resource_id = '%s' and uid = %d",
+ $r = q("update photo set filename = '%s', display_path = '%s' where resource_id = '%s' and uid = %d",
dbesc($newName),
+ dbesc($x['path']),
dbesc($this->data['hash']),
intval($this->auth->owner_id)
);
}
+
$ch = channelx_by_n($this->auth->owner_id);
if($ch) {
$sync = attach_export_data($ch,$this->data['hash']);
diff --git a/Zotlabs/Web/WebServer.php b/Zotlabs/Web/WebServer.php
index 5bb0e08e8..9c9f0483a 100644
--- a/Zotlabs/Web/WebServer.php
+++ b/Zotlabs/Web/WebServer.php
@@ -79,11 +79,6 @@ class WebServer {
if(! x($_SESSION, 'sysmsg_info'))
$_SESSION['sysmsg_info'] = array();
- /*
- * check_config() is responsible for running update scripts. These automatically
- * update the DB schema whenever we push a new one out. It also checks to see if
- * any plugins have been added or removed and reacts accordingly.
- */
if(\App::$install) {
@@ -91,8 +86,16 @@ class WebServer {
if(\App::$module != 'view')
\App::$module = 'setup';
}
- else
- check_config($a);
+ else {
+
+ /*
+ * check_config() is responsible for running update scripts. These automatically
+ * update the DB schema whenever we push a new one out. It also checks to see if
+ * any plugins have been added or removed and reacts accordingly.
+ */
+
+ check_config();
+ }
nav_set_selected('nothing');
diff --git a/Zotlabs/Widget/Activity.php b/Zotlabs/Widget/Activity.php
new file mode 100644
index 000000000..7264a3360
--- /dev/null
+++ b/Zotlabs/Widget/Activity.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Activity {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return '';
+
+ $o = '';
+
+ if(is_array($arr) && array_key_exists('limit',$arr))
+ $limit = " limit " . intval($limit) . " ";
+ else
+ $limit = '';
+
+ $perms_sql = item_permissions_sql(local_channel()) . item_normal();
+
+ $r = q("select author_xchan from item where item_unseen = 1 and uid = %d $perms_sql",
+ intval(local_channel())
+ );
+
+ $contributors = [];
+ $arr = [];
+
+ if($r) {
+ foreach($r as $rv) {
+ if(array_key_exists($rv['author_xchan'],$contributors)) {
+ $contributors[$rv['author_xchan']] ++;
+ }
+ else {
+ $contributors[$rv['author_xchan']] = 1;
+ }
+ }
+ foreach($contributors as $k => $v) {
+ $arr[] = [ 'author_xchan' => $k, 'total' => $v ];
+ }
+ usort($arr,'total_sort');
+ xchan_query($arr);
+ }
+
+ $x = [ 'entries' => $arr ];
+ call_hooks('activity_widget',$x);
+ $arr = $x['entries'];
+
+ if($arr) {
+ $o .= '<div class="widget">';
+ $o .= '<h3>' . t('Activity','widget') . '</h3><ul class="nav nav-pills flex-column">';
+
+ foreach($arr as $rv) {
+ $o .= '<li class="nav-item"><a class="nav-link" href="network?f=&xchan=' . urlencode($rv['author_xchan']) . '" ><span class="badge badge-default float-right">' . ((intval($rv['total'])) ? intval($rv['total']) : '') . '</span><img src="' . $rv['author']['xchan_photo_s'] . '" class="menu-img-1" /> ' . $rv['author']['xchan_name'] . '</a></li>';
+ }
+ $o .= '</ul></div>';
+ }
+ return $o;
+ }
+
+}
+
diff --git a/Zotlabs/Widget/Admin.php b/Zotlabs/Widget/Admin.php
new file mode 100644
index 000000000..a761eebe3
--- /dev/null
+++ b/Zotlabs/Widget/Admin.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Admin {
+
+ function widget($arr) {
+
+ /*
+ * Side bar links
+ */
+
+ if(! is_site_admin()) {
+ return '';
+ }
+
+ $o = '';
+
+ // array( url, name, extra css classes )
+
+ $aside = [
+ 'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
+ 'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')),
+ 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
+ 'security' => array(z_root() . '/admin/security/', t('Security'), 'security'),
+ 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'),
+ 'plugins' => array(z_root() . '/admin/plugins/', t('Plugins'), 'plugins'),
+ 'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'),
+ 'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
+ 'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'),
+ 'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
+ ];
+
+ /* get plugins admin page */
+
+ $r = q("SELECT * FROM addon WHERE plugin_admin = 1");
+
+ $plugins = array();
+ if($r) {
+ foreach ($r as $h){
+ $plugin = $h['aname'];
+ $plugins[] = array(z_root() . '/admin/plugins/' . $plugin, $plugin, 'plugin');
+ // temp plugins with admin
+ \App::$plugins_admin[] = $plugin;
+ }
+ }
+
+ $logs = array(z_root() . '/admin/logs/', t('Logs'), 'logs');
+
+ $arr = array('links' => $aside,'plugins' => $plugins,'logs' => $logs);
+ call_hooks('admin_aside',$arr);
+
+ $o .= replace_macros(get_markup_template('admin_aside.tpl'), array(
+ '$admin' => $aside,
+ '$admtxt' => t('Admin'),
+ '$plugadmtxt' => t('Plugin Features'),
+ '$plugins' => $plugins,
+ '$logtxt' => t('Logs'),
+ '$logs' => $logs,
+ '$h_pending' => t('Member registrations waiting for confirmation'),
+ '$admurl'=> z_root() . '/admin/'
+ ));
+
+ return $o;
+
+ }
+}
+
diff --git a/Zotlabs/Widget/Affinity.php b/Zotlabs/Widget/Affinity.php
new file mode 100644
index 000000000..439ba1f33
--- /dev/null
+++ b/Zotlabs/Widget/Affinity.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Affinity {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return '';
+
+ // Get default cmin value from pconfig, but allow GET parameter to override
+ $cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
+ $cmin = (($cmin) ? $cmin : 0);
+ $cmin = ((x($_REQUEST,'cmin')) ? intval($_REQUEST['cmin']) : $cmin);
+
+ // Get default cmax value from pconfig, but allow GET parameter to override
+ $cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
+ $cmax = (($cmax) ? $cmax : 99);
+ $cmax = ((x($_REQUEST,'cmax')) ? intval($_REQUEST['cmax']) : $cmax);
+
+
+ if(feature_enabled(local_channel(),'affinity')) {
+
+ $labels = array(
+ t('Me'),
+ t('Family'),
+ t('Friends'),
+ t('Acquaintances'),
+ t('All')
+ );
+ call_hooks('affinity_labels',$labels);
+ $label_str = '';
+
+ if($labels) {
+ foreach($labels as $l) {
+ if($label_str) {
+ $label_str .= ", '|'";
+ $label_str .= ", '" . $l . "'";
+ }
+ else
+ $label_str .= "'" . $l . "'";
+ }
+ }
+
+ $tpl = get_markup_template('main_slider.tpl');
+ $x = replace_macros($tpl,array(
+ '$val' => $cmin . ',' . $cmax,
+ '$refresh' => t('Refresh'),
+ '$labels' => $label_str,
+ ));
+
+ $arr = array('html' => $x);
+ call_hooks('main_slider',$arr);
+ return $arr['html'];
+ }
+ return '';
+ }
+}
+ \ No newline at end of file
diff --git a/Zotlabs/Widget/Album.php b/Zotlabs/Widget/Album.php
new file mode 100644
index 000000000..f359e6d0f
--- /dev/null
+++ b/Zotlabs/Widget/Album.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/attach.php');
+
+class Album {
+
+ function widget($args) {
+
+
+ $owner_uid = \App::$profile_uid;
+ $sql_extra = permissions_sql($owner_uid);
+
+
+ if(! perm_is_allowed($owner_uid,get_observer_hash(),'view_storage'))
+ return '';
+
+ if($args['album'])
+ $album = $args['album'];
+ if($args['title'])
+ $title = $args['title'];
+
+ /**
+ * This may return incorrect permissions if you have multiple directories of the same name.
+ * It is a limitation of the photo table using a name for a photo album instead of a folder hash
+ */
+
+ if($album) {
+ $x = q("select hash from attach where filename = '%s' and uid = %d limit 1",
+ dbesc($album),
+ intval($owner_uid)
+ );
+ if($x) {
+ $y = attach_can_view_folder($owner_uid,get_observer_hash(),$x[0]['hash']);
+ if(! $y)
+ return '';
+ }
+ }
+
+ $order = 'DESC';
+
+ $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
+ (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph
+ ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
+ ORDER BY created $order ",
+ intval($owner_uid),
+ dbesc($album),
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE)
+ );
+
+ //edit album name
+ $album_edit = null;
+
+ $photos = array();
+ if($r) {
+ $twist = 'rotright';
+ foreach($r as $rr) {
+
+ if($twist == 'rotright')
+ $twist = 'rotleft';
+ else
+ $twist = 'rotright';
+
+ $ext = $phototypes[$rr['mimetype']];
+
+ $imgalt_e = $rr['filename'];
+ $desc_e = $rr['description'];
+
+ $imagelink = (z_root() . '/photos/' . \App::$profile['channel_address'] . '/image/' . $rr['resource_id']);
+
+
+ $photos[] = array(
+ 'id' => $rr['id'],
+ 'twist' => ' ' . $twist . rand(2,4),
+ 'link' => $imagelink,
+ 'title' => t('View Photo'),
+ 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext,
+ 'alt' => $imgalt_e,
+ 'desc'=> $desc_e,
+ 'ext' => $ext,
+ 'hash'=> $rr['resource_id'],
+ 'unknown' => t('Unknown')
+ );
+ }
+ }
+
+
+ $tpl = get_markup_template('photo_album.tpl');
+ $o .= replace_macros($tpl, array(
+ '$photos' => $photos,
+ '$album' => (($title) ? $title : $album),
+ '$album_id' => rand(),
+ '$album_edit' => array(t('Edit Album'), $album_edit),
+ '$can_post' => false,
+ '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)),
+ '$order' => false,
+ '$upload_form' => $upload_form,
+ '$usage' => $usage_message
+ ));
+
+ return $o;
+ }
+}
+
diff --git a/Zotlabs/Widget/Appcategories.php b/Zotlabs/Widget/Appcategories.php
new file mode 100644
index 000000000..490ec1abc
--- /dev/null
+++ b/Zotlabs/Widget/Appcategories.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Appcategories {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return '';
+
+ $selected = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
+
+ // @FIXME ??? $srchurl undefined here - commented out until is reviewed
+ //$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ //$srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
+
+ // Leaving this line which negates the effect of the two invalid lines prior
+ $srchurl = z_root() . '/apps';
+
+ $terms = array();
+
+ $r = q("select distinct(term.term)
+ from term join app on term.oid = app.id
+ where app_channel = %d
+ and term.uid = app_channel
+ and term.otype = %d
+ and term.term != 'nav_featured_app'
+ order by term.term asc",
+ intval(local_channel()),
+ intval(TERM_OBJ_APP)
+ );
+
+ if($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' => $srchurl,
+
+ ));
+ }
+ }
+}
diff --git a/Zotlabs/Widget/Appcloud.php b/Zotlabs/Widget/Appcloud.php
new file mode 100644
index 000000000..2a4671eee
--- /dev/null
+++ b/Zotlabs/Widget/Appcloud.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Appcloud {
+
+ function widget($arr) {
+ if(! local_channel())
+ return '';
+ return app_tagblock(z_root() . '/apps');
+ }
+}
+
diff --git a/Zotlabs/Widget/Archive.php b/Zotlabs/Widget/Archive.php
new file mode 100644
index 000000000..c151ca563
--- /dev/null
+++ b/Zotlabs/Widget/Archive.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Archive {
+
+ function widget($arr) {
+
+ $o = '';
+
+ if(! \App::$profile_uid) {
+ return '';
+ }
+
+ $uid = \App::$profile_uid;
+
+ if(! feature_enabled($uid,'archives'))
+ return '';
+
+ if(! perm_is_allowed($uid,get_observer_hash(),'view_stream'))
+ return '';
+
+ $wall = ((array_key_exists('wall', $arr)) ? intval($arr['wall']) : 0);
+ $style = ((array_key_exists('style', $arr)) ? $arr['style'] : 'select');
+ $showend = ((get_pconfig($uid,'system','archive_show_end_date')) ? true : false);
+ $mindate = get_pconfig($uid,'system','archive_mindate');
+ $visible_years = get_pconfig($uid,'system','archive_visible_years');
+ if(! $visible_years)
+ $visible_years = 5;
+
+ $url = z_root() . '/' . \App::$cmd;
+
+ $ret = list_post_dates($uid,$wall,$mindate);
+
+ if(! count($ret))
+ return '';
+
+ $cutoff_year = intval(datetime_convert('',date_default_timezone_get(),'now','Y')) - $visible_years;
+ $cutoff = ((array_key_exists($cutoff_year,$ret))? true : false);
+
+ $o = replace_macros(get_markup_template('posted_date_widget.tpl'),array(
+ '$title' => t('Archives'),
+ '$size' => $visible_years,
+ '$cutoff_year' => $cutoff_year,
+ '$cutoff' => $cutoff,
+ '$url' => $url,
+ '$style' => $style,
+ '$showend' => $showend,
+ '$dates' => $ret
+ ));
+ return $o;
+ }
+}
+
diff --git a/Zotlabs/Widget/Bookmarkedchats.php b/Zotlabs/Widget/Bookmarkedchats.php
new file mode 100644
index 000000000..d64bbdb4b
--- /dev/null
+++ b/Zotlabs/Widget/Bookmarkedchats.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Bookmarkedchats {
+
+ function widget($arr) {
+
+ if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
+ return '';
+
+ $h = get_observer_hash();
+ if(! $h)
+ return;
+ $r = q("select xchat_url, xchat_desc from xchat where xchat_xchan = '%s' order by xchat_desc",
+ dbesc($h)
+ );
+ if($r) {
+ for($x = 0; $x < count($r); $x ++) {
+ $r[$x]['xchat_url'] = zid($r[$x]['xchat_url']);
+ }
+ }
+ return replace_macros(get_markup_template('bookmarkedchats.tpl'),array(
+ '$header' => t('Bookmarked Chatrooms'),
+ '$rooms' => $r
+ ));
+ }
+}
diff --git a/Zotlabs/Widget/Catcloud_wall.php b/Zotlabs/Widget/Catcloud_wall.php
new file mode 100644
index 000000000..3795987cc
--- /dev/null
+++ b/Zotlabs/Widget/Catcloud_wall.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Catcloud_wall {
+
+ function widget($arr) {
+
+ if((! \App::$profile['profile_uid']) || (! \App::$profile['channel_hash']))
+ return '';
+ if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_stream'))
+ return '';
+
+ $limit = ((array_key_exists('limit',$arr)) ? intval($arr['limit']) : 50);
+
+ return catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash'], 'wall');
+ }
+
+}
diff --git a/Zotlabs/Widget/Categories.php b/Zotlabs/Widget/Categories.php
new file mode 100644
index 000000000..d1dcfda93
--- /dev/null
+++ b/Zotlabs/Widget/Categories.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/contact_widgets.php');
+
+class Categories {
+
+ function widget($arr) {
+
+ if((! \App::$profile['profile_uid'])
+ || (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'view_stream'))) {
+ return '';
+ }
+
+ $cat = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
+ $srchurl = \App::$query_string;
+ $srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
+
+ return categories_widget($srchurl, $cat);
+ }
+}
diff --git a/Zotlabs/Widget/Chatroom_list.php b/Zotlabs/Widget/Chatroom_list.php
new file mode 100644
index 000000000..e2aad0e05
--- /dev/null
+++ b/Zotlabs/Widget/Chatroom_list.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Chatroom_list {
+
+ function widget($arr) {
+
+ if(! \App::$profile)
+ return '';
+
+ $r = \Zotlabs\Lib\Chatroom::roomlist(\App::$profile['profile_uid']);
+
+ if($r) {
+ return replace_macros(get_markup_template('chatroomlist.tpl'), array(
+ '$header' => t('Chatrooms'),
+ '$baseurl' => z_root(),
+ '$nickname' => \App::$profile['channel_address'],
+ '$items' => $r,
+ '$overview' => t('Overview')
+ ));
+ }
+ }
+}
diff --git a/Zotlabs/Widget/Chatroom_members.php b/Zotlabs/Widget/Chatroom_members.php
new file mode 100644
index 000000000..8ed77fb3c
--- /dev/null
+++ b/Zotlabs/Widget/Chatroom_members.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Chatroom_members {
+
+ // The actual contents are filled in via AJAX
+
+ function widget() {
+ return replace_macros(get_markup_template('chatroom_members.tpl'), array(
+ '$header' => t('Chat Members')
+ ));
+ }
+
+}
diff --git a/Zotlabs/Widget/Clock.php b/Zotlabs/Widget/Clock.php
new file mode 100644
index 000000000..b63b5f748
--- /dev/null
+++ b/Zotlabs/Widget/Clock.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Clock {
+
+ function widget($arr) {
+
+ $miltime = 0;
+ if(isset($arr['military']) && $arr['military'])
+ $miltime = 1;
+
+ $o = <<< EOT
+<div class="widget">
+<h3 class="clockface"></h3>
+<script>
+
+var timerID = null
+var timerRunning = false
+
+function stopclock(){
+ if(timerRunning)
+ clearTimeout(timerID)
+ timerRunning = false
+}
+
+function startclock(){
+ stopclock()
+ showtime()
+}
+
+function showtime(){
+ var now = new Date()
+ var hours = now.getHours()
+ var minutes = now.getMinutes()
+ var seconds = now.getSeconds()
+ var military = $miltime
+ var timeValue = ""
+ if(military)
+ timeValue = hours
+ else
+ timeValue = ((hours > 12) ? hours - 12 : hours)
+ timeValue += ((minutes < 10) ? ":0" : ":") + minutes
+// timeValue += ((seconds < 10) ? ":0" : ":") + seconds
+ if(! military)
+ timeValue += (hours >= 12) ? " P.M." : " A.M."
+ $('.clockface').html(timeValue)
+ timerID = setTimeout("showtime()",1000)
+ timerRunning = true
+}
+
+$(document).ready(function() {
+ startclock();
+});
+
+</script>
+</div>
+EOT;
+
+ return $o;
+ }
+}
+
diff --git a/Zotlabs/Widget/Collections.php b/Zotlabs/Widget/Collections.php
new file mode 100644
index 000000000..d2b29679a
--- /dev/null
+++ b/Zotlabs/Widget/Collections.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/group.php');
+
+class Collections {
+
+ function widget($args) {
+
+ $mode = ((array_key_exists('mode',$args)) ? $args['mode'] : 'conversation');
+ switch($mode) {
+ case 'conversation':
+ $every = argv(0);
+ $each = argv(0);
+ $edit = true;
+ $current = $_REQUEST['gid'];
+ $abook_id = 0;
+ $wmode = 0;
+ break;
+ case 'connections':
+ $every = 'connections';
+ $each = 'group';
+ $edit = true;
+ $current = $_REQUEST['gid'];
+ $abook_id = 0;
+ $wmode = 0;
+ case 'groups':
+ $every = 'connections';
+ $each = argv(0);
+ $edit = false;
+ $current = intval(argv(1));
+ $abook_id = 0;
+ $wmode = 1;
+ break;
+ case 'abook':
+ $every = 'connections';
+ $each = 'group';
+ $edit = false;
+ $current = 0;
+ $abook_id = \App::$poi['abook_xchan'];
+ $wmode = 1;
+ break;
+ default:
+ return '';
+ break;
+ }
+
+ return group_side($every, $each, $edit, $current, $abook_id, $wmode);
+ }
+}
diff --git a/Zotlabs/Widget/Conversations.php b/Zotlabs/Widget/Conversations.php
new file mode 100644
index 000000000..c1f1eff16
--- /dev/null
+++ b/Zotlabs/Widget/Conversations.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Conversations {
+
+ function widget($arr) {
+
+ if (! local_channel())
+ return;
+
+ if(argc() > 1) {
+
+ switch(argv(1)) {
+ case 'combined':
+ $mailbox = 'combined';
+ $header = t('Conversations');
+ break;
+ case 'inbox':
+ $mailbox = 'inbox';
+ $header = t('Received Messages');
+ break;
+ case 'outbox':
+ $mailbox = 'outbox';
+ $header = t('Sent Messages');
+ break;
+ default:
+ $mailbox = 'combined';
+ $header = t('Conversations');
+ break;
+ }
+
+ require_once('include/message.php');
+
+ // private_messages_list() can do other more complicated stuff, for now keep it simple
+ $r = private_messages_list(local_channel(), $mailbox, \App::$pager['start'], \App::$pager['itemspage']);
+
+ if(! $r) {
+ info( t('No messages.') . EOL);
+ return $o;
+ }
+
+ $messages = array();
+
+ foreach($r as $rr) {
+
+ $messages[] = array(
+ 'mailbox' => $mailbox,
+ 'id' => $rr['id'],
+ 'from_name' => $rr['from']['xchan_name'],
+ 'from_url' => chanlink_hash($rr['from_xchan']),
+ 'from_photo' => $rr['from']['xchan_photo_s'],
+ 'to_name' => $rr['to']['xchan_name'],
+ 'to_url' => chanlink_hash($rr['to_xchan']),
+ 'to_photo' => $rr['to']['xchan_photo_s'],
+ 'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
+ 'delete' => t('Delete conversation'),
+ 'body' => $rr['body'],
+ 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'),
+ 'seen' => $rr['seen'],
+ 'selected' => ((argv(2)) ? (argv(2) == $rr['id']) : ($r[0]['id'] == $rr['id']))
+ );
+ }
+
+ $tpl = get_markup_template('mail_head.tpl');
+ $o .= replace_macros($tpl, array(
+ '$header' => $header,
+ '$messages' => $messages
+ ));
+
+ }
+ return $o;
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Widget/Cover_photo.php b/Zotlabs/Widget/Cover_photo.php
new file mode 100644
index 000000000..d2eb1be92
--- /dev/null
+++ b/Zotlabs/Widget/Cover_photo.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Cover_photo {
+
+ function widget($arr) {
+
+ require_once('include/channel.php');
+ $o = '';
+
+ if(\App::$module == 'channel' && $_REQUEST['mid'])
+ return '';
+
+ $channel_id = 0;
+ if(array_key_exists('channel_id', $arr) && intval($arr['channel_id']))
+ $channel_id = intval($arr['channel_id']);
+ if(! $channel_id)
+ $channel_id = \App::$profile_uid;
+ if(! $channel_id)
+ return '';
+
+ $channel = channelx_by_n($channel_id);
+
+ if(array_key_exists('style', $arr) && isset($arr['style']))
+ $style = $arr['style'];
+ else
+ $style = 'width:100%; height: auto;';
+
+ // ensure they can't sneak in an eval(js) function
+
+ if(strpbrk($style,'(\'"<>') !== false)
+ $style = '';
+
+ if(array_key_exists('title', $arr) && isset($arr['title']))
+ $title = $arr['title'];
+ else
+ $title = $channel['channel_name'];
+
+ if(array_key_exists('subtitle', $arr) && isset($arr['subtitle']))
+ $subtitle = $arr['subtitle'];
+ else
+ $subtitle = str_replace('@','&#x40;',$channel['xchan_addr']);
+
+ $c = get_cover_photo($channel_id,'html');
+
+ if($c) {
+ $photo_html = (($style) ? str_replace('alt=',' style="' . $style . '" alt=',$c) : $c);
+
+ $o = replace_macros(get_markup_template('cover_photo_widget.tpl'),array(
+ '$photo_html' => $photo_html,
+ '$title' => $title,
+ '$subtitle' => $subtitle,
+ '$hovertitle' => t('Click to show more'),
+ ));
+ }
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Design_tools.php b/Zotlabs/Widget/Design_tools.php
new file mode 100644
index 000000000..8ab6a235d
--- /dev/null
+++ b/Zotlabs/Widget/Design_tools.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Design_tools {
+
+ function widget($arr) {
+
+ // mod menu doesn't load a profile. For any modules which load a profile, check it.
+ // otherwise local_channel() is sufficient for permissions.
+
+ if(\App::$profile['profile_uid'])
+ if((\App::$profile['profile_uid'] != local_channel()) && (! \App::$is_sys))
+ return '';
+
+ if(! local_channel())
+ return '';
+
+ return design_tools();
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Widget/Dirsort.php b/Zotlabs/Widget/Dirsort.php
new file mode 100644
index 000000000..e75a00e50
--- /dev/null
+++ b/Zotlabs/Widget/Dirsort.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/dir_fns.php');
+
+class Dirsort {
+ function widget($arr) {
+ return dir_sort_links();
+ }
+}
diff --git a/Zotlabs/Widget/Dirtags.php b/Zotlabs/Widget/Dirtags.php
new file mode 100644
index 000000000..f211d5942
--- /dev/null
+++ b/Zotlabs/Widget/Dirtags.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/dir_fns.php');
+
+class Dirtags {
+
+ function widget($arr) {
+ return dir_tagblock(z_root() . '/directory', null);
+ }
+
+}
diff --git a/Zotlabs/Widget/Eventstools.php b/Zotlabs/Widget/Eventstools.php
new file mode 100644
index 000000000..7efd3f72e
--- /dev/null
+++ b/Zotlabs/Widget/Eventstools.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Eventstools {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return;
+
+ return replace_macros(get_markup_template('events_tools_side.tpl'), array(
+ '$title' => t('Events Tools'),
+ '$export' => t('Export Calendar'),
+ '$import' => t('Import Calendar'),
+ '$submit' => t('Submit')
+ ));
+ }
+}
diff --git a/Zotlabs/Widget/Filer.php b/Zotlabs/Widget/Filer.php
new file mode 100644
index 000000000..5d6f96a87
--- /dev/null
+++ b/Zotlabs/Widget/Filer.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/contact_widgets.php');
+
+class Filer {
+
+ function widget($arr) {
+ if(! local_channel())
+ return '';
+
+
+ $selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : '');
+
+ $terms = array();
+ $r = q("select distinct term from term where uid = %d and ttype = %d order by term asc",
+ intval(local_channel()),
+ intval(TERM_FILE)
+ );
+ if(! $r)
+ return;
+
+ foreach($r as $rr)
+ $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : ''));
+
+ return replace_macros(get_markup_template('fileas_widget.tpl'),array(
+ '$title' => t('Saved Folders'),
+ '$desc' => '',
+ '$sel_all' => (($selected == '') ? 'selected' : ''),
+ '$all' => t('Everything'),
+ '$terms' => $terms,
+ '$base' => z_root() . '/' . \App::$cmd
+ ));
+ }
+}
diff --git a/Zotlabs/Widget/Findpeople.php b/Zotlabs/Widget/Findpeople.php
new file mode 100644
index 000000000..f450b96ae
--- /dev/null
+++ b/Zotlabs/Widget/Findpeople.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/contact_widgets.php');
+
+class Findpeople {
+ function widget($arr) {
+ return findpeople_widget();
+ }
+}
+
diff --git a/Zotlabs/Widget/Follow.php b/Zotlabs/Widget/Follow.php
new file mode 100644
index 000000000..c4aecc8e1
--- /dev/null
+++ b/Zotlabs/Widget/Follow.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Follow {
+
+ function widget($args) {
+ if(! local_channel())
+ return '';
+
+ $uid = \App::$channel['channel_id'];
+ $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'];
+
+ $limit = service_class_fetch($uid,'total_channels');
+ if($limit !== false) {
+ $abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $total_channels, $limit);
+ }
+ else {
+ $abook_usage_message = '';
+ }
+
+ return replace_macros(get_markup_template('follow.tpl'),array(
+ '$connect' => t('Add New Connection'),
+ '$desc' => t('Enter channel address'),
+ '$hint' => t('Examples: bob@example.com, https://example.com/barbara'),
+ '$follow' => t('Connect'),
+ '$abook_usage_message' => $abook_usage_message
+ ));
+ }
+}
+
diff --git a/Zotlabs/Widget/Forums.php b/Zotlabs/Widget/Forums.php
new file mode 100644
index 000000000..67e498b24
--- /dev/null
+++ b/Zotlabs/Widget/Forums.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Forums {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return '';
+
+ $o = '';
+
+ if(is_array($arr) && array_key_exists('limit',$arr))
+ $limit = " limit " . intval($limit) . " ";
+ else
+ $limit = '';
+
+ $unseen = 0;
+ if(is_array($arr) && array_key_exists('unseen',$arr) && intval($arr['unseen']))
+ $unseen = 1;
+
+ $perms_sql = item_permissions_sql(local_channel()) . item_normal();
+
+ $xf = false;
+
+ $x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
+ intval(local_channel())
+ );
+ if($x1) {
+ $xc = ids_to_querystr($x1,'xchan',true);
+ $x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
+ intval(local_channel())
+ );
+ if($x2)
+ $xf = ids_to_querystr($x2,'xchan',true);
+ }
+
+ $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
+
+ $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d $sql_extra order by xchan_name $limit ",
+ intval(local_channel())
+ );
+ if(! $r1)
+ return $o;
+
+ $str = '';
+
+ // Trying to cram all this into a single query with joins and the proper group by's is tough.
+ // There also should be a way to update this via ajax.
+
+ for($x = 0; $x < count($r1); $x ++) {
+ $r = q("select sum(item_unseen) as unseen from item where owner_xchan = '%s' and uid = %d and item_unseen = 1 $perms_sql ",
+ dbesc($r1[$x]['xchan_hash']),
+ intval(local_channel())
+ );
+ if($r)
+ $r1[$x]['unseen'] = $r[0]['unseen'];
+
+ /**
+ * @FIXME
+ * This SQL makes the counts correct when you get forum posts arriving from different routes/sources
+ * (like personal channels). However the network query for these posts doesn't yet include this
+ * correction and it makes the SQL for that query pretty hairy so this is left as a future exercise.
+ * It may make more sense in that query to look for the mention in the body rather than another join,
+ * but that makes it very inefficient.
+ *
+ $r = q("select sum(item_unseen) as unseen from item left join term on oid = id where otype = %d and owner_xchan != '%s' and item.uid = %d and url = '%s' and ttype = %d $perms_sql ",
+ intval(TERM_OBJ_POST),
+ dbesc($r1[$x]['xchan_hash']),
+ intval(local_channel()),
+ dbesc($r1[$x]['xchan_url']),
+ intval(TERM_MENTION)
+ );
+ if($r)
+ $r1[$x]['unseen'] = ((array_key_exists('unseen',$r1[$x])) ? $r1[$x]['unseen'] + $r[0]['unseen'] : $r[0]['unseen']);
+ *
+ * end @FIXME
+ */
+
+ }
+
+ if($r1) {
+ $o .= '<div class="widget">';
+ $o .= '<h3>' . t('Forums') . '</h3><ul class="nav nav-pills flex-column">';
+
+ foreach($r1 as $rr) {
+ if($unseen && (! intval($rr['unseen'])))
+ continue;
+ $o .= '<li class="nav-item"><a class="nav-link" href="network?f=&pf=1&cid=' . $rr['abook_id'] . '" ><span class="badge badge-default float-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img class ="menu-img-1" src="' . $rr['xchan_photo_s'] . '" /> ' . $rr['xchan_name'] . '</a></li>';
+ }
+ $o .= '</ul></div>';
+ }
+ return $o;
+
+ }
+}
diff --git a/Zotlabs/Widget/Fullprofile.php b/Zotlabs/Widget/Fullprofile.php
new file mode 100644
index 000000000..d7340ef40
--- /dev/null
+++ b/Zotlabs/Widget/Fullprofile.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Fullprofile {
+
+ function widget($arr) {
+
+ if(! \App::$profile['profile_uid'])
+ return;
+
+ $block = observer_prohibited();
+
+ return profile_sidebar(\App::$profile, $block);
+ }
+}
diff --git a/Zotlabs/Widget/Helpindex.php b/Zotlabs/Widget/Helpindex.php
new file mode 100644
index 000000000..f23e73e75
--- /dev/null
+++ b/Zotlabs/Widget/Helpindex.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Helpindex {
+
+ function widget($arr) {
+
+ $o .= '<div class="widget">';
+
+ $level_0 = get_help_content('sitetoc');
+ if(! $level_0)
+ $level_0 = get_help_content('toc');
+
+ $level_0 = preg_replace('/\<ul(.*?)\>/','<ul class="nav nav-pills flex-column">',$level_0);
+
+ $levels = array();
+
+
+ if(argc() > 2) {
+ $path = '';
+ for($x = 1; $x < argc(); $x ++) {
+ $path .= argv($x) . '/';
+ $y = get_help_content($path . 'sitetoc');
+ if(! $y)
+ $y = get_help_content($path . 'toc');
+ if($y)
+ $levels[] = preg_replace('/\<ul(.*?)\>/','<ul class="nav nav-pills flex-column">',$y);
+ }
+ }
+
+ if($level_0)
+ $o .= $level_0;
+ if($levels) {
+ foreach($levels as $l) {
+ $o .= '<br /><br />';
+ $o .= $l;
+ }
+ }
+
+ $o .= '</div>';
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Item.php b/Zotlabs/Widget/Item.php
new file mode 100644
index 000000000..273d5649c
--- /dev/null
+++ b/Zotlabs/Widget/Item.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/security.php');
+
+class Item {
+
+ function widget($arr) {
+
+ $channel_id = 0;
+ if(array_key_exists('channel_id',$arr) && intval($arr['channel_id']))
+ $channel_id = intval($arr['channel_id']);
+ if(! $channel_id)
+ $channel_id = \App::$profile_uid;
+ if(! $channel_id)
+ return '';
+
+
+ if((! $arr['mid']) && (! $arr['title']))
+ return '';
+
+ if(! perm_is_allowed($channel_id, get_observer_hash(), 'view_pages'))
+ return '';
+
+ $sql_extra = item_permissions_sql($channel_id);
+
+ if($arr['title']) {
+ $r = q("select item.* from item left join iconfig on item.id = iconfig.iid
+ where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s'
+ and iconfig.k = 'WEBPAGE' and item_type = %d $sql_options $revision limit 1",
+ intval($channel_id),
+ dbesc($arr['title']),
+ intval(ITEM_TYPE_WEBPAGE)
+ );
+ }
+ else {
+ $r = q("select * from item where mid = '%s' and uid = %d and item_type = "
+ . intval(ITEM_TYPE_WEBPAGE) . " $sql_extra limit 1",
+ dbesc($arr['mid']),
+ intval($channel_id)
+ );
+ }
+
+ if(! $r)
+ return '';
+
+ xchan_query($r);
+ $r = fetch_post_tags($r, true);
+
+ $o = prepare_page($r[0]);
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Mailmenu.php b/Zotlabs/Widget/Mailmenu.php
new file mode 100644
index 000000000..512f7d9c0
--- /dev/null
+++ b/Zotlabs/Widget/Mailmenu.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Mailmenu {
+
+ function widget($arr) {
+
+ if (! local_channel())
+ return;
+
+ return replace_macros(get_markup_template('message_side.tpl'), array(
+ '$title' => t('Private Mail Menu'),
+ '$combined' => array(
+ 'label' => t('Combined View'),
+ 'url' => z_root() . '/mail/combined',
+ 'sel' => (argv(1) == 'combined'),
+ ),
+ '$inbox' => array(
+ 'label' => t('Inbox'),
+ 'url' => z_root() . '/mail/inbox',
+ 'sel' => (argv(1) == 'inbox'),
+ ),
+ '$outbox' => array(
+ 'label' => t('Outbox'),
+ 'url' => z_root() . '/mail/outbox',
+ 'sel' => (argv(1) == 'outbox'),
+ ),
+ '$new' => array(
+ 'label' => t('New Message'),
+ 'url' => z_root() . '/mail/new',
+ 'sel'=> (argv(1) == 'new'),
+ )
+ ));
+ }
+}
diff --git a/Zotlabs/Widget/Menu_preview.php b/Zotlabs/Widget/Menu_preview.php
new file mode 100644
index 000000000..51218f6cf
--- /dev/null
+++ b/Zotlabs/Widget/Menu_preview.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/menu.php');
+
+class Menu_preview {
+
+ function widget($arr) {
+ if(! \App::$data['menu_item'])
+ return;
+
+ return menu_render(\App::$data['menu_item']);
+ }
+
+}
diff --git a/Zotlabs/Widget/Notes.php b/Zotlabs/Widget/Notes.php
new file mode 100644
index 000000000..5c83a550f
--- /dev/null
+++ b/Zotlabs/Widget/Notes.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Notes {
+
+ function widget($arr) {
+ if(! local_channel())
+ return '';
+ if(! feature_enabled(local_channel(),'private_notes'))
+ return '';
+
+ $text = get_pconfig(local_channel(),'notes','text');
+
+ $o = replace_macros(get_markup_template('notes.tpl'), array(
+ '$banner' => t('Notes'),
+ '$text' => $text,
+ '$save' => t('Save'),
+ ));
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Photo.php b/Zotlabs/Widget/Photo.php
new file mode 100644
index 000000000..10031f028
--- /dev/null
+++ b/Zotlabs/Widget/Photo.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Photo {
+
+
+ /**
+ * @brief Widget to display a single photo.
+ *
+ * @param array $arr associative array with
+ * * \e string \b src URL of photo; URL must be an http or https URL
+ * * \e boolean \b zrl use zid in URL
+ * * \e string \b style CSS string
+ *
+ * @return string with parsed HTML
+ */
+
+ function widget($arr) {
+
+ $style = $zrl = false;
+
+ if(array_key_exists('src', $arr) && isset($arr['src']))
+ $url = $arr['src'];
+
+ if(strpos($url, 'http') !== 0)
+ return '';
+
+ if(array_key_exists('style', $arr) && isset($arr['style']))
+ $style = $arr['style'];
+
+ // ensure they can't sneak in an eval(js) function
+
+ if(strpbrk($style, '(\'"<>' ) !== false)
+ $style = '';
+
+ if(array_key_exists('zrl', $arr) && isset($arr['zrl']))
+ $zrl = (($arr['zrl']) ? true : false);
+
+ if($zrl)
+ $url = zid($url);
+
+ $o = '<div class="widget">';
+
+ $o .= '<img ' . (($zrl) ? ' class="zrl" ' : '')
+ . (($style) ? ' style="' . $style . '"' : '')
+ . ' src="' . $url . '" alt="' . t('photo/image') . '">';
+
+ $o .= '</div>';
+
+ return $o;
+ }
+}
+
diff --git a/Zotlabs/Widget/Photo_albums.php b/Zotlabs/Widget/Photo_albums.php
new file mode 100644
index 000000000..2a746e492
--- /dev/null
+++ b/Zotlabs/Widget/Photo_albums.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/photos.php');
+
+class Photo_albums {
+
+ function widget($arr) {
+
+ if(! \App::$profile['profile_uid'])
+ return '';
+
+ $channelx = channelx_by_n(\App::$profile['profile_uid']);
+
+ if((! $channelx) || (! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_storage')))
+ return '';
+
+ $sortkey = ((array_key_exists('sortkey',$arr)) ? $arr['sortkey'] : 'album');
+ $direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc');
+
+ return photos_album_widget($channelx, \App::get_observer(),$sortkey,$direction);
+ }
+}
+
diff --git a/Zotlabs/Widget/Photo_rand.php b/Zotlabs/Widget/Photo_rand.php
new file mode 100644
index 000000000..af80a3b9f
--- /dev/null
+++ b/Zotlabs/Widget/Photo_rand.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/photos.php');
+
+class Photo_rand {
+
+ function widget($arr) {
+
+ $style = false;
+
+ if(array_key_exists('album', $arr) && isset($arr['album']))
+ $album = $arr['album'];
+ else
+ $album = '';
+
+ $channel_id = 0;
+ if(array_key_exists('channel_id', $arr) && intval($arr['channel_id']))
+ $channel_id = intval($arr['channel_id']);
+ if(! $channel_id)
+ $channel_id = \App::$profile_uid;
+ if(! $channel_id)
+ return '';
+
+ $scale = ((array_key_exists('scale',$arr)) ? intval($arr['scale']) : 0);
+
+ $ret = photos_list_photos(array('channel_id' => $channel_id),\App::get_observer(),$album);
+
+ $filtered = array();
+ if($ret['success'] && $ret['photos'])
+ foreach($ret['photos'] as $p)
+ if($p['imgscale'] == $scale)
+ $filtered[] = $p['src'];
+
+ if($filtered) {
+ $e = mt_rand(0, count($filtered) - 1);
+ $url = $filtered[$e];
+ }
+
+ if(strpos($url, 'http') !== 0)
+ return '';
+
+ if(array_key_exists('style', $arr) && isset($arr['style']))
+ $style = $arr['style'];
+
+ // ensure they can't sneak in an eval(js) function
+
+ if(strpos($style,'(') !== false)
+ return '';
+
+ $url = zid($url);
+
+ $o = '<div class="widget">';
+
+ $o .= '<img class="zrl" '
+ . (($style) ? ' style="' . $style . '"' : '')
+ . ' src="' . $url . '" alt="' . t('photo/image') . '">';
+
+ $o .= '</div>';
+
+ return $o;
+ }
+}
+
+
diff --git a/Zotlabs/Widget/Profile.php b/Zotlabs/Widget/Profile.php
new file mode 100644
index 000000000..bffd910b6
--- /dev/null
+++ b/Zotlabs/Widget/Profile.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Profile {
+
+ function widget($args) {
+ $block = observer_prohibited();
+ return profile_sidebar(\App::$profile, $block, true);
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Widget/Pubsites.php b/Zotlabs/Widget/Pubsites.php
new file mode 100644
index 000000000..958ba68c2
--- /dev/null
+++ b/Zotlabs/Widget/Pubsites.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Pubsites {
+
+ // used by site ratings pages to provide a return link
+
+ function widget($arr) {
+ if(\App::$poi)
+ return;
+ return '<div class="widget"><ul class="nav nav-pills"><li><a href="pubsites">' . t('Public Hubs') . '</a></li></ul></div>';
+ }
+}
+
+
diff --git a/Zotlabs/Widget/Random_block.php b/Zotlabs/Widget/Random_block.php
new file mode 100644
index 000000000..465a51f97
--- /dev/null
+++ b/Zotlabs/Widget/Random_block.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Random_block {
+
+ function widget($arr) {
+
+ $channel_id = 0;
+ if(array_key_exists('channel_id',$arr) && intval($arr['channel_id']))
+ $channel_id = intval($arr['channel_id']);
+ if(! $channel_id)
+ $channel_id = \App::$profile_uid;
+ if(! $channel_id)
+ return '';
+
+ if(array_key_exists('contains',$arr))
+ $contains = $arr['contains'];
+
+ $o = '';
+
+ require_once('include/security.php');
+ $sql_options = item_permissions_sql($channel_id);
+
+ $randfunc = db_getfunc('RAND');
+
+ $r = q("select item.* from item left join iconfig on item.id = iconfig.iid
+ where item.uid = %d and iconfig.cat = 'system' and iconfig.v like '%s' and iconfig.k = 'BUILDBLOCK' and
+ item_type = %d $sql_options order by $randfunc limit 1",
+ intval($channel_id),
+ dbesc('%' . $contains . '%'),
+ intval(ITEM_TYPE_BLOCK)
+ );
+
+ if($r) {
+ $o = '<div class="widget bblock">';
+ if($r[0]['title'])
+ $o .= '<h3>' . $r[0]['title'] . '</h3>';
+
+ $o .= prepare_text($r[0]['body'],$r[0]['mimetype']);
+ $o .= '</div>';
+ }
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Rating.php b/Zotlabs/Widget/Rating.php
new file mode 100644
index 000000000..5e09f457b
--- /dev/null
+++ b/Zotlabs/Widget/Rating.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Rating {
+
+ function widget($arr) {
+
+
+ $rating_enabled = get_config('system','rating_enabled');
+ if(! $rating_enabled) {
+ return;
+ }
+
+ if($arr['target'])
+ $hash = $arr['target'];
+ else
+ $hash = \App::$poi['xchan_hash'];
+
+ if(! $hash)
+ return;
+
+ $url = '';
+ $remote = false;
+
+ if(remote_channel() && ! local_channel()) {
+ $ob = \App::get_observer();
+ if($ob && $ob['xchan_url']) {
+ $p = parse_url($ob['xchan_url']);
+ if($p) {
+ $url = $p['scheme'] . '://' . $p['host'] . (($p['port']) ? ':' . $p['port'] : '');
+ $url .= '/rate?f=&target=' . urlencode($hash);
+ }
+ $remote = true;
+ }
+ }
+
+ $self = false;
+
+ if(local_channel()) {
+ $channel = \App::get_channel();
+
+ if($hash == $channel['channel_hash'])
+ $self = true;
+
+ head_add_js('ratings.js');
+ }
+
+
+ $o = '<div class="widget">';
+ $o .= '<h3>' . t('Rating Tools') . '</h3>';
+
+ if((($remote) || (local_channel())) && (! $self)) {
+ if($remote)
+ $o .= '<a class="btn btn-block btn-primary btn-sm" href="' . $url . '"><i class="fa fa-pencil"></i> ' . t('Rate Me') . '</a>';
+ else
+ $o .= '<div class="btn btn-block btn-primary btn-sm" onclick="doRatings(\'' . $hash . '\'); return false;"><i class="fa fa-pencil"></i> ' . t('Rate Me') . '</div>';
+ }
+
+ $o .= '<a class="btn btn-block btn-default btn-sm" href="ratings/' . $hash . '"><i class="fa fa-eye"></i> ' . t('View Ratings') . '</a>';
+ $o .= '</div>';
+
+ return $o;
+
+ }
+}
+
diff --git a/Zotlabs/Widget/Savedsearch.php b/Zotlabs/Widget/Savedsearch.php
new file mode 100644
index 000000000..378c27139
--- /dev/null
+++ b/Zotlabs/Widget/Savedsearch.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Savedsearch {
+
+ function widget($arr) {
+
+ if((! local_channel()) || (! feature_enabled(local_channel(),'savedsearch')))
+ return '';
+
+ $search = ((x($_GET,'netsearch')) ? $_GET['netsearch'] : '');
+ if(! $search)
+ $search = ((x($_GET,'search')) ? $_GET['search'] : '');
+
+ if(x($_GET,'searchsave') && $search) {
+ $r = q("select * from term where uid = %d and ttype = %d and term = '%s' limit 1",
+ intval(local_channel()),
+ intval(TERM_SAVEDSEARCH),
+ dbesc($search)
+ );
+ if(! $r) {
+ q("insert into term ( uid,ttype,term ) values ( %d, %d, '%s') ",
+ intval(local_channel()),
+ intval(TERM_SAVEDSEARCH),
+ dbesc($search)
+ );
+ }
+ }
+
+ if(x($_GET,'searchremove') && $search) {
+ q("delete from term where uid = %d and ttype = %d and term = '%s'",
+ intval(local_channel()),
+ intval(TERM_SAVEDSEARCH),
+ dbesc($search)
+ );
+ $search = '';
+ }
+
+ $srchurl = \App::$query_string;
+
+ $srchurl = rtrim(preg_replace('/searchsave\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $hasq = ((strpos($srchurl,'?') !== false) ? true : false);
+ $srchurl = rtrim(preg_replace('/searchremove\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+
+ $srchurl = rtrim(preg_replace('/search\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $srchurl = rtrim(preg_replace('/submit\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
+
+
+ $hasq = ((strpos($srchurl,'?') !== false) ? true : false);
+ $hasamp = ((strpos($srchurl,'&') !== false) ? true : false);
+
+ if(($hasamp) && (! $hasq))
+ $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
+
+ $o = '';
+
+ $r = q("select tid,term from term WHERE uid = %d and ttype = %d ",
+ intval(local_channel()),
+ intval(TERM_SAVEDSEARCH)
+ );
+
+ $saved = array();
+
+ if(count($r)) {
+ foreach($r as $rr) {
+ $saved[] = array(
+ 'id' => $rr['tid'],
+ 'term' => $rr['term'],
+ 'dellink' => z_root() . '/' . $srchurl . (($hasq || $hasamp) ? '' : '?f=') . '&amp;searchremove=1&amp;search=' . urlencode($rr['term']),
+ 'srchlink' => z_root() . '/' . $srchurl . (($hasq || $hasamp) ? '' : '?f=') . '&amp;search=' . urlencode($rr['term']),
+ 'displayterm' => htmlspecialchars($rr['term'], ENT_COMPAT,'UTF-8'),
+ 'encodedterm' => urlencode($rr['term']),
+ 'delete' => t('Remove term'),
+ 'selected' => ($search==$rr['term']),
+ );
+ }
+ }
+
+ $tpl = get_markup_template("saved_searches.tpl");
+ $o = replace_macros($tpl, array(
+ '$title' => t('Saved Searches'),
+ '$add' => t('add'),
+ '$searchbox' => searchbox($search, 'netsearch-box', $srchurl . (($hasq) ? '' : '?f='), true),
+ '$saved' => $saved,
+ ));
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Settings_menu.php b/Zotlabs/Widget/Settings_menu.php
new file mode 100644
index 000000000..753390c23
--- /dev/null
+++ b/Zotlabs/Widget/Settings_menu.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Settings_menu {
+
+ function widget($arr) {
+
+ if(! local_channel())
+ return;
+
+
+ $channel = \App::get_channel();
+
+ $abook_self_id = 0;
+
+ // Retrieve the 'self' address book entry for use in the auto-permissions link
+
+ $role = get_pconfig(local_channel(),'system','permissions_role');
+
+ $abk = q("select abook_id from abook where abook_channel = %d and abook_self = 1 limit 1",
+ intval(local_channel())
+ );
+ if($abk)
+ $abook_self_id = $abk[0]['abook_id'];
+
+ $x = q("select count(*) as total from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0 ",
+ dbesc($channel['channel_hash'])
+ );
+
+ $hublocs = (($x && $x[0]['total'] > 1) ? true : false);
+
+ $tabs = array(
+ array(
+ 'label' => t('Account settings'),
+ 'url' => z_root().'/settings/account',
+ 'selected' => ((argv(1) === 'account') ? 'active' : ''),
+ ),
+
+ array(
+ 'label' => t('Channel settings'),
+ 'url' => z_root().'/settings/channel',
+ 'selected' => ((argv(1) === 'channel') ? 'active' : ''),
+ ),
+
+ );
+
+ if(get_account_techlevel() > 0 && get_features()) {
+ $tabs[] = array(
+ 'label' => t('Additional features'),
+ 'url' => z_root().'/settings/features',
+ 'selected' => ((argv(1) === 'features') ? 'active' : ''),
+ );
+ }
+
+ $tabs[] = array(
+ 'label' => t('Feature/Addon settings'),
+ 'url' => z_root().'/settings/featured',
+ 'selected' => ((argv(1) === 'featured') ? 'active' : ''),
+ );
+
+ $tabs[] = array(
+ 'label' => t('Display settings'),
+ 'url' => z_root().'/settings/display',
+ 'selected' => ((argv(1) === 'display') ? 'active' : ''),
+ );
+
+ if($hublocs) {
+ $tabs[] = array(
+ 'label' => t('Manage locations'),
+ 'url' => z_root() . '/locs',
+ 'selected' => ((argv(1) === 'locs') ? 'active' : ''),
+ );
+ }
+
+ $tabs[] = array(
+ 'label' => t('Export channel'),
+ 'url' => z_root() . '/uexport',
+ 'selected' => ''
+ );
+
+ $tabs[] = array(
+ 'label' => t('Connected apps'),
+ 'url' => z_root() . '/settings/oauth',
+ 'selected' => ((argv(1) === 'oauth') ? 'active' : ''),
+ );
+
+ if(get_account_techlevel() > 2) {
+ $tabs[] = array(
+ 'label' => t('Guest Access Tokens'),
+ 'url' => z_root() . '/settings/tokens',
+ 'selected' => ((argv(1) === 'tokens') ? 'active' : ''),
+ );
+ }
+
+ if(feature_enabled(local_channel(),'permcats')) {
+ $tabs[] = array(
+ 'label' => t('Permission Groups'),
+ 'url' => z_root() . '/settings/permcats',
+ 'selected' => ((argv(1) === 'permcats') ? 'active' : ''),
+ );
+ }
+
+
+ if($role === false || $role === 'custom') {
+ $tabs[] = array(
+ 'label' => t('Connection Default Permissions'),
+ 'url' => z_root() . '/connedit/' . $abook_self_id,
+ 'selected' => ''
+ );
+ }
+
+ if(feature_enabled(local_channel(),'premium_channel')) {
+ $tabs[] = array(
+ 'label' => t('Premium Channel Settings'),
+ 'url' => z_root() . '/connect/' . $channel['channel_address'],
+ 'selected' => ''
+ );
+ }
+
+ if(feature_enabled(local_channel(),'channel_sources')) {
+ $tabs[] = array(
+ 'label' => t('Channel Sources'),
+ 'url' => z_root() . '/sources',
+ 'selected' => ''
+ );
+ }
+
+ $tabtpl = get_markup_template("generic_links_widget.tpl");
+ return replace_macros($tabtpl, array(
+ '$title' => t('Settings'),
+ '$class' => 'settings-widget',
+ '$items' => $tabs,
+ ));
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Widget/Shortprofile.php b/Zotlabs/Widget/Shortprofile.php
new file mode 100644
index 000000000..9c2a46e75
--- /dev/null
+++ b/Zotlabs/Widget/Shortprofile.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Shortprofile {
+
+ function widget($arr) {
+
+ if(! \App::$profile['profile_uid'])
+ return;
+
+ $block = observer_prohibited();
+
+ return profile_sidebar(\App::$profile, $block, true, true);
+ }
+
+}
+
diff --git a/Zotlabs/Widget/Sitesearch.php b/Zotlabs/Widget/Sitesearch.php
new file mode 100644
index 000000000..b3a25d76a
--- /dev/null
+++ b/Zotlabs/Widget/Sitesearch.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Sitesearch {
+
+ function widget($arr) {
+
+ $search = ((x($_GET,'search')) ? $_GET['search'] : '');
+
+ $srchurl = \App::$query_string;
+
+ $srchurl = rtrim(preg_replace('/search\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $srchurl = rtrim(preg_replace('/submit\=[^\&].*?(\&|$)/is','',$srchurl),'&');
+ $srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
+
+
+ $hasq = ((strpos($srchurl,'?') !== false) ? true : false);
+ $hasamp = ((strpos($srchurl,'&') !== false) ? true : false);
+
+ if(($hasamp) && (! $hasq))
+ $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
+
+ $o = '';
+
+ $saved = array();
+
+ $tpl = get_markup_template("sitesearch.tpl");
+ $o = replace_macros($tpl, array(
+ '$title' => t('Search'),
+ '$searchbox' => searchbox($search, 'netsearch-box', $srchurl . (($hasq) ? '' : '?f='), false),
+ '$saved' => $saved,
+ ));
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Suggestedchats.php b/Zotlabs/Widget/Suggestedchats.php
new file mode 100644
index 000000000..7df42944d
--- /dev/null
+++ b/Zotlabs/Widget/Suggestedchats.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Suggestedchats {
+
+ function widget($arr) {
+
+ if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
+ return '';
+
+ // There are reports that this tool does not ever remove chatrooms on dead sites,
+ // and also will happily link to private chats which you cannot enter.
+ // For those reasons, it will be disabled until somebody decides it's worth
+ // fixing and comes up with a plan for doing so.
+
+ return '';
+
+ // probably should restrict this to your friends, but then the widget will only work
+ // if you are logged in locally.
+
+ $h = get_observer_hash();
+ if(! $h)
+ return;
+ $r = q("select xchat_url, xchat_desc, count(xchat_xchan) as total from xchat group by xchat_url, xchat_desc order by total desc, xchat_desc limit 24");
+ if($r) {
+ for($x = 0; $x < count($r); $x ++) {
+ $r[$x]['xchat_url'] = zid($r[$x]['xchat_url']);
+ }
+ }
+ return replace_macros(get_markup_template('bookmarkedchats.tpl'),array(
+ '$header' => t('Suggested Chatrooms'),
+ '$rooms' => $r
+ ));
+ }
+}
+
diff --git a/Zotlabs/Widget/Suggestions.php b/Zotlabs/Widget/Suggestions.php
new file mode 100644
index 000000000..5fb3d3e8b
--- /dev/null
+++ b/Zotlabs/Widget/Suggestions.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/socgraph.php');
+
+
+class Suggestions {
+
+ function widget($arr) {
+
+ if((! local_channel()) || (! feature_enabled(local_channel(),'suggest')))
+ return '';
+
+
+ $r = suggestion_query(local_channel(),get_observer_hash(),0,20);
+
+ if(! $r) {
+ return;
+ }
+
+ $arr = array();
+
+ // Get two random entries from the top 20 returned.
+ // We'll grab the first one and the one immediately following.
+ // This will throw some entropy intot he situation so you won't
+ // be looking at the same two mug shots every time the widget runs
+
+ $index = ((count($r) > 2) ? mt_rand(0,count($r) - 2) : 0);
+
+ for($x = $index; $x <= ($index+1); $x ++) {
+ $rr = $r[$x];
+ if(! $rr['xchan_url'])
+ break;
+
+ $connlnk = z_root() . '/follow/?url=' . $rr['xchan_addr'];
+
+ $arr[] = array(
+ 'url' => chanlink_url($rr['xchan_url']),
+ 'profile' => $rr['xchan_url'],
+ 'name' => $rr['xchan_name'],
+ 'photo' => $rr['xchan_photo_m'],
+ 'ignlnk' => z_root() . '/directory?ignore=' . $rr['xchan_hash'],
+ 'conntxt' => t('Connect'),
+ 'connlnk' => $connlnk,
+ 'ignore' => t('Ignore/Hide')
+ );
+ }
+
+ $o = replace_macros(get_markup_template('suggest_widget.tpl'),array(
+ '$title' => t('Suggestions'),
+ '$more' => t('See more...'),
+ '$entries' => $arr
+ ));
+
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Tagcloud.php b/Zotlabs/Widget/Tagcloud.php
new file mode 100644
index 000000000..cf7a4932e
--- /dev/null
+++ b/Zotlabs/Widget/Tagcloud.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+// @FIXME The problem with this widget is that we don't have a search function for webpages
+// that we can send the links to. Then we should also provide an option to search webpages
+// and conversations.
+
+class Tagcloud {
+
+ function widget($args) {
+
+ $o = '';
+ $uid = \App::$profile_uid;
+ $count = ((x($args,'count')) ? intval($args['count']) : 24);
+ $flags = 0;
+ $type = TERM_CATEGORY;
+
+ // @FIXME there exists no $authors variable
+ $r = tagadelic($uid, $count, $authors, $owner, $flags, ITEM_TYPE_WEBPAGE, $type);
+
+ // @FIXME this should use a template
+
+ if($r) {
+ $o = '<div class="tagblock widget"><h3>' . t('Categories') . '</h3><div class="tags" align="center">';
+ foreach($r as $rv) {
+ $o .= '<span class="tag' . $rv[2] . '">' . $rv[0] .' </span> ' . "\r\n";
+ }
+ $o .= '</div></div>';
+ }
+ return $o;
+ }
+}
diff --git a/Zotlabs/Widget/Tagcloud_wall.php b/Zotlabs/Widget/Tagcloud_wall.php
new file mode 100644
index 000000000..7cff6ce09
--- /dev/null
+++ b/Zotlabs/Widget/Tagcloud_wall.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Tagcloud_wall {
+
+ function widget($arr) {
+
+ if((! \App::$profile['profile_uid']) || (! \App::$profile['channel_hash']))
+ return '';
+ if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_stream'))
+ return '';
+
+ $limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 50);
+ if(feature_enabled(\App::$profile['profile_uid'], 'tagadelic'))
+ return wtagblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash'], 'wall');
+
+ return '';
+ }
+}
diff --git a/Zotlabs/Widget/Tasklist.php b/Zotlabs/Widget/Tasklist.php
new file mode 100644
index 000000000..78dc27def
--- /dev/null
+++ b/Zotlabs/Widget/Tasklist.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+require_once('include/event.php');
+
+class Tasklist {
+
+ function widget($arr) {
+
+ if (! local_channel())
+ return;
+
+ $o .= '<script>var tasksShowAll = 0; $(document).ready(function() { tasksFetch(); $("#tasklist-new-form").submit(function(event) { event.preventDefault(); $.post( "tasks/new", $("#tasklist-new-form").serialize(), function(data) { tasksFetch(); $("#tasklist-new-summary").val(""); } ); return false; } )});</script>';
+ $o .= '<script>function taskComplete(id) { $.post("tasks/complete/"+id, function(data) { tasksFetch();}); }
+ function tasksFetch() {
+ $.get("tasks/fetch" + ((tasksShowAll) ? "/all" : ""), function(data) {
+ $(".tasklist-tasks").html(data.html);
+ });
+ }
+ </script>';
+
+ $o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks">';
+ $o .= '</div><form id="tasklist-new-form" action="" ><input class="form-control" id="tasklist-new-summary" type="text" name="summary" value="" /></form>';
+ $o .= '</div>';
+ return $o;
+
+ }
+}
+
diff --git a/Zotlabs/Widget/Vcard.php b/Zotlabs/Widget/Vcard.php
new file mode 100644
index 000000000..cab05dfdd
--- /dev/null
+++ b/Zotlabs/Widget/Vcard.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Vcard {
+
+ function widget($arr) {
+ return vcard_from_xchan('', \App::get_observer());
+ }
+
+}
+
diff --git a/Zotlabs/Widget/Website_portation_tools.php b/Zotlabs/Widget/Website_portation_tools.php
new file mode 100644
index 000000000..1cf3bb78a
--- /dev/null
+++ b/Zotlabs/Widget/Website_portation_tools.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Website_portation_tools {
+
+ function widget($arr) {
+
+ // mod menu doesn't load a profile. For any modules which load a profile, check it.
+ // otherwise local_channel() is sufficient for permissions.
+
+ if(\App::$profile['profile_uid'])
+ if((\App::$profile['profile_uid'] != local_channel()) && (! \App::$is_sys))
+ return '';
+
+ if(! local_channel())
+ return '';
+
+ return website_portation_tools();
+ }
+}
diff --git a/Zotlabs/Widget/Wiki_list.php b/Zotlabs/Widget/Wiki_list.php
new file mode 100644
index 000000000..62f32dbf0
--- /dev/null
+++ b/Zotlabs/Widget/Wiki_list.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Wiki_list {
+
+ function widget($arr) {
+
+ $channel = channelx_by_n(\App::$profile_uid);
+
+ $wikis = \Zotlabs\Lib\NativeWiki::listwikis($channel,get_observer_hash());
+
+ if($wikis) {
+ return replace_macros(get_markup_template('wikilist_widget.tpl'), array(
+ '$header' => t('Wiki List'),
+ '$channel' => $channel['channel_address'],
+ '$wikis' => $wikis['wikis']
+ ));
+ }
+ return '';
+ }
+
+}
diff --git a/Zotlabs/Widget/Wiki_page_history.php b/Zotlabs/Widget/Wiki_page_history.php
new file mode 100644
index 000000000..dcec9a037
--- /dev/null
+++ b/Zotlabs/Widget/Wiki_page_history.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Wiki_page_history {
+
+ function widget($arr) {
+
+ $pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
+ $resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
+
+ $pageHistory = \Zotlabs\Lib\NativeWikiPage::page_history([
+ 'channel_id' => \App::$profile_uid,
+ 'observer_hash' => get_observer_hash(),
+ 'resource_id' => $resource_id,
+ 'pageUrlName' => $pageUrlName
+ ]);
+
+ return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
+ '$pageHistory' => $pageHistory['history'],
+ '$permsWrite' => $arr['permsWrite'],
+ '$name_lbl' => t('Name'),
+ '$msg_label' => t('Message','wiki_history')
+ ));
+
+ }
+}
diff --git a/Zotlabs/Widget/Wiki_pages.php b/Zotlabs/Widget/Wiki_pages.php
new file mode 100644
index 000000000..f992b3f93
--- /dev/null
+++ b/Zotlabs/Widget/Wiki_pages.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+
+class Wiki_pages {
+
+ function widget($arr) {
+
+ $channelname = ((array_key_exists('channel',$arr)) ? $arr['channel'] : '');
+ $c = channelx_by_nick($channelname);
+
+ if(! $c)
+ $c = \App::get_channel();
+
+ if(! $c)
+ return '';
+
+ $wikiname = '';
+ if(array_key_exists('refresh', $arr)) {
+ $not_refresh = (($arr['refresh']=== true) ? false : true);
+ }
+ else {
+ $not_refresh = true;
+ }
+
+ $pages = array();
+ if(! array_key_exists('resource_id', $arr)) {
+ $hide = true;
+ }
+ else {
+ $p = \Zotlabs\Lib\NativeWikiPage::page_list($c['channel_id'],get_observer_hash(),$arr['resource_id']);
+
+ if($p['pages']) {
+ $pages = $p['pages'];
+ $w = $p['wiki'];
+ // Wiki item record is $w['wiki']
+ $wikiname = $w['urlName'];
+ if (!$wikiname) {
+ $wikiname = '';
+ }
+ }
+ }
+
+
+ $can_create = perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'write_wiki');
+
+ $can_delete = ((local_channel() && (local_channel() == \App::$profile['uid'])) ? true : false);
+
+ return replace_macros(get_markup_template('wiki_page_list.tpl'), array(
+ '$hide' => $hide,
+ '$resource_id' => $arr['resource_id'],
+ '$not_refresh' => $not_refresh,
+ '$header' => t('Wiki Pages'),
+ '$channel' => $channelname,
+ '$wikiname' => $wikiname,
+ '$pages' => $pages,
+ '$canadd' => $can_create,
+ '$candel' => $can_delete,
+ '$addnew' => t('Add new page'),
+ '$pageName' => array('pageName', t('Page name')),
+ ));
+ }
+}
+
+
diff --git a/Zotlabs/Widget/Zcard.php b/Zotlabs/Widget/Zcard.php
new file mode 100644
index 000000000..12e53eaab
--- /dev/null
+++ b/Zotlabs/Widget/Zcard.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Zotlabs\Widget;
+
+class Zcard {
+
+ function widget($args) {
+ $channel = channelx_by_n(\App::$profile_uid);
+ return get_zcard($channel,get_observer_hash(),array('width' => 875));
+ }
+}