From 0865d0ef51363764e3a40ba1f146b0cbae70f299 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 15 Apr 2016 22:36:07 -0700 Subject: Convert Channel to new module --- Zotlabs/Module/Channel.php | 364 ++++++++++++++++++++++++++++++++++++++ Zotlabs/Module/Update_channel.php | 70 ++++++++ 2 files changed, 434 insertions(+) create mode 100644 Zotlabs/Module/Channel.php create mode 100644 Zotlabs/Module/Update_channel.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php new file mode 100644 index 000000000..cae561266 --- /dev/null +++ b/Zotlabs/Module/Channel.php @@ -0,0 +1,364 @@ + 1) + $which = argv(1); + if(! $which) { + if(local_channel()) { + $channel = \App::get_channel(); + if($channel && $channel['channel_address']) + $which = $channel['channel_address']; + } + } + if(! $which) { + notice( t('You must be logged in to see this page.') . EOL ); + return; + } + + $profile = 0; + $channel = \App::get_channel(); + + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + \App::$page['htmlhead'] .= '' . "\r\n" ; + \App::$page['htmlhead'] .= '' . "\r\n" ; + +// Not yet ready for prime time +// \App::$page['htmlhead'] .= '' . "\r\n" ; +// \App::$page['htmlhead'] .= '' . "\r\n" ; + + // Run profile_load() here to make sure the theme is set before + // we start loading content + + profile_load($a,$which,$profile); + +} + +function get($update = 0, $load = false) { + + + if($load) + $_SESSION['loadtime'] = datetime_convert(); + + $checkjs = new \Zotlabs\Web\CheckJS(); + + $category = $datequery = $datequery2 = ''; + + $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); + + $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); + $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); + + if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { + return login(); + } + + $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : ''); + $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : ''); + + $groups = array(); + + $o = ''; + + if($update) { + // Ensure we've got a profile owner if updating. + \App::$profile['profile_uid'] = \App::$profile_uid = $update; + } + else { + if(\App::$profile['profile_uid'] == local_channel()) { + nav_set_selected('home'); + } + } + + $is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false); + + $channel = \App::get_channel(); + $observer = \App::get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash); + + if(! $perms['view_stream']) { + // We may want to make the target of this redirect configurable + if($perms['view_profile']) { + notice( t('Insufficient permissions. Request redirected to profile page.') . EOL); + goaway (z_root() . "/profile/" . \App::$profile['channel_address']); + } + notice( t('Permission denied.') . EOL); + return; + } + + + if(! $update) { + + $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']); + + $o .= common_friends_visitor_widget(\App::$profile['profile_uid']); + + if($channel && $is_owner) { + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + } + else + $channel_acl = array(); + + + if($perms['post_wall']) { + + $x = array( + 'is_owner' => $is_owner, + 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), + 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), + 'nickname' => \App::$profile['channel_address'], + 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')) : ''), + 'showacl' => (($is_owner) ? 'yes' : ''), + 'bang' => '', + 'visitor' => (($is_owner || $observer) ? true : false), + 'profile_uid' => \App::$profile['profile_uid'], + 'editor_autocomplete' => true, + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + + $o .= status_editor($a,$x); + } + + } + + + /** + * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups + */ + + $item_normal = item_normal(); + $sql_extra = item_permissions_sql(\App::$profile['profile_uid']); + + if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid)) + $page_mode = 'list'; + else + $page_mode = 'client'; + + $abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " "; + + $simple_update = (($update) ? " AND item_unseen = 1 " : ''); + + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + + if($update && $_SESSION['loadtime']) + $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; + if($load) + $simple_update = ''; + + if(($update) && (! $load)) { + + if ($mid) { + $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal + AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1", + dbesc($mid . '%'), + intval(\App::$profile['profile_uid']) + ); + } else { + $r = q("SELECT distinct parent AS `item_id`, created from item + left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) + WHERE uid = %d $item_normal + AND item_wall = 1 $simple_update + AND (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra + ORDER BY created DESC", + intval(\App::$profile['profile_uid']) + ); + $_SESSION['loadtime'] = datetime_convert(); + } + + } + else { + + if(x($category)) { + $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY)); + } + if(x($hashtags)) { + $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); + } + + if($datequery) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); + } + if($datequery2) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); + } + + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + + if($load || ($checkjs->disabled())) { + if ($mid) { + $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal + AND item_wall = 1 $sql_extra limit 1", + dbesc($mid), + intval(\App::$profile['profile_uid']) + ); + if (! $r) { + notice( t('Permission denied.') . EOL); + } + + } else { + $r = q("SELECT distinct id AS item_id, created FROM item + left join abook on item.author_xchan = abook.abook_xchan + WHERE uid = %d $item_normal + AND item_wall = 1 and item_thread_top = 1 + AND (abook_blocked = 0 or abook.abook_flags is null) + $sql_extra $sql_extra2 + ORDER BY created DESC $pager_sql ", + intval(\App::$profile['profile_uid']) + ); + } + } + else { + $r = array(); + } + } + + if($r) { + + $parents_str = ids_to_querystr($r,'item_id'); + + $items = q("SELECT `item`.*, `item`.`id` AS `item_id` + FROM `item` + WHERE `item`.`uid` = %d $item_normal + AND `item`.`parent` IN ( %s ) + $sql_extra ", + intval(\App::$profile['profile_uid']), + dbesc($parents_str) + ); + + xchan_query($items); + $items = fetch_post_tags($items, true); + $items = conv_sort($items,'created'); + + if ($load && $mid && (! count($items))) { + // This will happen if we don't have sufficient permissions + // to view the parent item (or the item itself if it is toplevel) + notice( t('Permission denied.') . EOL); + } + + } else { + $items = array(); + } + + if((! $update) && (! $load)) { + + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, + // because browser prefetching might change it on us. We have to deliver it with the page. + + $maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height'); + if(! $maxheight) + $maxheight = 400; + + $o .= '
' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'channel', + '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '0', + '$cmax' => '0', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$nouveau' => '0', + '$wall' => '1', + '$fh' => '0', + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$search' => '', + '$order' => '', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$file' => '', + '$cats' => (($category) ? $category : ''), + '$tags' => (($hashtags) ? $hashtags : ''), + '$mid' => $mid, + '$verb' => '', + '$dend' => $datequery, + '$dbegin' => $datequery2 + )); + + + } + + $update_unseen = ''; + + if($page_mode === 'list') { + + /** + * in "list mode", only mark the parent item and any like activities as "seen". + * We won't distinguish between comment likes and post likes. The important thing + * is that the number of unseen comments will be accurate. The SQL to separate the + * comment likes could also get somewhat hairy. + */ + + if($parents_str) { + $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )"; + $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) "; + } + } + else { + if($parents_str) { + $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )"; + } + } + + if($is_owner && $update_unseen) { + $r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen", + intval(local_channel()) + ); + } + + + if($checkjs->disabled()) { + $o .= conversation($a,$items,'channel',$update,'traditional'); + } else { + $o .= conversation($a,$items,'channel',$update,$page_mode); + } + + if((! $update) || ($checkjs->disabled())) { + $o .= alt_pager($a,count($items)); + if ($mid && $items[0]['title']) + \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; + } + + if($mid) + $o .= '
'; + + return $o; +} + + +} \ No newline at end of file diff --git a/Zotlabs/Module/Update_channel.php b/Zotlabs/Module/Update_channel.php new file mode 100644 index 000000000..b1b2d5103 --- /dev/null +++ b/Zotlabs/Module/Update_channel.php @@ -0,0 +1,70 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + + header("Content-type: text/html"); + echo "\r\n"; + + /** + * We can remove this hack once Internet Explorer recognises HTML5 natively + */ + + echo (($_GET['msie'] == 1) ? '
' : '
'); + + /** + * + * Grab the page inner contents by calling the content function from the profile module directly, + * but move any image src attributes to another attribute name. This is because + * some browsers will prefetch all the images for the page even if we don't need them. + * The only ones we need to fetch are those for new page additions, which we'll discover + * on the client side and then swap the image back. + * + */ + + $mod = new Channel(); + + $text = $mod->get($profile_uid,$load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } +*/ + + /** + * reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well + */ + + echo str_replace("\t",' ',$text); + echo (($_GET['msie'] == 1) ? '
' : ''); + echo "\r\n"; + killme(); + +} +} \ No newline at end of file -- cgit v1.2.3 From 966773cdbba80103e93290ccf01d0c91df5a000e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 17 Apr 2016 19:55:36 -0700 Subject: pull in the new object router and a few selected samples for the new controller layout --- Zotlabs/Module/Admin.php | 1782 +++++++++++++++++++++++++++++++++++++++++++ Zotlabs/Module/Lockview.php | 121 +++ 2 files changed, 1903 insertions(+) create mode 100644 Zotlabs/Module/Admin.php create mode 100644 Zotlabs/Module/Lockview.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php new file mode 100644 index 000000000..8cc08fd13 --- /dev/null +++ b/Zotlabs/Module/Admin.php @@ -0,0 +1,1782 @@ + 1) { + switch (argv(1)) { + case 'site': + $this->admin_page_site_post($a); + break; + case 'users': + $this->admin_page_users_post($a); + break; + case 'channels': + $this->admin_page_channels_post($a); + break; + case 'plugins': + if (argc() > 2 && + is_file("addon/" . argv(2) . "/" . argv(2) . ".php")){ + @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); + if(function_exists(argv(2).'_plugin_admin_post')) { + $func = argv(2) . '_plugin_admin_post'; + $func($a); + } + } + goaway(z_root() . '/admin/plugins/' . argv(2) ); + break; + case 'themes': + $theme = argv(2); + if (is_file("view/theme/$theme/php/config.php")){ + require_once("view/theme/$theme/php/config.php"); + // fixme add parent theme if derived + if (function_exists("theme_admin_post")){ + theme_admin_post($a); + } + } + info(t('Theme settings updated.')); + if(is_ajax()) return; + + goaway(z_root() . '/admin/themes/' . $theme ); + break; + case 'logs': + $this->admin_page_logs_post($a); + break; + case 'hubloc': + $this->admin_page_hubloc_post($a); + break; + case 'security': + $this->admin_page_security_post($a); + break; + case 'features': + $this->admin_page_features_post($a); + break; + case 'dbsync': + $this->admin_page_dbsync_post($a); + break; + case 'profs': + $this->admin_page_profs_post($a); + break; + } + } + + goaway(z_root() . '/admin' ); + } + + /** + * @param App &$a + * @return string + */ + function get() { + + logger('admin_content', LOGGER_DEBUG); + + if(! is_site_admin()) { + return login(false); + } + + + /* + * Page content + */ + $o = ''; + + // urls + if (argc() > 1){ + switch (argv(1)) { + case 'site': + $o = $this->admin_page_site($a); + break; + case 'users': + $o = $this->admin_page_users($a); + break; + case 'channels': + $o = $this->admin_page_channels($a); + break; + case 'plugins': + $o = $this->admin_page_plugins($a); + break; + case 'themes': + $o = $this->admin_page_themes($a); + break; + // case 'hubloc': + // $o = $this->admin_page_hubloc($a); + // break; + case 'security': + $o = $this->admin_page_security($a); + break; + case 'features': + $o = $this->admin_page_features($a); + break; + case 'logs': + $o = $this->admin_page_logs($a); + break; + case 'dbsync': + $o = $this->admin_page_dbsync($a); + break; + case 'profs': + $o = $this->admin_page_profs($a); + break; + case 'queue': + $o = $this->admin_page_queue($a); + break; + default: + notice( t('Item not found.') ); + } + } else { + $o = $this->admin_page_summary($a); + } + + if(is_ajax()) { + echo $o; + killme(); + return ''; + } else { + return $o; + } + } + + + /** + * @brief Returns content for Admin Summary Page. + * + * @param App &$a + * @return string HTML from parsed admin_summary.tpl + */ + function admin_page_summary(&$a) { + + // list total user accounts, expirations etc. + $accounts = array(); + $r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires != '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account", + db_utcnow(), + db_utcnow(), + dbesc(NULL_DATE), + intval(ACCOUNT_BLOCKED) + ); + if ($r) { + $accounts['total'] = array('label' => t('# Accounts'), 'val' => $r[0]['total']); + $accounts['blocked'] = array('label' => t('# blocked accounts'), 'val' => $r[0]['blocked']); + $accounts['expired'] = array('label' => t('# expired accounts'), 'val' => $r[0]['expired']); + $accounts['expiring'] = array('label' => t('# expiring accounts'), 'val' => $r[0]['expiring']); + } + + // pending registrations + $r = q("SELECT COUNT(id) AS `count` FROM `register` WHERE `uid` != '0'"); + $pending = $r[0]['count']; + + // available channels, primary and clones + $channels = array(); + $r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0"); + if ($r) { + $channels['total'] = array('label' => t('# Channels'), 'val' => $r[0]['total']); + $channels['main'] = array('label' => t('# primary'), 'val' => $r[0]['main']); + $channels['clones'] = array('label' => t('# clones'), 'val' => $r[0]['clones']); + } + + // We can do better, but this is a quick queue status + $r = q("SELECT COUNT(outq_delivered) AS total FROM outq WHERE outq_delivered = 0"); + $queue = (($r) ? $r[0]['total'] : 0); + $queues = array( 'label' => t('Message queues'), 'queue' => $queue ); + + // If no plugins active return 0, otherwise list of plugin names + $plugins = (count(\App::$plugins) == 0) ? count(\App::$plugins) : \App::$plugins; + + // Could be extended to provide also other alerts to the admin + $alertmsg = ''; + // annoy admin about upcoming unsupported PHP version + if (version_compare(PHP_VERSION, '5.4', '<')) { + $alertmsg = 'Your PHP version ' . PHP_VERSION . ' will not be supported with the next major release of $Projectname. You are strongly urged to upgrade to a current version.' + . '
PHP 5.3 has reached its End of Life (EOL) in August 2014.' + . ' A list about current PHP versions can be found here.'; + } + + $t = get_markup_template('admin_summary.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Summary'), + '$adminalertmsg' => $alertmsg, + '$queues' => $queues, + '$accounts' => array( t('Registered accounts'), $accounts), + '$pending' => array( t('Pending registrations'), $pending), + '$channels' => array( t('Registered channels'), $channels), + '$plugins' => array( t('Active plugins'), $plugins ), + '$version' => array( t('Version'), RED_VERSION), + '$build' => get_config('system', 'db_version') + )); + } + + + /** + * @brief POST handler for Admin Site Page. + * + * @param App &$a + */ + function admin_page_site_post(&$a){ + if (!x($_POST, 'page_site')){ + return; + } + + check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); + + $sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : ''); + $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false); + $admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false); + $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : ''); + $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : ''); + $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); + // $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); + $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); + + $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0); + + $access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0); + $invite_only = ((x($_POST,'invite_only')) ? True : False); + $abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0); + + $register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : ''); + $frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : ''); + $mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0); + $directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : ''); + $allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : ''); + $allowed_email = ((x($_POST,'allowed_email')) ? notags(trim($_POST['allowed_email'])) : ''); + $not_allowed_email = ((x($_POST,'not_allowed_email')) ? notags(trim($_POST['not_allowed_email'])) : ''); + $force_publish = ((x($_POST,'publish_all')) ? True : False); + $disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True); + $login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False); + $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : ''); + $no_community_page = !((x($_POST,'no_community_page')) ? True : False); + $default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0); + + $verifyssl = ((x($_POST,'verifyssl')) ? True : False); + $proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : ''); + $proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : ''); + $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60); + $delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0); + $delivery_batch_count = ((x($_POST,'delivery_batch_count') && $_POST['delivery_batch_count'] > 0)? intval(trim($_POST['delivery_batch_count'])) : 1); + $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0); + $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); + $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); + $verify_email = ((x($_POST,'verify_email')) ? 1 : 0); + + set_config('system', 'feed_contacts', $feed_contacts); + set_config('system', 'delivery_interval', $delivery_interval); + set_config('system', 'delivery_batch_count', $delivery_batch_count); + set_config('system', 'poll_interval', $poll_interval); + set_config('system', 'maxloadavg', $maxloadavg); + set_config('system', 'frontpage', $frontpage); + set_config('system', 'mirror_frontpage', $mirror_frontpage); + set_config('system', 'sitename', $sitename); + set_config('system', 'login_on_homepage', $login_on_homepage); + set_config('system', 'verify_email', $verify_email); + set_config('system', 'default_expire_days', $default_expire_days); + + if($directory_server) + set_config('system','directory_server',$directory_server); + + if ($banner == '') { + del_config('system', 'banner'); + } else { + set_config('system', 'banner', $banner); + } + + if ($admininfo == ''){ + del_config('system', 'admininfo'); + } else { + require_once('include/text.php'); + linkify_tags($a, $admininfo, local_channel()); + set_config('system', 'admininfo', $admininfo); + } + set_config('system', 'language', $language); + set_config('system', 'theme', $theme); + if ( $theme_mobile === '---' ) { + del_config('system', 'mobile_theme'); + } else { + set_config('system', 'mobile_theme', $theme_mobile); + } + // set_config('system','site_channel', $site_channel); + set_config('system','maximagesize', $maximagesize); + + set_config('system','register_policy', $register_policy); + set_config('system','invitation_only', $invite_only); + set_config('system','access_policy', $access_policy); + set_config('system','account_abandon_days', $abandon_days); + set_config('system','register_text', $register_text); + set_config('system','allowed_sites', $allowed_sites); + set_config('system','allowed_email', $allowed_email); + set_config('system','not_allowed_email', $not_allowed_email); + set_config('system','publish_all', $force_publish); + set_config('system','disable_discover_tab', $disable_discover_tab); + if ($global_directory == '') { + del_config('system', 'directory_submit_url'); + } else { + set_config('system', 'directory_submit_url', $global_directory); + } + + set_config('system','no_community_page', $no_community_page); + set_config('system','no_utf', $no_utf); + set_config('system','verifyssl', $verifyssl); + set_config('system','proxyuser', $proxyuser); + set_config('system','proxy', $proxy); + set_config('system','curl_timeout', $timeout); + + info( t('Site settings updated.') . EOL); + goaway(z_root() . '/admin/site' ); + } + + /** + * @brief Admin page site. + * + * @param App $a + * @return string + */ + function admin_page_site(&$a) { + + /* Installed langs */ + $lang_choices = array(); + $langs = glob('view/*/hstrings.php'); + + if(is_array($langs) && count($langs)) { + if(! in_array('view/en/hstrings.php',$langs)) + $langs[] = 'view/en/'; + asort($langs); + foreach($langs as $l) { + $t = explode("/",$l); + $lang_choices[$t[1]] = $t[1]; + } + } + + /* Installed themes */ + $theme_choices_mobile["---"] = t("Default"); + $theme_choices = array(); + $files = glob('view/theme/*'); + if($files) { + foreach($files as $file) { + $vars = ''; + $f = basename($file); + if (file_exists($file . '/library')) + continue; + if (file_exists($file . '/mobile')) + $vars = t('mobile'); + if (file_exists($file . '/experimental')) + $vars .= t('experimental'); + if (file_exists($file . '/unsupported')) + $vars .= t('unsupported'); + if ($vars) { + $theme_choices[$f] = $f . ' (' . $vars . ')'; + $theme_choices_mobile[$f] = $f . ' (' . $vars . ')'; + } + else { + $theme_choices[$f] = $f; + $theme_choices_mobile[$f] = $f; + } + } + } + + $dir_choices = null; + $dirmode = get_config('system','directory_mode'); + $realm = get_directory_realm(); + + // directory server should not be set or settable unless we are a directory client + + if($dirmode == DIRECTORY_MODE_NORMAL) { + $x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s'", + intval(DIRECTORY_MODE_SECONDARY), + intval(DIRECTORY_MODE_PRIMARY), + dbesc($realm) + ); + if($x) { + $dir_choices = array(); + foreach($x as $xx) { + $dir_choices[$xx['site_url']] = $xx['site_url']; + } + } + } + + /* Banner */ + + $banner = get_config('system', 'banner'); + if($banner === false) + $banner = get_config('system','sitename'); + + $banner = htmlspecialchars($banner); + + /* Admin Info */ + $admininfo = get_config('system', 'admininfo'); + + /* Register policy */ + $register_choices = Array( + REGISTER_CLOSED => t("No"), + REGISTER_APPROVE => t("Yes - with approval"), + REGISTER_OPEN => t("Yes") + ); + + /* Acess policy */ + $access_choices = Array( + ACCESS_PRIVATE => t("My site is not a public server"), + ACCESS_PAID => t("My site has paid access only"), + ACCESS_FREE => t("My site has free access only"), + ACCESS_TIERED => t("My site offers free accounts with optional paid upgrades") + ); + + // $ssl_choices = array( + // SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"), + // SSL_POLICY_FULL => t("Force all links to use SSL") + // ); + + $discover_tab = get_config('system','disable_discover_tab'); + // $disable public streams by default + if($discover_tab === false) + $discover_tab = 1; + // now invert the logic for the setting. + $discover_tab = (1 - $discover_tab); + + + $homelogin = get_config('system','login_on_homepage'); + + $t = get_markup_template("admin_site.tpl"); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Site'), + '$submit' => t('Submit'), + '$registration' => t('Registration'), + '$upload' => t('File upload'), + '$corporate' => t('Policies'), + '$advanced' => t('Advanced'), + + '$baseurl' => z_root(), + // name, label, value, help string, extra data... + '$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''), + '$banner' => array('banner', t("Banner/Logo"), $banner, ""), + '$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")), + '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices), + '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - change theme settings"), $theme_choices), + '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), + // '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), + '$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')), + '$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), + '$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices), + '$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")), + '$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), "This is displayed on the public server site list.", $access_choices), + '$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), + '$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")), + '$mirror_frontpage' => array('mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')), + '$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')), + '$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")), + '$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")), + '$not_allowed_email' => array('not_allowed_email', t("Not allowed email domains"), get_config('system','not_allowed_email'), t("Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined.")), + '$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")), + '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), + '$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')), + '$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.")), + + '$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'), ""), + '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""), + '$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")), + '$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")), + '$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")), + '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), + '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), + '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), + '$form_security_token' => get_form_security_token("admin_site"), + )); + } + + function admin_page_hubloc_post(&$a){ + check_form_security_token_redirectOnErr('/admin/hubloc', 'admin_hubloc'); + require_once('include/zot.php'); + + //prepare for ping + + if ( $_POST['hublocid']) { + $hublocid = $_POST['hublocid']; + $arrhublocurl = q("SELECT hubloc_url FROM hubloc WHERE hubloc_id = %d ", + intval($hublocid) + ); + $hublocurl = $arrhublocurl[0]['hubloc_url'] . '/post'; + + //perform ping + $m = zot_build_packet(\App::get_channel(),'ping'); + $r = zot_zot($hublocurl,$m); + //handle results and set the hubloc flags in db to make results visible + $r2 = $r['body']; + $r3 = $r2['success']; + if ( $r3['success'] == True ){ + //set HUBLOC_OFFLINE to 0 + logger(' success = true ',LOGGER_DEBUG); + } else { + //set HUBLOC_OFFLINE to 1 + logger(' success = false ', LOGGER_DEBUG); + } + + //unfotunatly zping wont work, I guess return format is not correct + //require_once('mod/zping.php'); + //$r = zping_content($hublocurl); + //logger('zping answer: ' . $r, LOGGER_DEBUG); + + //in case of repair store new pub key for tested hubloc (all channel with this hubloc) in db + //after repair set hubloc flags to 0 + } + + goaway(z_root() . '/admin/hubloc' ); + } + + function trim_array_elems($arr) { + $narr = array(); + + if($arr && is_array($arr)) { + for($x = 0; $x < count($arr); $x ++) { + $y = trim($arr[$x]); + if($y) + $narr[] = $y; + } + } + return $narr; + } + + function admin_page_security_post(&$a){ + check_form_security_token_redirectOnErr('/admin/security', 'admin_security'); + + logger('post: ' . print_r($_POST,true)); + + $block_public = ((x($_POST,'block_public')) ? True : False); + set_config('system','block_public',$block_public); + + $ws = trim_array_elems(explode("\n",$_POST['whitelisted_sites'])); + set_config('system','whitelisted_sites',$ws); + + $bs = trim_array_elems(explode("\n",$_POST['blacklisted_sites'])); + set_config('system','blacklisted_sites',$bs); + + $wc = trim_array_elems(explode("\n",$_POST['whitelisted_channels'])); + set_config('system','whitelisted_channels',$wc); + + $bc = trim_array_elems(explode("\n",$_POST['blacklisted_channels'])); + set_config('system','blacklisted_channels',$bc); + + $embed_coop = ((x($_POST,'embed_coop')) ? True : False); + set_config('system','embed_coop',$embed_coop); + + $we = trim_array_elems(explode("\n",$_POST['embed_allow'])); + set_config('system','embed_allow',$we); + + $be = trim_array_elems(explode("\n",$_POST['embed_deny'])); + set_config('system','embed_deny',$be); + + goaway(z_root() . '/admin/security'); + } + + + + + function admin_page_features_post(&$a) { + + check_form_security_token_redirectOnErr('/admin/features', 'admin_manage_features'); + + logger('postvars: ' . print_r($_POST,true)); + + $arr = array(); + $features = get_features(false); + + foreach($features as $fname => $fdata) { + foreach(array_slice($fdata,1) as $f) { + $feature = $f[0]; + + if(array_key_exists('feature_' . $feature,$_POST)) + $val = intval($_POST['feature_' . $feature]); + else + $val = 0; + set_config('feature',$feature,$val); + + if(array_key_exists('featurelock_' . $feature,$_POST)) + set_config('feature_lock',$feature,$val); + else + del_config('feature_lock',$feature); + } + } + + goaway(z_root() . '/admin/features' ); + + } + + function admin_page_features(&$a) { + + if((argc() > 1) && (argv(1) === 'features')) { + $arr = array(); + $features = get_features(false); + + foreach($features as $fname => $fdata) { + $arr[$fname] = array(); + $arr[$fname][0] = $fdata[0]; + foreach(array_slice($fdata,1) as $f) { + + $set = get_config('feature',$f[0]); + if($set === false) + $set = $f[3]; + $arr[$fname][1][] = array( + array('feature_' .$f[0],$f[1],$set,$f[2],array(t('Off'),t('On'))), + array('featurelock_' .$f[0],sprintf( t('Lock feature %s'),$f[1]),(($f[4] !== false) ? 1 : 0),'',array(t('Off'),t('On'))) + ); + } + } + + $tpl = get_markup_template("admin_settings_features.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("admin_manage_features"), + '$title' => t('Manage Additional Features'), + '$features' => $arr, + '$submit' => t('Submit'), + )); + + return $o; + } + } + + + + + + function admin_page_hubloc(&$a) { + $hubloc = q("SELECT hubloc_id, hubloc_addr, hubloc_host, hubloc_status FROM hubloc"); + + if(! $hubloc){ + notice( t('No server found') . EOL); + goaway(z_root() . '/admin/hubloc'); + } + + $t = get_markup_template('admin_hubloc.tpl'); + return replace_macros($t, array( + '$hubloc' => $hubloc, + '$th_hubloc' => array(t('ID'), t('for channel'), t('on server'), t('Status')), + '$title' => t('Administration'), + '$page' => t('Server'), + '$queues' => $queues, + //'$accounts' => $accounts, /*$accounts is empty here*/ + '$pending' => array( t('Pending registrations'), $pending), + '$plugins' => array( t('Active plugins'), \App::$plugins ), + '$form_security_token' => get_form_security_token('admin_hubloc') + )); + } + + function admin_page_security(&$a) { + + $whitesites = get_config('system','whitelisted_sites'); + $whitesites_str = ((is_array($whitesites)) ? implode($whitesites,"\n") : ''); + + $blacksites = get_config('system','blacklisted_sites'); + $blacksites_str = ((is_array($blacksites)) ? implode($blacksites,"\n") : ''); + + + $whitechannels = get_config('system','whitelisted_channels'); + $whitechannels_str = ((is_array($whitechannels)) ? implode($whitechannels,"\n") : ''); + + $blackchannels = get_config('system','blacklisted_channels'); + $blackchannels_str = ((is_array($blackchannels)) ? implode($blackchannels,"\n") : ''); + + + $whiteembeds = get_config('system','embed_allow'); + $whiteembeds_str = ((is_array($whiteembeds)) ? implode($whiteembeds,"\n") : ''); + + $blackembeds = get_config('system','embed_deny'); + $blackembeds_str = ((is_array($blackembeds)) ? implode($blackembeds,"\n") : ''); + + $embed_coop = intval(get_config('system','embed_coop')); + + // wait to implement this until we have a co-op in place. + // if((! $whiteembeds) && (! $blackembeds) && (! $embed_coop)) + // $whiteembeds_str = "youtube.com\nyoutu.be\ntwitter.com\nvimeo.com\nsoundcloud.com\nwikipedia.com"; + + $t = get_markup_template('admin_security.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Security'), + '$form_security_token' => get_form_security_token('admin_security'), + '$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated.")), + '$whitelisted_sites' => array('whitelisted_sites', t('Allow communications only from these sites'), $whitesites_str, t('One site per line. Leave empty to allow communication from anywhere by default')), + '$blacklisted_sites' => array('blacklisted_sites', t('Block communications from these sites'), $blacksites_str, ''), + '$whitelisted_channels' => array('whitelisted_channels', t('Allow communications only from these channels'), $whitechannels_str, t('One channel (hash) per line. Leave empty to allow from any channel by default')), + '$blacklisted_channels' => array('blacklisted_channels', t('Block communications from these channels'), $blackchannels_str, ''), + '$embed_allow' => array('embed_allow', t('Allow embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), + '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), + + '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), + '$submit' => t('Submit') + )); + } + + + + + function admin_page_dbsync(&$a) { + $o = ''; + + if(argc() > 3 && intval(argv(3)) && argv(2) === 'mark') { + set_config('database', 'update_r' . intval(argv(3)), 'success'); + if(intval(get_config('system','db_version')) <= intval(argv(3))) + set_config('system','db_version',intval(argv(3)) + 1); + info( t('Update has been marked successful') . EOL); + goaway(z_root() . '/admin/dbsync'); + } + + if(argc() > 2 && intval(argv(2))) { + require_once('install/update.php'); + $func = 'update_r' . intval(argv(2)); + if(function_exists($func)) { + $retval = $func(); + if($retval === UPDATE_FAILED) { + $o .= sprintf( t('Executing %s failed. Check system logs.'), $func); + } + elseif($retval === UPDATE_SUCCESS) { + $o .= sprintf( t('Update %s was successfully applied.'), $func); + set_config('database',$func, 'success'); + } + else + $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func); + } + else + $o .= sprintf( t('Update function %s could not be found.'), $func); + + return $o; + } + + $failed = array(); + $r = q("select * from config where `cat` = 'database' "); + if(count($r)) { + foreach($r as $rr) { + $upd = intval(substr($rr['k'],8)); + if($rr['v'] === 'success') + continue; + $failed[] = $upd; + } + } + if(! count($failed)) + return '

' . t('No failed updates.') . '

'; + + $o = replace_macros(get_markup_template('failed_updates.tpl'),array( + '$base' => z_root(), + '$banner' => t('Failed Updates'), + '$desc' => '', + '$mark' => t('Mark success (if update was manually applied)'), + '$apply' => t('Attempt to execute this update step automatically'), + '$failed' => $failed + )); + + return $o; + } + + function admin_page_queue($a) { + $o = ''; + + $expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0); + + if($_REQUEST['drophub']) { + require_once('hubloc.php'); + hubloc_mark_as_down($_REQUEST['drophub']); + remove_queue_by_posturl($_REQUEST['drophub']); + } + + if($_REQUEST['emptyhub']) { + remove_queue_by_posturl($_REQUEST['emptyhub']); + } + + $r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq + where outq_delivered = 0 group by outq_posturl order by total desc"); + + for($x = 0; $x < count($r); $x ++) { + $r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']); + $r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d'); + } + + $o = replace_macros(get_markup_template('admin_queue.tpl'), array( + '$banner' => t('Queue Statistics'), + '$numentries' => t('Total Entries'), + '$priority' => t('Priority'), + '$desturl' => t('Destination URL'), + '$nukehub' => t('Mark hub permanently offline'), + '$empty' => t('Empty queue for this hub'), + '$lastconn' => t('Last known contact'), + '$hasentries' => ((count($r)) ? true : false), + '$entries' => $r, + '$expert' => $expert + )); + + return $o; + } + + /** + * @brief Handle POST actions on users admin page. + * + * This function is called when on the admin user/account page the form was + * submitted to handle multiple operations at once. If one of the icons next + * to an entry are pressed the function admin_page_users() will handle this. + * + * @param App $a + */ + function admin_page_users_post($a) { + $pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); + $users = ( x($_POST, 'user') ? $_POST['user'] : array() ); + $blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); + + check_form_security_token_redirectOnErr('/admin/users', 'admin_users'); + + // change to switch structure? + // account block/unblock button was submitted + if (x($_POST, 'page_users_block')) { + for ($i = 0; $i < count($users); $i++) { + // if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag + $op = ($blocked[$i]) ? '& ~' : '| '; + q("UPDATE account SET account_flags = (account_flags $op%d) WHERE account_id = %d", + intval(ACCOUNT_BLOCKED), + intval($users[$i]) + ); + } + notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) ); + } + // account delete button was submitted + if (x($_POST, 'page_users_delete')) { + require_once('include/Contact.php'); + foreach ($users as $uid){ + account_remove($uid, true, false); + } + notice( sprintf( tt("%s account deleted", "%s accounts deleted", count($users)), count($users)) ); + } + // registration approved button was submitted + if (x($_POST, 'page_users_approve')) { + foreach ($pending as $hash) { + account_allow($hash); + } + } + // registration deny button was submitted + if (x($_POST, 'page_users_deny')) { + foreach ($pending as $hash) { + account_deny($hash); + } + } + + goaway(z_root() . '/admin/users' ); + } + + /** + * @brief Generate users admin page and handle single item operations. + * + * This function generates the users/account admin page and handles the actions + * if an icon next to an entry was clicked. If several items were selected and + * the form was submitted it is handled by the function admin_page_users_post(). + * + * @param App &$a + * @return string + */ + function admin_page_users(&$a){ + if (argc() > 2) { + $uid = argv(3); + $account = q("SELECT * FROM account WHERE account_id = %d", + intval($uid) + ); + + if (! $account) { + notice( t('Account not found') . EOL); + goaway(z_root() . '/admin/users' ); + } + + check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't'); + + switch (argv(2)){ + case 'delete': + // delete user + require_once('include/Contact.php'); + account_remove($uid,true,false); + + notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL); + break; + case 'block': + q("UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d", + intval(ACCOUNT_BLOCKED), + intval($uid) + ); + + notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL); + break; + case 'unblock': + q("UPDATE account SET account_flags = ( account_flags & ~%d ) WHERE account_id = %d", + intval(ACCOUNT_BLOCKED), + intval($uid) + ); + + notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL); + break; + } + + goaway(z_root() . '/admin/users' ); + } + + /* get pending */ + $pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d )>0 ", + intval(ACCOUNT_PENDING) + ); + + /* get users */ + + $total = q("SELECT count(*) as total FROM account"); + if (count($total)) { + \App::set_pager_total($total[0]['total']); + \App::set_pager_itemspage(100); + } + + + // We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet. + // That's where we need to be doing last post/channel flags/etc, not here. + + $serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : ''); + + $order = " order by account_email asc "; + if($_REQUEST['order'] === 'expires') + $order = " order by account_expires desc "; + if($_REQUEST['order'] === 'created') + $order = " order by account_created desc "; + + $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d )>0 as `blocked`, " . + "(SELECT %s FROM channel as ch " . + "WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " . + "FROM account as ac where true $serviceclass $order limit %d offset %d ", + intval(ACCOUNT_BLOCKED), + db_concat('ch.channel_address', ' '), + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + // function _setup_users($e){ + // $accounts = Array( + // t('Normal Account'), + // t('Soapbox Account'), + // t('Community/Celebrity Account'), + // t('Automatic Friend Account') + // ); + + // $e['page_flags'] = $accounts[$e['page-flags']]; + // $e['register_date'] = relative_date($e['register_date']); + // $e['login_date'] = relative_date($e['login_date']); + // $e['lastitem_date'] = relative_date($e['lastitem_date']); + // return $e; + // } + // $users = array_map("_setup_users", $users); + + $t = get_markup_template('admin_users.tpl'); + $o = replace_macros($t, array( + // strings // + '$title' => t('Administration'), + '$page' => t('Users'), + '$submit' => t('Submit'), + '$select_all' => t('select all'), + '$h_pending' => t('User registrations waiting for confirm'), + '$th_pending' => array( t('Request date'), t('Email') ), + '$no_pending' => t('No registrations.'), + '$approve' => t('Approve'), + '$deny' => t('Deny'), + '$delete' => t('Delete'), + '$block' => t('Block'), + '$unblock' => t('Unblock'), + + '$h_users' => t('Users'), + '$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')), + + '$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'), + '$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'), + + '$form_security_token' => get_form_security_token("admin_users"), + + // values // + '$baseurl' => z_root(), + + '$pending' => $pending, + '$users' => $users, + )); + $o .= paginate($a); + + return $o; + } + + + /** + * @brief Channels admin page. + * + * @param App &$a + */ + function admin_page_channels_post(&$a) { + $channels = ( x($_POST, 'channel') ? $_POST['channel'] : Array() ); + + check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels'); + + $xor = db_getfunc('^'); + + if (x($_POST,'page_channels_block')){ + foreach($channels as $uid){ + q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", + intval(PAGE_CENSORED), + intval( $uid ) + ); + proc_run('php','include/directory.php',$uid,'nopush'); + } + notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) ); + } + if (x($_POST,'page_channels_code')){ + foreach($channels as $uid){ + q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", + intval(PAGE_ALLOWCODE), + intval( $uid ) + ); + } + notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) ); + } + if (x($_POST,'page_channels_delete')){ + require_once("include/Contact.php"); + foreach($channels as $uid){ + channel_remove($uid,true); + } + notice( sprintf( tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)) ); + } + + goaway(z_root() . '/admin/channels' ); + } + + /** + * @brief + * + * @param App &$a + * @return string + */ + function admin_page_channels(&$a){ + if (argc() > 2) { + $uid = argv(3); + $channel = q("SELECT * FROM channel WHERE channel_id = %d", + intval($uid) + ); + + if (! $channel) { + notice( t('Channel not found') . EOL); + goaway(z_root() . '/admin/channels' ); + } + + switch(argv(2)) { + case "delete":{ + check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); + // delete channel + require_once("include/Contact.php"); + channel_remove($uid,true); + + notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL); + }; break; + + case "block":{ + check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); + $pflags = $channel[0]['channel_pageflags'] ^ PAGE_CENSORED; + q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", + intval($pflags), + intval( $uid ) + ); + proc_run('php','include/directory.php',$uid,'nopush'); + + notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL); + }; break; + + case "code":{ + check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); + $pflags = $channel[0]['channel_pageflags'] ^ PAGE_ALLOWCODE; + q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", + intval($pflags), + intval( $uid ) + ); + + notice( sprintf( (($pflags & PAGE_ALLOWCODE) ? t("Channel '%s' code allowed"): t("Channel '%s' code disallowed")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL); + }; break; + + default: + break; + } + goaway(z_root() . '/admin/channels' ); + } + + /* get channels */ + + $total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0"); + if($total) { + \App::set_pager_total($total[0]['total']); + \App::set_pager_itemspage(100); + } + + $order = " order by channel_name asc "; + + $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ", + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + if($channels) { + for($x = 0; $x < count($channels); $x ++) { + if($channels[$x]['channel_pageflags'] & PAGE_CENSORED) + $channels[$x]['blocked'] = true; + else + $channels[$x]['blocked'] = false; + + if($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE) + $channels[$x]['allowcode'] = true; + else + $channels[$x]['allowcode'] = false; + } + } + + $t = get_markup_template("admin_channels.tpl"); + $o = replace_macros($t, array( + // strings // + '$title' => t('Administration'), + '$page' => t('Channels'), + '$submit' => t('Submit'), + '$select_all' => t('select all'), + '$delete' => t('Delete'), + '$block' => t('Censor'), + '$unblock' => t('Uncensor'), + '$code' => t('Allow Code'), + '$uncode' => t('Disallow Code'), + '$h_channels' => t('Channel'), + '$th_channels' => array( t('UID'), t('Name'), t('Address')), + + '$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'), + '$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'), + + '$form_security_token' => get_form_security_token("admin_channels"), + + // values // + '$baseurl' => z_root(), + '$channels' => $channels, + )); + $o .= paginate($a); + + return $o; + } + + + /** + * Plugins admin page + * + * @param App $a + * @return string + */ + function admin_page_plugins(&$a){ + + /* + * Single plugin + */ + if (\App::$argc == 3){ + $plugin = \App::$argv[2]; + if (!is_file("addon/$plugin/$plugin.php")){ + notice( t("Item not found.") ); + return ''; + } + + $enabled = in_array($plugin,\App::$plugins); + $info = get_plugin_info($plugin); + $x = check_plugin_versions($info); + + // disable plugins which are installed but incompatible versions + + if($enabled && ! $x) { + $enabled = false; + $idz = array_search($plugin, \App::$plugins); + if ($idz !== false) { + unset(\App::$plugins[$idz]); + uninstall_plugin($plugin); + set_config("system","addon", implode(", ",\App::$plugins)); + } + } + $info['disabled'] = 1-intval($x); + + if (x($_GET,"a") && $_GET['a']=="t"){ + check_form_security_token_redirectOnErr('/admin/plugins', 'admin_plugins', 't'); + + // Toggle plugin status + $idx = array_search($plugin, \App::$plugins); + if ($idx !== false){ + unset(\App::$plugins[$idx]); + uninstall_plugin($plugin); + info( sprintf( t("Plugin %s disabled."), $plugin ) ); + } else { + \App::$plugins[] = $plugin; + install_plugin($plugin); + info( sprintf( t("Plugin %s enabled."), $plugin ) ); + } + set_config("system","addon", implode(", ",\App::$plugins)); + goaway(z_root() . '/admin/plugins' ); + } + // display plugin details + require_once('library/markdown.php'); + + if (in_array($plugin, \App::$plugins)){ + $status = 'on'; + $action = t('Disable'); + } else { + $status = 'off'; + $action = t('Enable'); + } + + $readme = null; + if (is_file("addon/$plugin/README.md")){ + $readme = file_get_contents("addon/$plugin/README.md"); + $readme = Markdown($readme); + } else if (is_file("addon/$plugin/README")){ + $readme = "
". file_get_contents("addon/$plugin/README") ."
"; + } + + $admin_form = ''; + + $r = q("select * from addon where plugin_admin = 1 and name = '%s' limit 1", + dbesc($plugin) + ); + + if($r) { + @require_once("addon/$plugin/$plugin.php"); + if(function_exists($plugin.'_plugin_admin')) { + $func = $plugin.'_plugin_admin'; + $func($a, $admin_form); + } + } + + + $t = get_markup_template('admin_plugins_details.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Plugins'), + '$toggle' => t('Toggle'), + '$settings' => t('Settings'), + '$baseurl' => z_root(), + + '$plugin' => $plugin, + '$status' => $status, + '$action' => $action, + '$info' => $info, + '$str_author' => t('Author: '), + '$str_maintainer' => t('Maintainer: '), + '$str_minversion' => t('Minimum project version: '), + '$str_maxversion' => t('Maximum project version: '), + '$str_minphpversion' => t('Minimum PHP version: '), + '$str_requires' => t('Requires: '), + '$disabled' => t('Disabled - version incompatibility'), + + '$admin_form' => $admin_form, + '$function' => 'plugins', + '$screenshot' => '', + '$readme' => $readme, + + '$form_security_token' => get_form_security_token('admin_plugins'), + )); + } + + + /* + * List plugins + */ + $plugins = array(); + $files = glob('addon/*/'); + if($files) { + foreach($files as $file) { + if (is_dir($file)){ + list($tmp, $id) = array_map('trim', explode('/', $file)); + $info = get_plugin_info($id); + $enabled = in_array($id,\App::$plugins); + $x = check_plugin_versions($info); + + // disable plugins which are installed but incompatible versions + + if($enabled && ! $x) { + $enabled = false; + $idz = array_search($id, \App::$plugins); + if ($idz !== false) { + unset(\App::$plugins[$idz]); + uninstall_plugin($id); + set_config("system","addon", implode(", ",\App::$plugins)); + } + } + $info['disabled'] = 1-intval($x); + + $plugins[] = array( $id, (($enabled)?"on":"off") , $info); + } + } + } + + $t = get_markup_template('admin_plugins.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Plugins'), + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$function' => 'plugins', + '$plugins' => $plugins, + '$disabled' => t('Disabled - version incompatibility'), + '$form_security_token' => get_form_security_token('admin_plugins'), + )); + } + + /** + * @param array $themes + * @param string $th + * @param int $result + */ + function toggle_theme(&$themes, $th, &$result) { + for($x = 0; $x < count($themes); $x ++) { + if($themes[$x]['name'] === $th) { + if($themes[$x]['allowed']) { + $themes[$x]['allowed'] = 0; + $result = 0; + } + else { + $themes[$x]['allowed'] = 1; + $result = 1; + } + } + } + } + + /** + * @param array $themes + * @param string $th + * @return int + */ + function theme_status($themes, $th) { + for($x = 0; $x < count($themes); $x ++) { + if($themes[$x]['name'] === $th) { + if($themes[$x]['allowed']) { + return 1; + } + else { + return 0; + } + } + } + return 0; + } + + + /** + * @param array $themes + * @return string + */ + function rebuild_theme_table($themes) { + $o = ''; + if(count($themes)) { + foreach($themes as $th) { + if($th['allowed']) { + if(strlen($o)) + $o .= ','; + $o .= $th['name']; + } + } + } + return $o; + } + + + /** + * @brief Themes admin page. + * + * @param App &$a + * @return string + */ + function admin_page_themes(&$a){ + + $allowed_themes_str = get_config('system', 'allowed_themes'); + $allowed_themes_raw = explode(',', $allowed_themes_str); + $allowed_themes = array(); + if(count($allowed_themes_raw)) + foreach($allowed_themes_raw as $x) + if(strlen(trim($x))) + $allowed_themes[] = trim($x); + + $themes = array(); + $files = glob('view/theme/*'); + if($files) { + foreach($files as $file) { + $f = basename($file); + $is_experimental = intval(file_exists($file . '/.experimental')); + $is_supported = 1-(intval(file_exists($file . '/.unsupported'))); // Is not used yet + $is_allowed = intval(in_array($f,$allowed_themes)); + $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed); + } + } + + if(! count($themes)) { + notice( t('No themes found.')); + return ''; + } + + /* + * Single theme + */ + + if (\App::$argc == 3){ + $theme = \App::$argv[2]; + if(! is_dir("view/theme/$theme")){ + notice( t("Item not found.") ); + return ''; + } + + if (x($_GET,"a") && $_GET['a']=="t"){ + check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't'); + + // Toggle theme status + + toggle_theme($themes, $theme, $result); + $s = rebuild_theme_table($themes); + if($result) + info( sprintf('Theme %s enabled.', $theme)); + else + info( sprintf('Theme %s disabled.', $theme)); + + set_config('system', 'allowed_themes', $s); + goaway(z_root() . '/admin/themes' ); + } + + // display theme details + require_once('library/markdown.php'); + + if (theme_status($themes,$theme)) { + $status="on"; $action= t("Disable"); + } else { + $status="off"; $action= t("Enable"); + } + + $readme=Null; + if (is_file("view/theme/$theme/README.md")){ + $readme = file_get_contents("view/theme/$theme/README.md"); + $readme = Markdown($readme); + } else if (is_file("view/theme/$theme/README")){ + $readme = "
". file_get_contents("view/theme/$theme/README") ."
"; + } + + $admin_form = ''; + if (is_file("view/theme/$theme/php/config.php")){ + require_once("view/theme/$theme/php/config.php"); + if(function_exists("theme_admin")){ + $admin_form = theme_admin($a); + } + } + + $screenshot = array( get_theme_screenshot($theme), t('Screenshot')); + if(! stristr($screenshot[0],$theme)) + $screenshot = null; + + $t = get_markup_template('admin_plugins_details.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Themes'), + '$toggle' => t('Toggle'), + '$settings' => t('Settings'), + '$baseurl' => z_root(), + + '$plugin' => $theme, + '$status' => $status, + '$action' => $action, + '$info' => get_theme_info($theme), + '$function' => 'themes', + '$admin_form' => $admin_form, + '$str_author' => t('Author: '), + '$str_maintainer' => t('Maintainer: '), + '$screenshot' => $screenshot, + '$readme' => $readme, + + '$form_security_token' => get_form_security_token('admin_themes'), + )); + } + + /* + * List themes + */ + + $xthemes = array(); + if($themes) { + foreach($themes as $th) { + $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name'])); + } + } + + $t = get_markup_template('admin_plugins.tpl'); + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Themes'), + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$function' => 'themes', + '$plugins' => $xthemes, + '$experimental' => t('[Experimental]'), + '$unsupported' => t('[Unsupported]'), + '$form_security_token' => get_form_security_token('admin_themes'), + )); + } + + + /** + * @brief POST handler for logs admin page. + * + * @param App &$a + */ + function admin_page_logs_post(&$a) { + if (x($_POST, 'page_logs')) { + check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs'); + + $logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : ''); + $debugging = ((x($_POST,'debugging')) ? true : false); + $loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0); + + set_config('system','logfile', $logfile); + set_config('system','debugging', $debugging); + set_config('system','loglevel', $loglevel); + } + + info( t('Log settings updated.') ); + goaway(z_root() . '/admin/logs' ); + } + + /** + * @brief Logs admin page. + * + * @param App $a + * @return string + */ + function admin_page_logs(&$a){ + + $log_choices = Array( + LOGGER_NORMAL => 'Normal', + LOGGER_TRACE => 'Trace', + LOGGER_DEBUG => 'Debug', + LOGGER_DATA => 'Data', + LOGGER_ALL => 'All' + ); + + $t = get_markup_template('admin_logs.tpl'); + + $f = get_config('system', 'logfile'); + + $data = ''; + + if(!file_exists($f)) { + $data = t("Error trying to open $f log file.\r\n
Check to see if file $f exist and is + readable."); + } + else { + $fp = fopen($f, 'r'); + if(!$fp) { + $data = t("Couldn't open $f log file.\r\n
Check to see if file $f is readable."); + } + else { + $fstat = fstat($fp); + $size = $fstat['size']; + if($size != 0) + { + if($size > 5000000 || $size < 0) + $size = 5000000; + $seek = fseek($fp,0-$size,SEEK_END); + if($seek === 0) { + $data = escape_tags(fread($fp,$size)); + while(! feof($fp)) + $data .= escape_tags(fread($fp,4096)); + } + } + fclose($fp); + } + } + + return replace_macros($t, array( + '$title' => t('Administration'), + '$page' => t('Logs'), + '$submit' => t('Submit'), + '$clear' => t('Clear'), + '$data' => $data, + '$baseurl' => z_root(), + '$logname' => get_config('system','logfile'), + + // name, label, value, help string, extra data... + '$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""), + '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")), + '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices), + + '$form_security_token' => get_form_security_token('admin_logs'), + )); + } + + function admin_page_profs_post(&$a) { + + if(array_key_exists('basic',$_REQUEST)) { + $arr = explode(',',$_REQUEST['basic']); + for($x = 0; $x < count($arr); $x ++) + if(trim($arr[$x])) + $arr[$x] = trim($arr[$x]); + set_config('system','profile_fields_basic',$arr); + + if(array_key_exists('advanced',$_REQUEST)) { + $arr = explode(',',$_REQUEST['advanced']); + for($x = 0; $x < count($arr); $x ++) + if(trim($arr[$x])) + $arr[$x] = trim($arr[$x]); + set_config('system','profile_fields_advanced',$arr); + } + goaway(z_root() . '/admin/profs'); + } + + + if(array_key_exists('field_name',$_REQUEST)) { + if($_REQUEST['id']) { + $r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d", + dbesc($_REQUEST['field_name']), + dbesc($_REQUEST['field_type']), + dbesc($_REQUEST['field_desc']), + dbesc($_REQUEST['field_help']), + dbesc($_REQUEST['field_inputs']), + intval($_REQUEST['id']) + ); + } + else { + $r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )", + dbesc($_REQUEST['field_name']), + dbesc($_REQUEST['field_type']), + dbesc($_REQUEST['field_desc']), + dbesc($_REQUEST['field_help']), + dbesc($_REQUEST['field_inputs']) + ); + } + } + + + // add to chosen array basic or advanced + + goaway(z_root() . '/admin/profs'); + } + + function admin_page_profs(&$a) { + + if((argc() > 3) && argv(2) == 'drop' && intval(argv(3))) { + $r = q("delete from profdef where id = %d", + intval(argv(3)) + ); + // remove from allowed fields + + goaway(z_root() . '/admin/profs'); + } + + if((argc() > 2) && argv(2) === 'new') { + return replace_macros(get_markup_template('profdef_edit.tpl'),array( + '$header' => t('New Profile Field'), + '$field_name' => array('field_name',t('Field nickname'),$_REQUEST['field_name'],t('System name of field')), + '$field_type' => array('field_type',t('Input type'),(($_REQUEST['field_type']) ? $_REQUEST['field_type'] : 'text'),''), + '$field_desc' => array('field_desc',t('Field Name'),$_REQUEST['field_desc'],t('Label on profile pages')), + '$field_help' => array('field_help',t('Help text'),$_REQUEST['field_help'],t('Additional info (optional)')), + '$submit' => t('Save') + )); + } + + if((argc() > 2) && intval(argv(2))) { + $r = q("select * from profdef where id = %d limit 1", + intval(argv(2)) + ); + if(! $r) { + notice( t('Field definition not found') . EOL); + goaway(z_root() . '/admin/profs'); + } + + return replace_macros(get_markup_template('profdef_edit.tpl'),array( + '$id' => intval($r[0]['id']), + '$header' => t('Edit Profile Field'), + '$field_name' => array('field_name',t('Field nickname'),$r[0]['field_name'],t('System name of field')), + '$field_type' => array('field_type',t('Input type'),$r[0]['field_type'],''), + '$field_desc' => array('field_desc',t('Field Name'),$r[0]['field_desc'],t('Label on profile pages')), + '$field_help' => array('field_help',t('Help text'),$r[0]['field_help'],t('Additional info (optional)')), + '$submit' => t('Save') + )); + } + + $basic = ''; + $barr = array(); + $fields = get_profile_fields_basic(); + if(! $fields) + $fields = get_profile_fields_basic(1); + if($fields) { + foreach($fields as $k => $v) { + if($basic) + $basic .= ', '; + $basic .= trim($k); + $barr[] = trim($k); + } + } + + $advanced = ''; + $fields = get_profile_fields_advanced(); + if(! $fields) + $fields = get_profile_fields_advanced(1); + if($fields) { + foreach($fields as $k => $v) { + if(in_array(trim($k),$barr)) + continue; + if($advanced) + $advanced .= ', '; + $advanced .= trim($k); + } + } + + $all = ''; + $fields = get_profile_fields_advanced(1); + if($fields) { + foreach($fields as $k => $v) { + if($all) + $all .= ', '; + $all .= trim($k); + } + } + + $r = q("select * from profdef where true"); + if($r) { + foreach($r as $rr) { + if($all) + $all .= ', '; + $all .= $rr['field_name']; + } + } + + + $o = replace_macros(get_markup_template('admin_profiles.tpl'),array( + '$title' => t('Profile Fields'), + '$basic' => array('basic',t('Basic Profile Fields'),$basic,''), + '$advanced' => array('advanced',t('Advanced Profile Fields'),$advanced,t('(In addition to basic fields)')), + '$all' => $all, + '$all_desc' => t('All available fields'), + '$cust_field_desc' => t('Custom Fields'), + '$cust_fields' => $r, + '$edit' => t('Edit'), + '$drop' => t('Delete'), + '$new' => t('Create Custom Field'), + '$submit' => t('Submit') + )); + + return $o; + + + } + +} diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php new file mode 100644 index 000000000..0df0dd4da --- /dev/null +++ b/Zotlabs/Module/Lockview.php @@ -0,0 +1,121 @@ + 1) ? argv(1) : 0); + if (is_numeric($type)) { + $item_id = intval($type); + $type='item'; + } else { + $item_id = ((argc() > 2) ? intval(argv(2)) : 0); + } + + if(! $item_id) + killme(); + + if (!in_array($type, array('item','photo','event', 'menu_item', 'chatroom'))) + killme(); + + //we have different naming in in menu_item table and chatroom table + switch($type) { + case 'menu_item': + $id = 'mitem_id'; + break; + case 'chatroom': + $id = 'cr_id'; + break; + default: + $id = 'id'; + break; + } + + $r = q("SELECT * FROM %s WHERE $id = %d LIMIT 1", + dbesc($type), + intval($item_id) + ); + + if(! $r) + killme(); + + $item = $r[0]; + + //we have different naming in in menu_item table and chatroom table + switch($type) { + case 'menu_item': + $uid = $item['mitem_channel_id']; + break; + case 'chatroom': + $uid = $item['cr_uid']; + break; + default: + $uid = $item['uid']; + break; + } + + if($uid != local_channel()) { + echo '
  • ' . t('Remote privacy information not available.') . '
  • '; + killme(); + } + + if(($item['item_private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) + && (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) { + + // if the post is private, but public_policy is blank ("visible to the internet"), and there aren't any + // specific recipients, we're the recipient of a post with "bcc" or targeted recipients; so we'll just show it + // as unknown specific recipients. The sender will have the visibility list and will fall through to the + // next section. + + echo '
  • ' . translate_scope((! $item['public_policy']) ? 'specific' : $item['public_policy']) . '
  • '; + killme(); + } + + $allowed_users = expand_acl($item['allow_cid']); + $allowed_groups = expand_acl($item['allow_gid']); + $deny_users = expand_acl($item['deny_cid']); + $deny_groups = expand_acl($item['deny_gid']); + + $o = '
  • ' . t('Visible to:') . '
  • '; + $l = array(); + + stringify_array_elms($allowed_groups,true); + stringify_array_elms($allowed_users,true); + stringify_array_elms($deny_groups,true); + stringify_array_elms($deny_users,true); + + if(count($allowed_groups)) { + $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); + if($r) + foreach($r as $rr) + $l[] = '
  • ' . $rr['name'] . '
  • '; + } + if(count($allowed_users)) { + $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )"); + if($r) + foreach($r as $rr) + $l[] = '
  • ' . $rr['xchan_name'] . '
  • '; + } + if(count($deny_groups)) { + $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); + if($r) + foreach($r as $rr) + $l[] = '
  • ' . $rr['name'] . '
  • '; + } + if(count($deny_users)) { + $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )"); + if($r) + foreach($r as $rr) + $l[] = '
  • ' . $rr['xchan_name'] . '
  • '; + } + + echo $o . implode($l); + killme(); + + + } + +} -- cgit v1.2.3 From 1698732cffab2f625c16a1d8d1227497a0965d43 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 18 Apr 2016 01:35:09 -0700 Subject: convert all the _well_known service controllers which are a bit touchy when it comes to the router --- Zotlabs/Module/Hostxrd.php | 24 ++++++++ Zotlabs/Module/Well_known.php | 69 +++++++++++++++++++++ Zotlabs/Module/Wfinger.php | 140 ++++++++++++++++++++++++++++++++++++++++++ Zotlabs/Module/Zfinger.php | 18 ++++++ 4 files changed, 251 insertions(+) create mode 100644 Zotlabs/Module/Hostxrd.php create mode 100644 Zotlabs/Module/Well_known.php create mode 100644 Zotlabs/Module/Wfinger.php create mode 100644 Zotlabs/Module/Zfinger.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Hostxrd.php b/Zotlabs/Module/Hostxrd.php new file mode 100644 index 000000000..1aae8da9e --- /dev/null +++ b/Zotlabs/Module/Hostxrd.php @@ -0,0 +1,24 @@ + \App::get_hostname(), + '$zroot' => z_root() + )); + $arr = array('xrd' => $x); + call_hooks('hostxrd',$arr); + + echo $arr['xrd']; + killme(); + } + +} diff --git a/Zotlabs/Module/Well_known.php b/Zotlabs/Module/Well_known.php new file mode 100644 index 000000000..b57666bff --- /dev/null +++ b/Zotlabs/Module/Well_known.php @@ -0,0 +1,69 @@ + 1) { + + $arr = array('server' => $_SERVER, 'request' => $_REQUEST); + call_hooks('well_known', $arr); + + + if(! check_siteallowed($_SERVER['REMOTE_ADDR'])) { + logger('well_known: site not allowed. ' . $_SERVER['REMOTE_ADDR']); + killme(); + } + + // from php.net re: REMOTE_HOST: + // Note: Your web server must be configured to create this variable. For example in Apache + // you'll need HostnameLookups On inside httpd.conf for it to exist. See also gethostbyaddr(). + + if(get_config('system','siteallowed_remote_host') && (! check_siteallowed($_SERVER['REMOTE_HOST']))) { + logger('well_known: site not allowed. ' . $_SERVER['REMOTE_HOST']); + killme(); + } + + + switch(argv(1)) { + case 'zot-info': + \App::$argc -= 1; + array_shift(\App::$argv); + \App::$argv[0] = 'zfinger'; + $module = new \Zotlabs\Module\Zfinger(); + $module->init(); + break; + + case 'webfinger': + \App::$argc -= 1; + array_shift(\App::$argv); + \App::$argv[0] = 'wfinger'; + $module = new \Zotlabs\Module\Wfinger(); + $module->init(); + break; + + case 'host-meta': + \App::$argc -= 1; + array_shift(\App::$argv); + \App::$argv[0] = 'hostxrd'; + $module = new \Zotlabs\Module\Hostxrd(); + $module->init(); + break; + + default: + if(file_exists(\App::$cmd)) { + echo file_get_contents(\App::$cmd); + killme(); + } + elseif(file_exists(\App::$cmd . '.php')) + require_once(\App::$cmd . '.php'); + break; + + } + } + + http_status_exit(404); + } +} diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php new file mode 100644 index 000000000..fa1e11518 --- /dev/null +++ b/Zotlabs/Module/Wfinger.php @@ -0,0 +1,140 @@ + $r[0]['channel_name'], + 'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'] + ); + + foreach($aliases as $alias) + if($alias != $resource) + $result['aliases'][] = $alias; + + $result['links'] = array( + + array( + 'rel' => 'http://webfinger.net/rel/avatar', + 'type' => $r[0]['xchan_photo_mimetype'], + 'href' => $r[0]['xchan_photo_l'] + ), + + array( + 'rel' => 'http://webfinger.net/rel/profile-page', + 'href' => z_root() . '/profile/' . $r[0]['channel_address'], + ), + + array( + 'rel' => 'http://webfinger.net/rel/blog', + 'href' => z_root() . '/channel/' . $r[0]['channel_address'], + ), + + array( + 'rel' => 'http://ostatus.org/schema/1.0/subscribe', + 'template' => z_root() . '/follow/url={uri}', + ), + + array( + 'rel' => 'http://purl.org/zot/protocol', + 'href' => z_root() . '/.well-known/zot-info' . '?address=' . $r[0]['xchan_addr'], + ), + + array( + 'rel' => 'magic-public-key', + 'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey']), + ) + ); + + if($zot) { + // get a zotinfo packet and return it with webfinger + $result['zot'] = zotinfo(array('address' => $r[0]['xchan_addr'])); + } + } + else { + header($_SERVER["SERVER_PROTOCOL"] . ' ' . 400 . ' ' . 'Bad Request'); + killme(); + } + + $arr = array('channel' => $r[0], 'request' => $_REQUEST, 'result' => $result); + call_hooks('webfinger',$arr); + + json_return_and_die($arr['result'],'application/jrd+json'); + + } + +} diff --git a/Zotlabs/Module/Zfinger.php b/Zotlabs/Module/Zfinger.php new file mode 100644 index 000000000..2ff605fc9 --- /dev/null +++ b/Zotlabs/Module/Zfinger.php @@ -0,0 +1,18 @@ + Date: Mon, 18 Apr 2016 20:38:38 -0700 Subject: module updates --- Zotlabs/Module/Achievements.php | 93 +++ Zotlabs/Module/Acl.php | 314 ++++++++ Zotlabs/Module/Api.php | 122 +++ Zotlabs/Module/Appman.php | 108 +++ Zotlabs/Module/Apps.php | 46 ++ Zotlabs/Module/Attach.php | 61 ++ Zotlabs/Module/Authtest.php | 61 ++ Zotlabs/Module/Block.php | 92 +++ Zotlabs/Module/Blocks.php | 172 +++++ Zotlabs/Module/Bookmarks.php | 105 +++ Zotlabs/Module/Branchtopic.php | 47 ++ Zotlabs/Module/Cal.php | 357 +++++++++ Zotlabs/Module/Chanview.php | 110 +++ Zotlabs/Module/Chat.php | 261 +++++++ Zotlabs/Module/Chatsvc.php | 168 +++++ Zotlabs/Module/Cloud.php | 110 +++ Zotlabs/Module/Common.php | 73 ++ Zotlabs/Module/Connect.php | 130 ++++ Zotlabs/Module/Connections.php | 324 ++++++++ Zotlabs/Module/Connedit.php | 762 +++++++++++++++++++ Zotlabs/Module/Contactgroup.php | 54 ++ Zotlabs/Module/Cover_photo.php | 423 +++++++++++ Zotlabs/Module/Dav.php | 150 ++++ Zotlabs/Module/Directory.php | 425 +++++++++++ Zotlabs/Module/Dirsearch.php | 462 ++++++++++++ Zotlabs/Module/Display.php | 346 +++++++++ Zotlabs/Module/Dreport.php | 145 ++++ Zotlabs/Module/Editblock.php | 198 +++++ Zotlabs/Module/Editlayout.php | 195 +++++ Zotlabs/Module/Editpost.php | 181 +++++ Zotlabs/Module/Editwebpage.php | 239 ++++++ Zotlabs/Module/Events.php | 714 ++++++++++++++++++ Zotlabs/Module/Fbrowser.php | 136 ++++ Zotlabs/Module/Feed.php | 48 ++ Zotlabs/Module/Ffsapi.php | 71 ++ Zotlabs/Module/Fhublocs.php | 85 +++ Zotlabs/Module/Filer.php | 61 ++ Zotlabs/Module/Filerm.php | 39 + Zotlabs/Module/Filestorage.php | 173 +++++ Zotlabs/Module/Follow.php | 65 ++ Zotlabs/Module/Fsuggest.php | 117 +++ Zotlabs/Module/Getfile.php | 102 +++ Zotlabs/Module/Group.php | 244 ++++++ Zotlabs/Module/Hcard.php | 60 ++ Zotlabs/Module/Help.php | 146 ++++ Zotlabs/Module/Home.php | 89 +++ Zotlabs/Module/Id.php | 319 ++++++++ Zotlabs/Module/Impel.php | 207 +++++ Zotlabs/Module/Import.php | 553 ++++++++++++++ Zotlabs/Module/Import_items.php | 129 ++++ Zotlabs/Module/Invite.php | 152 ++++ Zotlabs/Module/Item.php | 1265 +++++++++++++++++++++++++++++++ Zotlabs/Module/Lang.php | 12 + Zotlabs/Module/Layouts.php | 199 +++++ Zotlabs/Module/Like.php | 547 ++++++++++++++ Zotlabs/Module/Linkinfo.php | 381 ++++++++++ Zotlabs/Module/Locs.php | 132 ++++ Zotlabs/Module/Login.php | 13 + Zotlabs/Module/Lostpass.php | 138 ++++ Zotlabs/Module/Magic.php | 173 +++++ Zotlabs/Module/Mail.php | 397 ++++++++++ Zotlabs/Module/Manage.php | 181 +++++ Zotlabs/Module/Match.php | 84 +++ Zotlabs/Module/Menu.php | 173 +++++ Zotlabs/Module/Message.php | 110 +++ Zotlabs/Module/Mitem.php | 245 ++++++ Zotlabs/Module/Mood.php | 146 ++++ Zotlabs/Module/Msearch.php | 47 ++ Zotlabs/Module/Network.php | 531 +++++++++++++ Zotlabs/Module/New_channel.php | 151 ++++ Zotlabs/Module/Nojs.php | 15 + Zotlabs/Module/Notes.php | 40 + Zotlabs/Module/Notifications.php | 111 +++ Zotlabs/Module/Notify.php | 69 ++ Zotlabs/Module/Oembed.php | 36 + Zotlabs/Module/Oep.php | 403 ++++++++++ Zotlabs/Module/Oexchange.php | 77 ++ Zotlabs/Module/Online.php | 17 + Zotlabs/Module/Openid.php | 198 +++++ Zotlabs/Module/Opensearch.php | 24 + Zotlabs/Module/Page.php | 150 ++++ Zotlabs/Module/Pconfig.php | 122 +++ Zotlabs/Module/Pdledit.php | 72 ++ Zotlabs/Module/Photo.php | 250 ++++++ Zotlabs/Module/Photos.php | 1384 ++++++++++++++++++++++++++++++++++ Zotlabs/Module/Ping.php | 497 ++++++++++++ Zotlabs/Module/Poco.php | 13 + Zotlabs/Module/Poke.php | 194 +++++ Zotlabs/Module/Post.php | 36 + Zotlabs/Module/Prate.php | 105 +++ Zotlabs/Module/Pretheme.php | 28 + Zotlabs/Module/Probe.php | 47 ++ Zotlabs/Module/Profile.php | 90 +++ Zotlabs/Module/Profile_photo.php | 436 +++++++++++ Zotlabs/Module/Profiles.php | 795 +++++++++++++++++++ Zotlabs/Module/Profperm.php | 172 +++++ Zotlabs/Module/Pubsites.php | 59 ++ Zotlabs/Module/Pubstream.php | 168 +++++ Zotlabs/Module/Pushcall.php | 19 + Zotlabs/Module/Randprof.php | 18 + Zotlabs/Module/Rate.php | 178 +++++ Zotlabs/Module/Ratings.php | 115 +++ Zotlabs/Module/Ratingsearch.php | 76 ++ Zotlabs/Module/Rbmark.php | 121 +++ Zotlabs/Module/Regdir.php | 109 +++ Zotlabs/Module/Register.php | 270 +++++++ Zotlabs/Module/Regmod.php | 40 + Zotlabs/Module/Regver.php | 28 + Zotlabs/Module/Removeaccount.php | 72 ++ Zotlabs/Module/Removeme.php | 72 ++ Zotlabs/Module/Rmagic.php | 95 +++ Zotlabs/Module/Rpost.php | 144 ++++ Zotlabs/Module/Rsd_xml.php | 29 + Zotlabs/Module/Search.php | 228 ++++++ Zotlabs/Module/Search_ac.php | 82 ++ Zotlabs/Module/Service_limits.php | 28 + Zotlabs/Module/Settings.php | 1150 ++++++++++++++++++++++++++++ Zotlabs/Module/Setup.php | 754 ++++++++++++++++++ Zotlabs/Module/Share.php | 93 +++ Zotlabs/Module/Sharedwithme.php | 113 +++ Zotlabs/Module/Siteinfo.php | 94 +++ Zotlabs/Module/Siteinfo_json.php | 14 + Zotlabs/Module/Sitelist.php | 67 ++ Zotlabs/Module/Smilies.php | 21 + Zotlabs/Module/Sources.php | 173 +++++ Zotlabs/Module/Sslify.php | 30 + Zotlabs/Module/Starred.php | 39 + Zotlabs/Module/Subthread.php | 169 +++++ Zotlabs/Module/Suggest.php | 72 ++ Zotlabs/Module/Tagger.php | 140 ++++ Zotlabs/Module/Tagrm.php | 147 ++++ Zotlabs/Module/Tasks.php | 112 +++ Zotlabs/Module/Test.php | 38 + Zotlabs/Module/Thing.php | 368 +++++++++ Zotlabs/Module/Toggle_mobile.php | 23 + Zotlabs/Module/Toggle_safesearch.php | 31 + Zotlabs/Module/Uexport.php | 71 ++ Zotlabs/Module/Update_display.php | 48 ++ Zotlabs/Module/Update_home.php | 42 ++ Zotlabs/Module/Update_network.php | 44 ++ Zotlabs/Module/Update_pubstream.php | 42 ++ Zotlabs/Module/Update_search.php | 69 ++ Zotlabs/Module/View.php | 20 + Zotlabs/Module/Viewconnections.php | 117 +++ Zotlabs/Module/Viewsrc.php | 53 ++ Zotlabs/Module/Wall_attach.php | 55 ++ Zotlabs/Module/Wall_upload.php | 57 ++ Zotlabs/Module/Webfinger.php | 54 ++ Zotlabs/Module/Webpages.php | 207 +++++ Zotlabs/Module/Xchan.php | 47 ++ Zotlabs/Module/Xpoco.php | 13 + Zotlabs/Module/Xrd.php | 81 ++ Zotlabs/Module/Xref.php | 26 + Zotlabs/Module/Zcard.php | 107 +++ Zotlabs/Module/Zotfeed.php | 52 ++ Zotlabs/Module/Zping.php | 33 + 156 files changed, 26987 insertions(+) create mode 100644 Zotlabs/Module/Achievements.php create mode 100644 Zotlabs/Module/Acl.php create mode 100644 Zotlabs/Module/Api.php create mode 100644 Zotlabs/Module/Appman.php create mode 100644 Zotlabs/Module/Apps.php create mode 100644 Zotlabs/Module/Attach.php create mode 100644 Zotlabs/Module/Authtest.php create mode 100644 Zotlabs/Module/Block.php create mode 100644 Zotlabs/Module/Blocks.php create mode 100644 Zotlabs/Module/Bookmarks.php create mode 100644 Zotlabs/Module/Branchtopic.php create mode 100644 Zotlabs/Module/Cal.php create mode 100644 Zotlabs/Module/Chanview.php create mode 100644 Zotlabs/Module/Chat.php create mode 100644 Zotlabs/Module/Chatsvc.php create mode 100644 Zotlabs/Module/Cloud.php create mode 100644 Zotlabs/Module/Common.php create mode 100644 Zotlabs/Module/Connect.php create mode 100644 Zotlabs/Module/Connections.php create mode 100644 Zotlabs/Module/Connedit.php create mode 100644 Zotlabs/Module/Contactgroup.php create mode 100644 Zotlabs/Module/Cover_photo.php create mode 100644 Zotlabs/Module/Dav.php create mode 100644 Zotlabs/Module/Directory.php create mode 100644 Zotlabs/Module/Dirsearch.php create mode 100644 Zotlabs/Module/Display.php create mode 100644 Zotlabs/Module/Dreport.php create mode 100644 Zotlabs/Module/Editblock.php create mode 100644 Zotlabs/Module/Editlayout.php create mode 100644 Zotlabs/Module/Editpost.php create mode 100644 Zotlabs/Module/Editwebpage.php create mode 100644 Zotlabs/Module/Events.php create mode 100644 Zotlabs/Module/Fbrowser.php create mode 100644 Zotlabs/Module/Feed.php create mode 100644 Zotlabs/Module/Ffsapi.php create mode 100644 Zotlabs/Module/Fhublocs.php create mode 100644 Zotlabs/Module/Filer.php create mode 100644 Zotlabs/Module/Filerm.php create mode 100644 Zotlabs/Module/Filestorage.php create mode 100644 Zotlabs/Module/Follow.php create mode 100644 Zotlabs/Module/Fsuggest.php create mode 100644 Zotlabs/Module/Getfile.php create mode 100644 Zotlabs/Module/Group.php create mode 100644 Zotlabs/Module/Hcard.php create mode 100644 Zotlabs/Module/Help.php create mode 100644 Zotlabs/Module/Home.php create mode 100644 Zotlabs/Module/Id.php create mode 100644 Zotlabs/Module/Impel.php create mode 100644 Zotlabs/Module/Import.php create mode 100644 Zotlabs/Module/Import_items.php create mode 100644 Zotlabs/Module/Invite.php create mode 100644 Zotlabs/Module/Item.php create mode 100644 Zotlabs/Module/Lang.php create mode 100644 Zotlabs/Module/Layouts.php create mode 100644 Zotlabs/Module/Like.php create mode 100644 Zotlabs/Module/Linkinfo.php create mode 100644 Zotlabs/Module/Locs.php create mode 100644 Zotlabs/Module/Login.php create mode 100644 Zotlabs/Module/Lostpass.php create mode 100644 Zotlabs/Module/Magic.php create mode 100644 Zotlabs/Module/Mail.php create mode 100644 Zotlabs/Module/Manage.php create mode 100644 Zotlabs/Module/Match.php create mode 100644 Zotlabs/Module/Menu.php create mode 100644 Zotlabs/Module/Message.php create mode 100644 Zotlabs/Module/Mitem.php create mode 100644 Zotlabs/Module/Mood.php create mode 100644 Zotlabs/Module/Msearch.php create mode 100644 Zotlabs/Module/Network.php create mode 100644 Zotlabs/Module/New_channel.php create mode 100644 Zotlabs/Module/Nojs.php create mode 100644 Zotlabs/Module/Notes.php create mode 100644 Zotlabs/Module/Notifications.php create mode 100644 Zotlabs/Module/Notify.php create mode 100644 Zotlabs/Module/Oembed.php create mode 100644 Zotlabs/Module/Oep.php create mode 100644 Zotlabs/Module/Oexchange.php create mode 100644 Zotlabs/Module/Online.php create mode 100644 Zotlabs/Module/Openid.php create mode 100644 Zotlabs/Module/Opensearch.php create mode 100644 Zotlabs/Module/Page.php create mode 100644 Zotlabs/Module/Pconfig.php create mode 100644 Zotlabs/Module/Pdledit.php create mode 100644 Zotlabs/Module/Photo.php create mode 100644 Zotlabs/Module/Photos.php create mode 100644 Zotlabs/Module/Ping.php create mode 100644 Zotlabs/Module/Poco.php create mode 100644 Zotlabs/Module/Poke.php create mode 100644 Zotlabs/Module/Post.php create mode 100644 Zotlabs/Module/Prate.php create mode 100644 Zotlabs/Module/Pretheme.php create mode 100644 Zotlabs/Module/Probe.php create mode 100644 Zotlabs/Module/Profile.php create mode 100644 Zotlabs/Module/Profile_photo.php create mode 100644 Zotlabs/Module/Profiles.php create mode 100644 Zotlabs/Module/Profperm.php create mode 100644 Zotlabs/Module/Pubsites.php create mode 100644 Zotlabs/Module/Pubstream.php create mode 100644 Zotlabs/Module/Pushcall.php create mode 100644 Zotlabs/Module/Randprof.php create mode 100644 Zotlabs/Module/Rate.php create mode 100644 Zotlabs/Module/Ratings.php create mode 100644 Zotlabs/Module/Ratingsearch.php create mode 100644 Zotlabs/Module/Rbmark.php create mode 100644 Zotlabs/Module/Regdir.php create mode 100644 Zotlabs/Module/Register.php create mode 100644 Zotlabs/Module/Regmod.php create mode 100644 Zotlabs/Module/Regver.php create mode 100644 Zotlabs/Module/Removeaccount.php create mode 100644 Zotlabs/Module/Removeme.php create mode 100644 Zotlabs/Module/Rmagic.php create mode 100644 Zotlabs/Module/Rpost.php create mode 100644 Zotlabs/Module/Rsd_xml.php create mode 100644 Zotlabs/Module/Search.php create mode 100644 Zotlabs/Module/Search_ac.php create mode 100644 Zotlabs/Module/Service_limits.php create mode 100644 Zotlabs/Module/Settings.php create mode 100644 Zotlabs/Module/Setup.php create mode 100644 Zotlabs/Module/Share.php create mode 100644 Zotlabs/Module/Sharedwithme.php create mode 100644 Zotlabs/Module/Siteinfo.php create mode 100644 Zotlabs/Module/Siteinfo_json.php create mode 100644 Zotlabs/Module/Sitelist.php create mode 100644 Zotlabs/Module/Smilies.php create mode 100644 Zotlabs/Module/Sources.php create mode 100644 Zotlabs/Module/Sslify.php create mode 100644 Zotlabs/Module/Starred.php create mode 100644 Zotlabs/Module/Subthread.php create mode 100644 Zotlabs/Module/Suggest.php create mode 100644 Zotlabs/Module/Tagger.php create mode 100644 Zotlabs/Module/Tagrm.php create mode 100644 Zotlabs/Module/Tasks.php create mode 100644 Zotlabs/Module/Test.php create mode 100644 Zotlabs/Module/Thing.php create mode 100644 Zotlabs/Module/Toggle_mobile.php create mode 100644 Zotlabs/Module/Toggle_safesearch.php create mode 100644 Zotlabs/Module/Uexport.php create mode 100644 Zotlabs/Module/Update_display.php create mode 100644 Zotlabs/Module/Update_home.php create mode 100644 Zotlabs/Module/Update_network.php create mode 100644 Zotlabs/Module/Update_pubstream.php create mode 100644 Zotlabs/Module/Update_search.php create mode 100644 Zotlabs/Module/View.php create mode 100644 Zotlabs/Module/Viewconnections.php create mode 100644 Zotlabs/Module/Viewsrc.php create mode 100644 Zotlabs/Module/Wall_attach.php create mode 100644 Zotlabs/Module/Wall_upload.php create mode 100644 Zotlabs/Module/Webfinger.php create mode 100644 Zotlabs/Module/Webpages.php create mode 100644 Zotlabs/Module/Xchan.php create mode 100644 Zotlabs/Module/Xpoco.php create mode 100644 Zotlabs/Module/Xrd.php create mode 100644 Zotlabs/Module/Xref.php create mode 100644 Zotlabs/Module/Zcard.php create mode 100644 Zotlabs/Module/Zotfeed.php create mode 100644 Zotlabs/Module/Zping.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Achievements.php b/Zotlabs/Module/Achievements.php new file mode 100644 index 000000000..8ddefb3e5 --- /dev/null +++ b/Zotlabs/Module/Achievements.php @@ -0,0 +1,93 @@ + 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + return; + } + + $profile = 0; + $profile = argv(1); + profile_load($a,$which,$profile); + + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + + $observer = \App::get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + $perms = get_all_perms($owner,$ob_hash); + if(! $perms['view_profile']) { + notice( t('Permission denied.') . EOL); + return; + } + + $newmembertext = t('Some blurb about what to do when you\'re new here'); + + + // By default, all badges are false + $contactbadge = false; + $profilebadge = false; + $keywordsbadge = false; + + // Check number of contacts. Award a badge if over 10 + // We'll figure these out on each page load instead of + // writing them to the DB because that will mean one needs + // to retain their achievements - eg, you can't add + // a bunch of channels just to get your badge, and then + // delete them all again. If these become popular or + // used in profiles or something, we may need to reconsider + // and add a table for this - because this won't scale. + + $r = q("select * from abook where abook_channel = %d", + intval($owner) + ); + + if (count($r)) + $contacts = count($r); + // We're checking for 11 to adjust for the abook record for self + if ($contacts >= 11) + $contactbadge = true; + + // Check if an about field in the profile has been created. + + $r = q("select * from profile where uid = %d and about <> ''", + intval($owner) + ); + + if ($r) + $profilebadge = 1; + + // Check if keywords have been set + + $r = q("select * from profile where uid = %d and keywords <> ''", + intval($owner) + ); + + if($r) + $keywordsbadge = 1; + + return replace_macros(get_markup_template("achievements.tpl"), array( + '$newmembertext' => $newmembertext, + '$profilebadge' => $profilebadge, + '$contactbadge' => $contactbadge, + '$keywordsbadge' => $keywordsbadge, + '$channelsbadge' => $channelsbadge + )); + + } + +} diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php new file mode 100644 index 000000000..5c14ab599 --- /dev/null +++ b/Zotlabs/Module/Acl.php @@ -0,0 +1,314 @@ + "g", + "photo" => "images/twopeople.png", + "name" => $g['name'], + "id" => $g['id'], + "xid" => $g['hash'], + "uids" => group_get_members_xchan($g['id']), + "link" => '' + ); + } + } + + if ($type=='' || $type=='c') { + $extra_channels_sql = ''; + // Only include channels who allow the observer to view their permissions + foreach($extra_channels as $channel) { + if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) + $extra_channels_sql .= "," . intval($channel); + } + + $extra_channels_sql = substr($extra_channels_sql,1); // Remove initial comma + + // Getting info from the abook is better for local users because it contains info about permissions + if(local_channel()) { + if($extra_channels_sql != '') + $extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 "; + + $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , + intval(local_channel()) + ); + + } + else { // Visitors + $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self + FROM xchan left join xlink on xlink_link = xchan_hash + WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , + dbesc(get_observer_hash()) + ); + + // Find contacts of extra channels + // This is probably more complicated than it needs to be + if($extra_channels_sql) { + // Build a list of hashes that we got previously so we don't get them again + $known_hashes = array("'".get_observer_hash()."'"); + if($r) + foreach($r as $rr) + $known_hashes[] = "'".$rr['hash']."'"; + $known_hashes_sql = 'AND xchan_hash not in ('.join(',',$known_hashes).')'; + + $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc"); + if($r2) + $r = array_merge($r,$r2); + + // Sort accoring to match position, then alphabetically. This could be avoided if the above two SQL queries could be combined into one, and the sorting could be done on the SQl server (like in the case of a local user) + $matchpos = function($x) use($search) { + $namepos = strpos($x['name'],$search); + $nickpos = strpos($x['nick'],$search); + // Use a large position if not found + return min($namepos === false ? 9999 : $namepos, $nickpos === false ? 9999 : $nickpos); + }; + // This could be made simpler if PHP supported stable sorting + usort($r,function($a,$b) use($matchpos) { + $pos1 = $matchpos($a); + $pos2 = $matchpos($b); + if($pos1 == $pos2) { // Order alphabetically if match position is the same + if($a['name'] == $b['name']) + return 0; + else + return ($a['name'] < $b['name']) ? -1 : 1; + } + return ($pos1 < $pos2) ? -1 : 1; + }); + } + } + if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) { + if((count($r) < 100) && $type == 'c') { + $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self + FROM xchan + WHERE xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" + ); + if($r2) + $r = array_merge($r,$r2); + } + } + } + elseif($type == 'm') { + + $r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0) + and xchan_deleted = 0 + $sql_extra3 + ORDER BY `xchan_name` ASC ", + intval(local_channel()), + intval(PERMS_W_MAIL) + ); + } + elseif(($type == 'a') || ($type == 'p')) { + + $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d + and xchan_deleted = 0 + $sql_extra3 + ORDER BY xchan_name ASC ", + intval(local_channel()) + ); + + } + elseif($type == 'x') { + $r = $this->navbar_complete($a); + $contacts = array(); + if($r) { + foreach($r as $g) { + $contacts[] = array( + "photo" => $g['photo'], + "name" => $g['name'], + "nick" => $g['address'], + ); + } + } + + $o = array( + 'start' => $start, + 'count' => $count, + 'items' => $contacts, + ); + echo json_encode($o); + killme(); + } + else + $r = array(); + + if(count($r)) { + foreach($r as $g){ + + // remove RSS feeds from ACLs - they are inaccessible + if(strpos($g['hash'],'/') && $type != 'a') + continue; + + if(($g['abook_their_perms'] & PERMS_W_TAGWALL) && $type == 'c' && (! $noforums)) { + $contacts[] = array( + "type" => "c", + "photo" => "images/twopeople.png", + "name" => $g['name'] . '+', + "id" => $g['id'] . '+', + "xid" => $g['hash'], + "link" => $g['nick'], + "nick" => substr($g['nick'],0,strpos($g['nick'],'@')), + "self" => (intval($g['abook_self']) ? 'abook-self' : ''), + "taggable" => 'taggable', + "label" => t('network') + ); + } + $contacts[] = array( + "type" => "c", + "photo" => $g['micro'], + "name" => $g['name'], + "id" => $g['id'], + "xid" => $g['hash'], + "link" => $g['nick'], + "nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : t('RSS')), + "self" => (intval($g['abook_self']) ? 'abook-self' : ''), + "taggable" => '', + "label" => '', + ); + } + } + + $items = array_merge($groups, $contacts); + + $o = array( + 'start' => $start, + 'count' => $count, + 'items' => $items, + ); + + + + echo json_encode($o); + + killme(); + } + + + function navbar_complete(&$a) { + + // logger('navbar_complete'); + + if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + return; + } + + $dirmode = intval(get_config('system','directory_mode')); + $search = ((x($_REQUEST,'search')) ? htmlentities($_REQUEST['search'],ENT_COMPAT,'UTF-8',false) : ''); + if(! $search || mb_strlen($search) < 2) + return array(); + + $star = false; + $address = false; + + if(substr($search,0,1) === '@') + $search = substr($search,1); + + if(substr($search,0,1) === '*') { + $star = true; + $search = substr($search,1); + } + + if(strpos($search,'@') !== false) { + $address = true; + } + + if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { + $url = z_root() . '/dirsearch'; + } + + if(! $url) { + require_once("include/dir_fns.php"); + $directory = find_upstream_directory($dirmode); + $url = $directory['url'] . '/dirsearch'; + } + + $count = (x($_REQUEST,'count')?$_REQUEST['count']:100); + if($url) { + $query = $url . '?f=' ; + $query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : ''); + + $x = z_fetch_url($query); + if($x['success']) { + $t = 0; + $j = json_decode($x['body'],true); + if($j && $j['results']) { + return $j['results']; + } + } + } + return array(); + } + +} diff --git a/Zotlabs/Module/Api.php b/Zotlabs/Module/Api.php new file mode 100644 index 000000000..3e7f23b6c --- /dev/null +++ b/Zotlabs/Module/Api.php @@ -0,0 +1,122 @@ +"; var_dump($e); killme(); + } + + + if(x($_POST,'oauth_yes')){ + + $app = $this->oauth_get_client($request); + if (is_null($app)) return "Invalid request. Unknown token."; + $consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']); + + $verifier = md5($app['secret'].local_channel()); + set_config("oauth", $verifier, local_channel()); + + + if($consumer->callback_url!=null) { + $params = $request->get_parameters(); + $glue="?"; + if (strstr($consumer->callback_url,$glue)) $glue="?"; + goaway($consumer->callback_url . $glue . "oauth_token=" . OAuth1Util::urlencode_rfc3986($params['oauth_token']) . "&oauth_verifier=" . OAuth1Util::urlencode_rfc3986($verifier)); + killme(); + } + + $tpl = get_markup_template("oauth_authorize_done.tpl"); + $o = replace_macros($tpl, array( + '$title' => t('Authorize application connection'), + '$info' => t('Return to your app and insert this Securty Code:'), + '$code' => $verifier, + )); + + return $o; + } + + + if(! local_channel()) { + //TODO: we need login form to redirect to this page + notice( t('Please login to continue.') . EOL ); + return login(false,'api-login',$request->get_parameters()); + } + //FKOAuth1::loginUser(4); + + $app = $this->oauth_get_client($request); + if (is_null($app)) return "Invalid request. Unknown token."; + + + + + $tpl = get_markup_template('oauth_authorize.tpl'); + $o = replace_macros($tpl, array( + '$title' => t('Authorize application connection'), + '$app' => $app, + '$authorize' => t('Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?'), + '$yes' => t('Yes'), + '$no' => t('No'), + )); + + //echo "
    "; var_dump($app); killme();
    +			
    +			return $o;
    +		}
    +		
    +		echo api_call($a);
    +		killme();
    +	}
    +
    +	function oauth_get_client($request){
    +
    +	
    +		$params = $request->get_parameters();
    +		$token = $params['oauth_token'];
    +	
    +		$r = q("SELECT `clients`.* 
    +			FROM `clients`, `tokens` 
    +			WHERE `clients`.`client_id`=`tokens`.`client_id` 
    +			AND `tokens`.`id`='%s' AND `tokens`.`scope`='request'",
    +			dbesc($token));
    +
    +		if (!count($r))
    +			return null;
    +	
    +		return $r[0];
    +	}
    +	
    +	
    +	
    +	
    +}
    diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php
    new file mode 100644
    index 000000000..96e4cdd87
    --- /dev/null
    +++ b/Zotlabs/Module/Appman.php
    @@ -0,0 +1,108 @@
    + intval($_REQUEST['uid']),
    +				'url' => escape_tags($_REQUEST['url']),
    +				'guid' => escape_tags($_REQUEST['guid']),
    +				'author' => escape_tags($_REQUEST['author']),
    +				'addr' => escape_tags($_REQUEST['addr']),
    +				'name' => escape_tags($_REQUEST['name']),
    +				'desc' => escape_tags($_REQUEST['desc']),
    +				'photo' => escape_tags($_REQUEST['photo']),
    +				'version' => escape_tags($_REQUEST['version']),
    +				'price' => escape_tags($_REQUEST['price']),
    +				'sig' => escape_tags($_REQUEST['sig'])
    +			);
    +	
    +			$_REQUEST['appid'] = app_install(local_channel(),$arr);
    +	
    +			if(app_installed(local_channel(),$arr))
    +				info( t('App installed.') . EOL);
    +	
    +			return;
    +		}
    +	
    +	
    +		$papp = app_decode($_POST['papp']);
    +	
    +		if(! is_array($papp)) {
    +			notice( t('Malformed app.') . EOL);
    +			return;
    +		}
    +	
    +		if($_POST['install']) {
    +			app_install(local_channel(),$papp);
    +			if(app_installed(local_channel(),$papp))
    +				info( t('App installed.') . EOL);
    +		}
    +	
    +		if($_POST['delete']) {
    +			app_destroy(local_channel(),$papp);
    +		}
    +	
    +		if($_POST['edit']) {
    +			return;
    +		}
    +	
    +		if($_SESSION['return_url']) 
    +			goaway(z_root() . '/' . $_SESSION['return_url']);
    +		goaway(z_root() . '/apps');
    +	
    +	
    +	}
    +	
    +	
    +		function get() {
    +	
    +		if(! local_channel()) {
    +			notice( t('Permission denied.') . EOL);
    +			return;
    +		}
    +	
    +		$channel = \App::get_channel();
    +		$app = null;
    +		$embed = null;
    +		if($_REQUEST['appid']) {
    +			$r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
    +				dbesc($_REQUEST['appid']),
    +				dbesc(local_channel())
    +			);
    +			if($r)
    +				$app = $r[0];
    +			$embed = array('embed', t('Embed code'), app_encode($app,true),'', 'onclick="this.select();"');
    +	
    +		}
    +				
    +		return replace_macros(get_markup_template('app_create.tpl'), array(
    +	
    +			'$banner' => (($app) ? t('Edit App') : t('Create App')),
    +			'$app' => $app,
    +			'$guid' => (($app) ? $app['app_id'] : ''),
    +			'$author' => (($app) ? $app['app_author'] : $channel['channel_hash']),
    +			'$addr' => (($app) ? $app['app_addr'] : $channel['xchan_addr']),
    +			'$name' => array('name', t('Name of app'),(($app) ? $app['app_name'] : ''), t('Required')),
    +			'$url' => array('url', t('Location (URL) of app'),(($app) ? $app['app_url'] : ''), t('Required')),
    +	 		'$desc' => array('desc', t('Description'),(($app) ? $app['app_desc'] : ''), ''),
    +			'$photo' => array('photo', t('Photo icon URL'),(($app) ? $app['app_photo'] : ''), t('80 x 80 pixels - optional')),
    +			'$version' => array('version', t('Version ID'),(($app) ? $app['app_version'] : ''), ''),
    +			'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
    +			'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
    +			'$embed' => $embed,
    +			'$submit' => t('Submit')
    +		));
    +	
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php
    new file mode 100644
    index 000000000..4066966ca
    --- /dev/null
    +++ b/Zotlabs/Module/Apps.php
    @@ -0,0 +1,46 @@
    + get_config('system','sitename'),
    +			'$title' => t('Apps'),
    +			'$apps' => $apps,
    +		));
    +	
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php
    new file mode 100644
    index 000000000..8948b66d7
    --- /dev/null
    +++ b/Zotlabs/Module/Attach.php
    @@ -0,0 +1,61 @@
    + 2) ? intval(argv(2)) : 0));
    +	
    +		if(! $r['success']) {
    +			notice( $r['message'] . EOL);
    +			return;
    +		}
    +	
    +		$c = q("select channel_address from channel where channel_id = %d limit 1",
    +			intval($r['data']['uid'])
    +		);
    +	
    +		if(! $c)
    +			return;
    +	
    +	
    +		$unsafe_types = array('text/html','text/css','application/javascript');
    +	
    +		if(in_array($r['data']['filetype'],$unsafe_types)) {
    +				header('Content-type: text/plain');
    +		}
    +		else {
    +			header('Content-type: ' . $r['data']['filetype']);
    +		}
    +	
    +		header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"');
    +		if(intval($r['data']['os_storage'])) {
    +			$fname = dbunescbin($r['data']['data']);
    +			if(strpos($fname,'store') !== false)
    +				$istream = fopen($fname,'rb');
    +			else
    +				$istream = fopen('store/' . $c[0]['channel_address'] . '/' . $fname,'rb');
    +			$ostream = fopen('php://output','wb');
    +			if($istream && $ostream) {
    +				pipe_streams($istream,$ostream);
    +				fclose($istream);
    +				fclose($ostream);
    +			}
    +		}
    +		else
    +			echo dbunescbin($r['data']['data']);
    +		killme();
    +	
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Authtest.php b/Zotlabs/Module/Authtest.php
    new file mode 100644
    index 000000000..239ae3bdb
    --- /dev/null
    +++ b/Zotlabs/Module/Authtest.php
    @@ -0,0 +1,61 @@
    +Magic-Auth Diagnostic';
    +	
    +		if(! local_channel()) {
    +			notice( t('Permission denied.') . EOL);
    +			return $o;
    +		}
    +	
    +		$o .= '
    '; + $o .= 'Target URL: '; + $o .= '
    '; + + $o .= '

    '; + + if(x($_GET,'dest')) { + if(strpos($_GET['dest'],'@')) { + $_GET['dest'] = $_REQUEST['dest'] = 'https://' . substr($_GET['dest'],strpos($_GET['dest'],'@')+1) . '/channel/' . substr($_GET['dest'],0,strpos($_GET['dest'],'@')); + } + + $_REQUEST['test'] = 1; + $mod = new Magic(); + $x = $mod->init($a); + + $o .= 'Local Setup returns: ' . print_r($x,true); + + + + if($x['url']) { + $z = z_fetch_url($x['url'] . '&test=1'); + if($z['success']) { + $j = json_decode($z['body'],true); + if(! $j) + $o .= 'json_decode failure from remote site. ' . print_r($z['body'],true); + $o .= 'Remote site responded: ' . print_r($j,true); + if($j['success'] && strpos($j['message'],'Authentication Success')) + $auth_success = true; + } + else { + $o .= 'fetch url failure.' . print_r($z,true); + } + } + + if(! $auth_success) + $o .= 'Authentication Failed!' . EOL; + } + + return str_replace("\n",'
    ',$o); + } + +} diff --git a/Zotlabs/Module/Block.php b/Zotlabs/Module/Block.php new file mode 100644 index 000000000..062befdb5 --- /dev/null +++ b/Zotlabs/Module/Block.php @@ -0,0 +1,92 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $_SESSION['return_url'] = \App::$query_string; + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + // Block design features from visitors + + if((! $uid) || ($uid != $owner)) { + notice( t('Permission denied.') . EOL); + return; + } + + $mimetype = (($_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype')); + + if(! $mimetype) { + $mimetype = 'choose'; + } + + $x = array( + 'webpage' => ITEM_TYPE_BLOCK, + 'is_owner' => true, + 'nickname' => \App::$profile['channel_address'], + 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'bang' => '', + 'showacl' => false, + 'visitor' => true, + 'mimetype' => $mimetype, + 'ptlabel' => t('Block Name'), + 'profile_uid' => intval($owner), + 'expanded' => true, + 'novoting' => true, + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + + if($_REQUEST['title']) + $x['title'] = $_REQUEST['title']; + if($_REQUEST['body']) + $x['body'] = $_REQUEST['body']; + if($_REQUEST['pagetitle']) + $x['pagetitle'] = $_REQUEST['pagetitle']; + + $editor = status_editor($a,$x); + + $r = q("select iid, sid, mid, title, body, mimetype, created, edited from item_id left join item on item_id.iid = item.id + where item_id.uid = %d and service = 'BUILDBLOCK' and item_type = %d order by item.created desc", + intval($owner), + intval(ITEM_TYPE_BLOCK) + ); + + $pages = null; + + if($r) { + $pages = array(); + foreach($r as $rr) { + $element_arr = array( + 'type' => 'block', + 'title' => $rr['title'], + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'pagetitle' => $rr['sid'], + 'mid' => $rr['mid'] + ); + $pages[$rr['iid']][] = array( + 'url' => $rr['iid'], + 'name' => $rr['sid'], + 'title' => $rr['title'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]' + ); + } + } + + //Build the base URL for edit links + $url = z_root() . '/editblock/' . $which; + + $o .= replace_macros(get_markup_template('blocklist.tpl'), array( + '$baseurl' => $url, + '$title' => t('Blocks'), + '$name' => t('Block Name'), + '$blocktitle' => t('Block Title'), + '$created' => t('Created'), + '$edited' => t('Edited'), + '$create' => t('Create'), + '$edit' => t('Edit'), + '$share' => t('Share'), + '$delete' => t('Delete'), + '$editor' => $editor, + '$pages' => $pages, + '$channel' => $which, + '$view' => t('View'), + '$preview' => '1', + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Bookmarks.php b/Zotlabs/Module/Bookmarks.php new file mode 100644 index 000000000..733bfd4e3 --- /dev/null +++ b/Zotlabs/Module/Bookmarks.php @@ -0,0 +1,105 @@ +'; + + $o .= '

    ' . t('My Bookmarks') . '

    '; + + $x = menu_list(local_channel(),'',MENU_BOOKMARK); + + if($x) { + foreach($x as $xx) { + $y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash()); + $o .= menu_render($y,'',true); + } + } + + $o .= '

    ' . t('My Connections Bookmarks') . '

    '; + + + $x = menu_list(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK); + + if($x) { + foreach($x as $xx) { + $y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash()); + $o .= menu_render($y,'',true); + } + } + + $o .= ''; + + return $o; + + } + + +} diff --git a/Zotlabs/Module/Branchtopic.php b/Zotlabs/Module/Branchtopic.php new file mode 100644 index 000000000..87a1a43e9 --- /dev/null +++ b/Zotlabs/Module/Branchtopic.php @@ -0,0 +1,47 @@ + 1) + $item_id = intval(argv(1)); + + if(! $item_id) + return; + + $channel = \App::get_channel(); + + if(! $channel) + return; + + + $r = q("select * from item where id = %d and uid = %d and owner_xchan = '%s' and id != parent limit 1", + intval($item_id), + intval(local_channel()), + dbesc($channel['channel_hash']) + ); + + if(! $r) + return; + + $p = q("select * from item where id = %d and uid = %d limit 1", + intval($r[0]['parent']), + intval(local_channel()) + ); + + $x = q("update item set parent = id, route = '', item_thread_top = 1 where id = %d", + intval($item_id) + ); + + return; + } + +} diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php new file mode 100644 index 000000000..89967bca1 --- /dev/null +++ b/Zotlabs/Module/Cal.php @@ -0,0 +1,357 @@ + 1) { + $nick = argv(1); + + profile_load($a,$nick); + + $channelx = channelx_by_nick($nick); + + if(! $channelx) + return; + + \App::$data['channel'] = $channelx; + + $observer = \App::get_observer(); + \App::$data['observer'] = $observer; + + $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); + + head_set_icon(\App::$data['channel']['xchan_photo_s']); + + \App::$page['htmlhead'] .= "" ; + + } + + return; + } + + + + function get() { + + if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + return; + } + + + $channel = null; + + if(argc() > 1) { + $channel = channelx_by_nick(argv(1)); + } + + + if(! $channel) { + notice( t('Channel not found.') . EOL); + return; + } + + // since we don't currently have an event permission - use the stream permission + + if(! perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_stream')) { + notice( t('Permissions denied.') . EOL); + return; + } + + $sql_extra = permissions_sql($channel['channel_id'],get_observer_hash(),'event'); + + $first_day = get_pconfig(local_channel(),'system','cal_first_day'); + $first_day = (($first_day) ? $first_day : 0); + + $htpl = get_markup_template('event_head.tpl'); + \App::$page['htmlhead'] .= replace_macros($htpl,array( + '$baseurl' => z_root(), + '$module_url' => '/cal/' . $channel['channel_address'], + '$modparams' => 2, + '$lang' => \App::$language, + '$first_day' => $first_day + )); + + $o = ''; + + $tabs = profile_tabs($a, True, $channel['channel_address']); + + $mode = 'view'; + $y = 0; + $m = 0; + $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : ''); + + // logger('args: ' . print_r(\App::$argv,true)); + + if(argc() > 3 && intval(argv(2)) && intval(argv(3))) { + $mode = 'view'; + $y = intval(argv(2)); + $m = intval(argv(3)); + } + if(argc() <= 3) { + $mode = 'view'; + $event_id = argv(2); + } + + if($mode == 'view') { + + /* edit/create form */ + if($event_id) { + $r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1", + dbesc($event_id), + intval($channel['channel_id']) + ); + if(count($r)) + $orig_event = $r[0]; + } + + + // Passed parameters overrides anything found in the DB + if(!x($orig_event)) + $orig_event = array(); + + + + $tz = date_default_timezone_get(); + if(x($orig_event)) + $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC'); + + $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); + $smonth = datetime_convert('UTC', $tz, $sdt, 'm'); + $sday = datetime_convert('UTC', $tz, $sdt, 'd'); + $shour = datetime_convert('UTC', $tz, $sdt, 'H'); + $sminute = datetime_convert('UTC', $tz, $sdt, 'i'); + + $stext = datetime_convert('UTC',$tz,$sdt); + $stext = substr($stext,0,14) . "00:00"; + + $fyear = datetime_convert('UTC', $tz, $fdt, 'Y'); + $fmonth = datetime_convert('UTC', $tz, $fdt, 'm'); + $fday = datetime_convert('UTC', $tz, $fdt, 'd'); + $fhour = datetime_convert('UTC', $tz, $fdt, 'H'); + $fminute = datetime_convert('UTC', $tz, $fdt, 'i'); + + $ftext = datetime_convert('UTC',$tz,$fdt); + $ftext = substr($ftext,0,14) . "00:00"; + + $type = ((x($orig_event)) ? $orig_event['type'] : 'event'); + + $f = get_config('system','event_input_format'); + if(! $f) + $f = 'ymd'; + + $catsenabled = feature_enabled($channel['channel_id'],'categories'); + + + $show_bd = perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts'); + if(! $show_bd) { + $sql_extra .= " and event.type != 'birthday' "; + } + + + $category = ''; + + $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); + $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m'); + if(! $y) + $y = intval($thisyear); + if(! $m) + $m = intval($thismonth); + + // Put some limits on dates. The PHP date functions don't seem to do so well before 1900. + // An upper limit was chosen to keep search engines from exploring links millions of years in the future. + + if($y < 1901) + $y = 1900; + if($y > 2099) + $y = 2100; + + $nextyear = $y; + $nextmonth = $m + 1; + if($nextmonth > 12) { + $nextmonth = 1; + $nextyear ++; + } + + $prevyear = $y; + if($m > 1) + $prevmonth = $m - 1; + else { + $prevmonth = 12; + $prevyear --; + } + + $dim = get_dim($y,$m); + $start = sprintf('%d-%d-%d %d:%d:%d',$y,$m,1,0,0,0); + $finish = sprintf('%d-%d-%d %d:%d:%d',$y,$m,$dim,23,59,59); + + + if (argv(2) === 'json'){ + if (x($_GET,'start')) $start = $_GET['start']; + if (x($_GET,'end')) $finish = $_GET['end']; + } + + $start = datetime_convert('UTC','UTC',$start); + $finish = datetime_convert('UTC','UTC',$finish); + + $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); + $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); + + if (x($_GET,'id')){ + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1", + intval($channel['channel_id']), + intval($_GET['id']) + ); + } + else { + // fixed an issue with "nofinish" events not showing up in the calendar. + // There's still an issue if the finish date crosses the end of month. + // Noting this for now - it will need to be fixed here and in Friendica. + // Ultimately the finish date shouldn't be involved in the query. + + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on event_hash = resource_id + where resource_type = 'event' and event.uid = %d $ignored + AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' ) + OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) $sql_extra ", + intval($channel['channel_id']), + dbesc($start), + dbesc($finish), + dbesc($adjust_start), + dbesc($adjust_finish) + ); + + } + + $links = array(); + + if($r) { + xchan_query($r); + $r = fetch_post_tags($r,true); + + $r = sort_by_date($r); + } + + if($r) { + foreach($r as $rr) { + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + if(! x($links,$j)) + $links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j; + } + } + + $events=array(); + + $last_date = ''; + $fmt = t('l, F j'); + + if($r) { + + foreach($r as $rr) { + + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt)); + $d = day_translate($d); + + $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c')); + if ($rr['nofinish']){ + $end = null; + } else { + $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c')); + } + + + $is_first = ($d !== $last_date); + + $last_date = $d; + + $edit = false; + + $drop = false; + + $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8')); + if(! $title) { + list($title, $_trash) = explode("$rr['id'], + 'hash' => $rr['event_hash'], + 'start'=> $start, + 'end' => $end, + 'drop' => $drop, + 'allDay' => false, + 'title' => $title, + + 'j' => $j, + 'd' => $d, + 'edit' => $edit, + 'is_first'=>$is_first, + 'item'=>$rr, + 'html'=>$html, + 'plink' => array($rr['plink'],t('Link to Source'),'',''), + ); + + + } + } + + if (argv(2) === 'json'){ + echo json_encode($events); killme(); + } + + // links: array('href', 'text', 'extra css classes', 'title') + if (x($_GET,'id')){ + $tpl = get_markup_template("event_cal.tpl"); + } + else { + $tpl = get_markup_template("events_cal-js.tpl"); + } + + $nick = $channel['channel_address']; + + $o = replace_macros($tpl, array( + '$baseurl' => z_root(), + '$new_event' => array(z_root().'/cal',(($event_id) ? t('Edit Event') : t('Create Event')),'',''), + '$previus' => array(z_root()."/cal/$nick/$prevyear/$prevmonth",t('Previous'),'',''), + '$next' => array(z_root()."/cal/$nick/$nextyear/$nextmonth",t('Next'),'',''), + '$export' => array(z_root()."/cal/$nick/$y/$m/export",t('Export'),'',''), + '$calendar' => cal($y,$m,$links, ' eventcal'), + '$events' => $events, + '$upload' => t('Import'), + '$submit' => t('Submit'), + '$prev' => t('Previous'), + '$next' => t('Next'), + '$today' => t('Today'), + '$form' => $form, + '$expandform' => ((x($_GET,'expandform')) ? true : false), + '$tabs' => $tabs + )); + + if (x($_GET,'id')){ echo $o; killme(); } + + return $o; + } + + } + +} diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php new file mode 100644 index 000000000..f70444816 --- /dev/null +++ b/Zotlabs/Module/Chanview.php @@ -0,0 +1,110 @@ + $url, + // '$full' => t('toggle full screen mode') + // )); + + // return $o; + + } + +} diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php new file mode 100644 index 000000000..9508ed3de --- /dev/null +++ b/Zotlabs/Module/Chat.php @@ -0,0 +1,261 @@ + 1) + $which = argv(1); + if(! $which) { + if(local_channel()) { + $channel = \App::get_channel(); + if($channel && $channel['channel_address']) + $which = $channel['channel_address']; + } + } + if(! $which) { + notice( t('You must be logged in to see this page.') . EOL ); + return; + } + + $profile = 0; + $channel = \App::get_channel(); + + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + \App::$page['htmlhead'] .= '' . "\r\n" ; + + // Run profile_load() here to make sure the theme is set before + // we start loading content + + profile_load($a,$which,$profile); + + } + + function post() { + + if($_POST['room_name']) + $room = strip_tags(trim($_POST['room_name'])); + + if((! $room) || (! local_channel())) + return; + + $channel = \App::get_channel(); + + + if($_POST['action'] === 'drop') { + logger('delete chatroom'); + chatroom_destroy($channel,array('cr_name' => $room)); + goaway(z_root() . '/chat/' . $channel['channel_address']); + } + + $acl = new \Zotlabs\Access\AccessList($channel); + $acl->set_from_array($_REQUEST); + + $arr = $acl->get(); + $arr['name'] = $room; + $arr['expire'] = intval($_POST['chat_expire']); + if(intval($arr['expire']) < 0) + $arr['expire'] = 0; + + chatroom_create($channel,$arr); + + $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1", + dbesc($room), + intval(local_channel()) + ); + + build_sync_packet(0, array('chatroom' => $x)); + + if($x) + goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']); + + // that failed. Try again perhaps? + + goaway(z_root() . '/chat/' . $channel['channel_address'] . '/new'); + + + } + + + function get() { + + if(local_channel()) + $channel = \App::get_channel(); + + $ob = \App::get_observer(); + $observer = get_observer_hash(); + if(! $observer) { + notice( t('Permission denied.') . EOL); + return; + } + + if(! perm_is_allowed(\App::$profile['profile_uid'],$observer,'chat')) { + notice( t('Permission denied.') . EOL); + return; + } + + if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) { + chatroom_leave($observer,argv(2),$_SERVER['REMOTE_ADDR']); + goaway(z_root() . '/channel/' . argv(1)); + } + + + if((argc() > 3) && intval(argv(2)) && (argv(3) === 'status')) { + $ret = array('success' => false); + $room_id = intval(argv(2)); + if(! $room_id || ! $observer) + return; + + $r = q("select * from chatroom where cr_id = %d limit 1", + intval($room_id) + ); + if(! $r) { + json_return_and_die($ret); + } + require_once('include/security.php'); + $sql_extra = permissions_sql($r[0]['cr_uid']); + + $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", + intval($room_id), + intval($r[0]['cr_uid']) + ); + if(! $x) { + json_return_and_die($ret); + } + $y = q("select count(*) as total from chatpresence where cp_room = %d", + intval($room_id) + ); + if($y) { + $ret['success'] = true; + $ret['chatroom'] = $r[0]['cr_name']; + $ret['inroom'] = $y[0]['total']; + } + + // figure out how to present a timestamp of the last activity, since we don't know the observer's timezone. + + $z = q("select created from chat where chat_room = %d order by created desc limit 1", + intval($room_id) + ); + if($z) { + $ret['last'] = $z[0]['created']; + } + json_return_and_die($ret); + } + + + if(argc() > 2 && intval(argv(2))) { + + $room_id = intval(argv(2)); + $bookmark_link = get_bookmark_link($ob); + + $x = chatroom_enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']); + if(! $x) + return; + $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", + intval($room_id), + intval(\App::$profile['profile_uid']) + ); + + if($x) { + $acl = new \Zotlabs\Access\AccessList(false); + $acl->set($x[0]); + + $private = $acl->is_private(); + $room_name = $x[0]['cr_name']; + if($bookmark_link) + $bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . (($private) ? '&private=1' : '') . '&ischat=1'; + } + else { + notice( t('Room not found') . EOL); + return; + } + + $cipher = get_pconfig(local_channel(),'system','default_cipher'); + if(! $cipher) + $cipher = 'aes256'; + + + $o = replace_macros(get_markup_template('chat.tpl'),array( + '$is_owner' => ((local_channel() && local_channel() == $x[0]['cr_uid']) ? true : false), + '$room_name' => $room_name, + '$room_id' => $room_id, + '$baseurl' => z_root(), + '$nickname' => argv(1), + '$submit' => t('Submit'), + '$leave' => t('Leave Room'), + '$drop' => t('Delete Room'), + '$away' => t('I am away right now'), + '$online' => t('I am online'), + '$bookmark_link' => $bookmark_link, + '$bookmark' => t('Bookmark this room'), + '$feature_encrypt' => ((feature_enabled(local_channel(),'content_encrypt')) ? true : false), + '$cipher' => $cipher, + '$linkurl' => t('Please enter a link URL:'), + '$encrypt' => t('Encrypt text'), + '$insert' => t('Insert web link') + )); + return $o; + } + + + require_once('include/conversation.php'); + + $o = profile_tabs($a,((local_channel() && local_channel() == \App::$profile['profile_uid']) ? true : false),\App::$profile['channel_address']); + + if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat')) { + notice( t('Feature disabled.') . EOL); + return $o; + } + + + $acl = new \Zotlabs\Access\AccessList($channel); + $channel_acl = $acl->get(); + + $lockstate = (($channel_acl['allow_cid'] || $channel_acl['allow_gid'] || $channel_acl['deny_cid'] || $channel_acl['deny_gid']) ? 'lock' : 'unlock'); + require_once('include/acl_selectors.php'); + + $chatroom_new = ''; + if(local_channel()) { + $chatroom_new = replace_macros(get_markup_template('chatroom_new.tpl'),array( + '$header' => t('New Chatroom'), + '$name' => array('room_name',t('Chatroom name'),'', ''), + '$chat_expire' => array('chat_expire',t('Expiration of chats (minutes)'),120,''), + '$permissions' => t('Permissions'), + '$acl' => populate_acl($channel_acl,false), + '$lockstate' => $lockstate, + '$submit' => t('Submit') + + )); + } + + $rooms = chatroom_list(\App::$profile['profile_uid']); + + $o .= replace_macros(get_markup_template('chatrooms.tpl'), array( + '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['name']), + '$name' => t('Name'), + '$baseurl' => z_root(), + '$nickname' => \App::$profile['channel_address'], + '$rooms' => $rooms, + '$norooms' => t('No chatrooms available'), + '$newroom' => t('Create New'), + '$is_owner' => ((local_channel() && local_channel() == \App::$profile['profile_uid']) ? 1 : 0), + '$chatroom_new' => $chatroom_new, + '$expire' => t('Expiration'), + '$expire_unit' => t('min') //minutes + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php new file mode 100644 index 000000000..a9bc97301 --- /dev/null +++ b/Zotlabs/Module/Chatsvc.php @@ -0,0 +1,168 @@ + false); + + \App::$data['chat']['room_id'] = intval($_REQUEST['room_id']); + $x = q("select cr_uid from chatroom where cr_id = %d and cr_id != 0 limit 1", + intval(\App::$data['chat']['room_id']) + ); + if(! $x) + json_return_and_die($ret); + + \App::$data['chat']['uid'] = $x[0]['cr_uid']; + + if(! perm_is_allowed(\App::$data['chat']['uid'],get_observer_hash(),'chat')) { + json_return_and_die($ret); + } + + } + + function post() { + + $ret = array('success' => false); + + $room_id = \App::$data['chat']['room_id']; + $text = escape_tags($_REQUEST['chat_text']); + if(! $text) + return; + + $sql_extra = permissions_sql(\App::$data['chat']['uid']); + + $r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra", + intval(\App::$data['chat']['uid']), + intval(\App::$data['chat']['room_id']) + ); + if(! $r) + json_return_and_die($ret); + + $arr = array( + 'chat_room' => \App::$data['chat']['room_id'], + 'chat_xchan' => get_observer_hash(), + 'chat_text' => $text + ); + + call_hooks('chat_post',$arr); + + $x = q("insert into chat ( chat_room, chat_xchan, created, chat_text ) + values( %d, '%s', '%s', '%s' )", + intval(\App::$data['chat']['room_id']), + dbesc(get_observer_hash()), + dbesc(datetime_convert()), + dbesc($arr['chat_text']) + ); + + $ret['success'] = true; + json_return_and_die($ret); + } + + function get() { + + $status = strip_tags($_REQUEST['status']); + $room_id = intval(\App::$data['chat']['room_id']); + $stopped = ((x($_REQUEST,'stopped') && intval($_REQUEST['stopped'])) ? true : false); + + if($status && $room_id) { + + $x = q("select channel_address from channel where channel_id = %d limit 1", + intval(\App::$data['chat']['uid']) + ); + + $r = q("update chatpresence set cp_status = '%s', cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s'", + dbesc($status), + dbesc(datetime_convert()), + intval($room_id), + dbesc(get_observer_hash()), + dbesc($_SERVER['REMOTE_ADDR']) + ); + + goaway(z_root() . '/chat/' . $x[0]['channel_address'] . '/' . $room_id); + } + + if(! $stopped) { + + $lastseen = intval($_REQUEST['last']); + + $ret = array('success' => false); + + $sql_extra = permissions_sql(\App::$data['chat']['uid']); + + $r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra", + intval(\App::$data['chat']['uid']), + intval(\App::$data['chat']['room_id']) + ); + if(! $r) + json_return_and_die($ret); + + $inroom = array(); + + $r = q("select * from chatpresence left join xchan on xchan_hash = cp_xchan where cp_room = %d order by xchan_name", + intval(\App::$data['chat']['room_id']) + ); + if($r) { + foreach($r as $rr) { + switch($rr['cp_status']) { + case 'away': + $status = t('Away'); + $status_class = 'away'; + break; + case 'online': + default: + $status = t('Online'); + $status_class = 'online'; + break; + } + + $inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'],'name' => $rr['xchan_name'], 'status' => $status, 'status_class' => $status_class); + } + } + + $chats = array(); + + $r = q("select * from chat left join xchan on chat_xchan = xchan_hash where chat_room = %d and chat_id > %d order by created", + intval(\App::$data['chat']['room_id']), + intval($lastseen) + ); + if($r) { + foreach($r as $rr) { + $chats[] = array( + 'id' => $rr['chat_id'], + 'img' => zid($rr['xchan_photo_m']), + 'img_type' => $rr['xchan_photo_mimetype'], + 'name' => $rr['xchan_name'], + 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'), + 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'), + 'text' => smilies(bbcode($rr['chat_text'])), + 'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '') + ); + } + } + } + + $r = q("update chatpresence set cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s'", + dbesc(datetime_convert()), + intval(\App::$data['chat']['room_id']), + dbesc(get_observer_hash()), + dbesc($_SERVER['REMOTE_ADDR']) + ); + + $ret['success'] = true; + if(! $stopped) { + $ret['inroom'] = $inroom; + $ret['chats'] = $chats; + } + json_return_and_die($ret); + + } + + +} diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php new file mode 100644 index 000000000..0e04cb68b --- /dev/null +++ b/Zotlabs/Module/Cloud.php @@ -0,0 +1,110 @@ + 1) + $which = argv(1); + + $profile = 0; + + \App::$page['htmlhead'] .= '' . "\r\n"; + + if ($which) + profile_load($a, $which, $profile); + + $auth = new \Zotlabs\Storage\BasicAuth(); + + $ob_hash = get_observer_hash(); + + if ($ob_hash) { + if (local_channel()) { + $channel = \App::get_channel(); + $auth->setCurrentUser($channel['channel_address']); + $auth->channel_id = $channel['channel_id']; + $auth->channel_hash = $channel['channel_hash']; + $auth->channel_account_id = $channel['channel_account_id']; + if($channel['channel_timezone']) + $auth->setTimezone($channel['channel_timezone']); + } + $auth->observer = $ob_hash; + } + + if ($_GET['davguest']) + $_SESSION['davguest'] = true; + + $_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); + + // A SabreDAV server-object + $server = new DAV\Server($rootDirectory); + // prevent overwriting changes each other with a lock backend + $lockBackend = new DAV\Locks\Backend\File('store/[data]/locks'); + $lockPlugin = new DAV\Locks\Plugin($lockBackend); + + $server->addPlugin($lockPlugin); + + $is_readable = false; + + if($_SERVER['REQUEST_METHOD'] === 'GET') { + try { + $x = RedFileData('/' . \App::$cmd, $auth); + } + catch(\Exception $e) { + if($e instanceof Sabre\DAV\Exception\Forbidden) { + http_status_exit(401, 'Permission denied.'); + } + } + } + + // require_once('\Zotlabs/Storage/Browser.php'); + // provide a directory view for the cloud in Hubzilla + $browser = new \Zotlabs\Storage\Browser($auth); + $auth->setBrowserPlugin($browser); + + $server->addPlugin($browser); + + // Experimental QuotaPlugin + // require_once('\Zotlabs\Storage/QuotaPlugin.php'); + // $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth)); + + // All we need to do now, is to fire up the server + $server->exec(); + + killme(); + } + +} diff --git a/Zotlabs/Module/Common.php b/Zotlabs/Module/Common.php new file mode 100644 index 000000000..1c428d256 --- /dev/null +++ b/Zotlabs/Module/Common.php @@ -0,0 +1,73 @@ + 1 && intval(argv(1))) + $channel_id = intval(argv(1)); + else { + notice( t('No channel.') . EOL ); + \App::$error = 404; + return; + } + + $x = q("select channel_address from channel where channel_id = %d limit 1", + intval($channel_id) + ); + + if($x) + profile_load($a,$x[0]['channel_address'],0); + + } + + function get() { + + $o = ''; + + if(! \App::$profile['profile_uid']) + return; + + $observer_hash = get_observer_hash(); + + + if(! perm_is_allowed(\App::$profile['profile_uid'],$observer_hash,'view_contacts')) { + notice( t('Permission denied.') . EOL); + return; + } + + $o .= '

    ' . t('Common connections') . '

    '; + + $t = count_common_friends(\App::$profile['profile_uid'],$observer_hash); + + if(! $t) { + notice( t('No connections in common.') . EOL); + return $o; + } + + $r = common_friends(\App::$profile['profile_uid'],$observer_hash); + + if($r) { + + $tpl = get_markup_template('common_friends.tpl'); + + foreach($r as $rr) { + $o .= replace_macros($tpl,array( + '$url' => $rr['xchan_url'], + '$name' => $rr['xchan_name'], + '$photo' => $rr['xchan_photo_m'], + '$tags' => '' + )); + } + + $o .= cleardiv(); + } + + return $o; + } + +} diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php new file mode 100644 index 000000000..6ef3577d7 --- /dev/null +++ b/Zotlabs/Module/Connect.php @@ -0,0 +1,130 @@ + 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $r = q("select * from channel where channel_address = '%s' limit 1", + dbesc($which) + ); + + if($r) + \App::$data['channel'] = $r[0]; + + profile_load($a,$which,''); + } + + function post() { + + if(! array_key_exists('channel', \App::$data)) + return; + + $edit = ((local_channel() && (local_channel() == \App::$data['channel']['channel_id'])) ? true : false); + + if($edit) { + $has_premium = ((\App::$data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? 1 : 0); + $premium = (($_POST['premium']) ? intval($_POST['premium']) : 0); + $text = escape_tags($_POST['text']); + + if($has_premium != $premium) { + $r = q("update channel set channel_pageflags = ( channel_pageflags %s %d ) where channel_id = %d", + db_getfunc('^'), + intval(PAGE_PREMIUM), + intval(local_channel()) + ); + proc_run('php','include/notifier.php','refresh_all',\App::$data['channel']['channel_id']); + } + set_pconfig(\App::$data['channel']['channel_id'],'system','selltext',$text); + // reload the page completely to get fresh data + goaway(z_root() . '/' . \App::$query_string); + + } + + $url = ''; + $observer = \App::get_observer(); + if(($observer) && ($_POST['submit'] === t('Continue'))) { + if($observer['xchan_follow']) + $url = sprintf($observer['xchan_follow'],urlencode(\App::$data['channel']['channel_address'] . '@' . \App::get_hostname())); + if(! $url) { + $r = q("select * from hubloc where hubloc_hash = '%s' order by hubloc_id desc limit 1", + dbesc($observer['xchan_hash']) + ); + if($r) + $url = $r[0]['hubloc_url'] . '/follow?f=&url=' . urlencode(\App::$data['channel']['channel_address'] . '@' . \App::get_hostname()); + } + } + if($url) + goaway($url . '&confirm=1'); + else + notice('Unable to connect to your home hub location.'); + + } + + + + function get() { + + $edit = ((local_channel() && (local_channel() == \App::$data['channel']['channel_id'])) ? true : false); + + $text = get_pconfig(\App::$data['channel']['channel_id'],'system','selltext'); + + if($edit) { + + $o = replace_macros(get_markup_template('sellpage_edit.tpl'),array( + '$header' => t('Premium Channel Setup'), + '$address' => \App::$data['channel']['channel_address'], + '$premium' => array('premium', t('Enable premium channel connection restrictions'),((\App::$data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? '1' : ''),''), + '$lbl_about' => t('Please enter your restrictions or conditions, such as paypal receipt, usage guidelines, etc.'), + '$text' => $text, + '$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'), + '$lbl2' => t('Potential connections will then see the following text before proceeding:'), + '$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'), + '$submit' => t('Submit'), + + + )); + return $o; + } + else { + if(! $text) + $text = t('(No specific instructions have been provided by the channel owner.)'); + + $submit = replace_macros(get_markup_template('sellpage_submit.tpl'), array( + '$continue' => t('Continue'), + '$address' => \App::$data['channel']['channel_address'] + )); + + $o = replace_macros(get_markup_template('sellpage_view.tpl'),array( + '$header' => t('Restricted or Premium Channel'), + '$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'), + '$text' => prepare_text($text), + + '$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'), + '$submit' => $submit, + + )); + + $arr = array('channel' => \App::$data['channel'],'observer' => \App::get_observer(), 'sellpage' => $o, 'submit' => $submit); + call_hooks('connect_premium', $arr); + $o = $arr['sellpage']; + + } + + return $o; + } +} diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php new file mode 100644 index 000000000..564f4e527 --- /dev/null +++ b/Zotlabs/Module/Connections.php @@ -0,0 +1,324 @@ + t('Suggestions'), + 'url' => z_root() . '/suggest', + 'sel' => '', + 'title' => t('Suggest new connections'), + ), + */ + + 'pending' => array( + 'label' => t('New Connections'), + 'url' => z_root() . '/connections/pending', + 'sel' => ($pending) ? 'active' : '', + 'title' => t('Show pending (new) connections'), + ), + + 'all' => array( + 'label' => t('All Connections'), + 'url' => z_root() . '/connections/all', + 'sel' => ($all) ? 'active' : '', + 'title' => t('Show all connections'), + ), + + /* + array( + 'label' => t('Unblocked'), + 'url' => z_root() . '/connections', + 'sel' => (($unblocked) && (! $search) && (! $nets)) ? 'active' : '', + 'title' => t('Only show unblocked connections'), + ), + */ + + 'blocked' => array( + 'label' => t('Blocked'), + 'url' => z_root() . '/connections/blocked', + 'sel' => ($blocked) ? 'active' : '', + 'title' => t('Only show blocked connections'), + ), + + 'ignored' => array( + 'label' => t('Ignored'), + 'url' => z_root() . '/connections/ignored', + 'sel' => ($ignored) ? 'active' : '', + 'title' => t('Only show ignored connections'), + ), + + 'archived' => array( + 'label' => t('Archived'), + 'url' => z_root() . '/connections/archived', + 'sel' => ($archived) ? 'active' : '', + 'title' => t('Only show archived connections'), + ), + + 'hidden' => array( + 'label' => t('Hidden'), + 'url' => z_root() . '/connections/hidden', + 'sel' => ($hidden) ? 'active' : '', + 'title' => t('Only show hidden connections'), + ), + + // array( + // 'label' => t('Unconnected'), + // 'url' => z_root() . '/connections/unconnected', + // 'sel' => ($unconnected) ? 'active' : '', + // 'title' => t('Only show one-way connections'), + // ), + + + ); + + //$tab_tpl = get_markup_template('common_tabs.tpl'); + //$t = replace_macros($tab_tpl, array('$tabs'=>$tabs)); + + $searching = false; + if($search) { + $search_hdr = $search; + $search_txt = dbesc(protect_sprintf(preg_quote($search))); + $searching = true; + } + $sql_extra .= (($searching) ? protect_sprintf(" AND xchan_name like '%$search_txt%' ") : ""); + + if($_REQUEST['gid']) { + $sql_extra .= " and xchan_hash in ( select xchan from group_member where gid = " . intval($_REQUEST['gid']) . " and uid = " . intval(local_channel()) . " ) "; + } + + $r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash + where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ", + intval(local_channel()) + ); + if($r) { + \App::set_pager_total($r[0]['total']); + $total = $r[0]['total']; + } + + $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash + WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ORDER BY xchan_name LIMIT %d OFFSET %d ", + intval(local_channel()), + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + $contacts = array(); + + if(count($r)) { + + foreach($r as $rr) { + if($rr['xchan_url']) { + + $status_str = ''; + $status = array( + ((intval($rr['abook_pending'])) ? t('Pending approval') : ''), + ((intval($rr['abook_archived'])) ? t('Archived') : ''), + ((intval($rr['abook_hidden'])) ? t('Hidden') : ''), + ((intval($rr['abook_ignored'])) ? t('Ignored') : ''), + ((intval($rr['abook_blocked'])) ? t('Blocked') : '') + ); + + foreach($status as $str) { + if(!$str) + continue; + $status_str .= $str; + $status_str .= ', '; + } + $status_str = rtrim($status_str, ', '); + + $contacts[] = array( + 'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']), + 'edit_hover' => t('Edit connection'), + 'delete_hover' => t('Delete connection'), + 'id' => $rr['abook_id'], + 'thumb' => $rr['xchan_photo_m'], + 'name' => $rr['xchan_name'], + 'classes' => (intval($rr['abook_archived']) ? 'archived' : ''), + 'link' => z_root() . '/connedit/' . $rr['abook_id'], + 'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop', + 'delete' => t('Delete'), + 'url' => chanlink_url($rr['xchan_url']), + 'webbie_label' => t('Channel address'), + 'webbie' => $rr['xchan_addr'], + 'network_label' => t('Network'), + 'network' => network_to_name($rr['xchan_network']), + 'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false), + 'status_label' => t('Status'), + 'status' => $status_str, + 'connected_label' => t('Connected'), + 'connected' => datetime_convert('UTC',date_default_timezone_get(),$rr['abook_created'], 'c'), + 'approve_hover' => t('Approve connection'), + 'approve' => (($rr['abook_pending']) ? t('Approve') : false), + 'ignore_hover' => t('Ignore connection'), + 'ignore' => ((! $rr['abook_ignored']) ? t('Ignore') : false), + 'recent_label' => t('Recent activity'), + 'recentlink' => z_root() . '/network/?f=&cid=' . intval($rr['abook_id']) + ); + } + } + } + + + if($_REQUEST['aj']) { + if($contacts) { + $o = replace_macros(get_markup_template('contactsajax.tpl'),array( + '$contacts' => $contacts, + '$edit' => t('Edit'), + )); + } + else { + $o = '
    '; + } + echo $o; + killme(); + } + else { + $o .= ""; + $o .= replace_macros(get_markup_template('connections.tpl'),array( + '$header' => t('Connections') . (($head) ? ': ' . $head : ''), + '$tabs' => $tabs, + '$total' => $total, + '$search' => $search_hdr, + '$label' => t('Search'), + '$desc' => t('Search your connections'), + '$finding' => (($searching) ? t('Connections search') . ": '" . $search . "'" : ""), + '$submit' => t('Find'), + '$edit' => t('Edit'), + '$cmd' => \App::$cmd, + '$contacts' => $contacts, + '$paginate' => paginate($a), + + )); + } + + if(! $contacts) + $o .= '
    '; + + return $o; + } + +} diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php new file mode 100644 index 000000000..2b524096f --- /dev/null +++ b/Zotlabs/Module/Connedit.php @@ -0,0 +1,762 @@ += 2) && intval(argv(1))) { + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_id = %d LIMIT 1", + intval(local_channel()), + intval(argv(1)) + ); + if($r) { + \App::$poi = $r[0]; + } + } + + $channel = \App::get_channel(); + if($channel) + head_set_icon($channel['xchan_photo_s']); + + } + + /* @brief Evaluate posted values and set changes + * + */ + + function post() { + + if(! local_channel()) + return; + + $contact_id = intval(argv(1)); + if(! $contact_id) + return; + + $channel = \App::get_channel(); + + // TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the + // connection enable is toggled to a special autopost url and set permissions immediately, leaving + // the other form elements alone pending a manual submit of the form. The downside is that there + // will be a window of opportunity when the permissions have been set but before you've had a chance + // to review and possibly restrict them. The upside is we won't have to warn you that your connection + // can't do anything until you save the bloody form. + + $autopost = (((argc() > 2) && (argv(2) === 'auto')) ? true : false); + + $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", + intval($contact_id), + intval(local_channel()) + ); + + if(! $orig_record) { + notice( t('Could not access contact record.') . EOL); + goaway(z_root() . '/connections'); + return; // NOTREACHED + } + + call_hooks('contact_edit_post', $_POST); + + if(intval($orig_record[0]['abook_self'])) { + $autoperms = intval($_POST['autoperms']); + $is_self = true; + } + else { + $autoperms = null; + $is_self = false; + } + + + $profile_id = $_POST['profile_assign']; + if($profile_id) { + $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", + dbesc($profile_id), + intval(local_channel()) + ); + if(! count($r)) { + notice( t('Could not locate selected profile.') . EOL); + return; + } + } + + $abook_incl = escape_tags($_POST['abook_incl']); + $abook_excl = escape_tags($_POST['abook_excl']); + + $hidden = intval($_POST['hidden']); + + $priority = intval($_POST['poll']); + if($priority > 5 || $priority < 0) + $priority = 0; + + $closeness = intval($_POST['closeness']); + if($closeness < 0) + $closeness = 99; + + $rating = intval($_POST['rating']); + if($rating < (-10)) + $rating = (-10); + if($rating > 10) + $rating = 10; + + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); + + $abook_my_perms = 0; + + foreach($_POST as $k => $v) { + if(strpos($k,'perms_') === 0) { + $abook_my_perms += $v; + } + } + + $new_friend = false; + + if(! $is_self) { + + $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text; + + $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); + + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc($orig_record[0]['abook_xchan']) + ); + + if($z) { + $record = $z[0]['xlink_id']; + $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s' + where xlink_id = %d", + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()), + intval($record) + ); + } + else { + $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", + dbesc($channel['channel_hash']), + dbesc($orig_record[0]['abook_xchan']), + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()) + ); + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc($orig_record[0]['abook_xchan']) + ); + if($z) + $record = $z[0]['xlink_id']; + } + if($record) { + proc_run('php','include/ratenotif.php','rating',$record); + } + } + + if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) { + $new_friend = true; + + // @fixme it won't be common, but when you accept a new connection request + // the permissions will now be that of your permissions role and ignore + // any you may have set manually on the form. We'll probably see a bug if somebody + // tries to set the permissions *and* approve the connection in the same + // request. The workaround is to approve the connection, then go back and + // adjust permissions as desired. + + $abook_my_perms = get_channel_default_perms(local_channel()); + + $role = get_pconfig(local_channel(),'system','permissions_role'); + if($role) { + $x = get_role_perms($role); + if($x['perms_accept']) + $abook_my_perms = $x['perms_accept']; + } + } + + $abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']); + + $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_pending = %d, + abook_incl = '%s', abook_excl = '%s' + where abook_id = %d AND abook_channel = %d", + dbesc($profile_id), + intval($abook_my_perms), + intval($closeness), + intval($abook_pending), + dbesc($abook_incl), + dbesc($abook_excl), + intval($contact_id), + intval(local_channel()) + ); + + if($orig_record[0]['abook_profile'] != $profile_id) { + //Update profile photo permissions + + logger('A new profile was assigned - updating profile photos'); + profile_photo_set_profile_perms($profile_id); + + } + + if($r) + info( t('Connection updated.') . EOL); + else + notice( t('Failed to update connection record.') . EOL); + + if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms + && (! intval(\App::$poi['abook_self']))) { + proc_run('php', 'include/notifier.php', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id); + } + + if($new_friend) { + $default_group = $channel['channel_default_group']; + if($default_group) { + require_once('include/group.php'); + $g = group_rec_byhash(local_channel(),$default_group); + if($g) + group_add_member(local_channel(),'',\App::$poi['abook_xchan'],$g['id']); + } + + // Check if settings permit ("post new friend activity" is allowed, and + // friends in general or this friend in particular aren't hidden) + // and send out a new friend activity + + $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", + intval($channel['channel_id']) + ); + if(($pr) && (! intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'],'system','post_newfriend')))) { + $xarr = array(); + $xarr['verb'] = ACTIVITY_FRIEND; + $xarr['item_wall'] = 1; + $xarr['item_origin'] = 1; + $xarr['item_thread_top'] = 1; + $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash']; + $xarr['allow_cid'] = $channel['channel_allow_cid']; + $xarr['allow_gid'] = $channel['channel_allow_gid']; + $xarr['deny_cid'] = $channel['channel_deny_cid']; + $xarr['deny_gid'] = $channel['channel_deny_gid']; + $xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0); + $obj = array( + 'type' => ACTIVITY_OBJ_PERSON, + 'title' => \App::$poi['xchan_name'], + 'id' => \App::$poi['xchan_hash'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => \App::$poi['xchan_url']), + array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l']) + ), + ); + $xarr['object'] = json_encode($obj); + $xarr['obj_type'] = ACTIVITY_OBJ_PERSON; + + $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]'; + + $xarr['body'] .= "\n\n\n" . '[zrl=' . \App::$poi['xchan_url'] . '][zmg=80x80]' . \App::$poi['xchan_photo_m'] . '[/zmg][/zrl]'; + + post_activity_item($xarr); + + } + + + // pull in a bit of content if there is any to pull in + proc_run('php','include/onepoll.php',$contact_id); + + } + + // Refresh the structure in memory with the new data + + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_id = %d LIMIT 1", + intval(local_channel()), + intval($contact_id) + ); + if($r) { + \App::$poi = $r[0]; + } + + if($new_friend) { + $arr = array('channel_id' => local_channel(), 'abook' => \App::$poi); + call_hooks('accept_follow', $arr); + } + + if(! is_null($autoperms)) + set_pconfig(local_channel(),'system','autoperms',(($autoperms) ? $abook_my_perms : 0)); + + $this->connedit_clone($a); + + if(($_REQUEST['pending']) && (!$_REQUEST['done'])) + goaway(z_root() . '/connections/ifpending'); + + return; + + } + + /* @brief Clone connection + * + * + */ + + function connedit_clone(&$a) { + + if(! \App::$poi) + return; + + + $channel = \App::get_channel(); + + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_id = %d LIMIT 1", + intval(local_channel()), + intval(\App::$poi['abook_id']) + ); + if($r) { + \App::$poi = $r[0]; + } + + $clone = \App::$poi; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + + $abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']); + if($abconfig) + $clone['abconfig'] = $abconfig; + + build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone))); + } + + /* @brief Generate content of connection edit page + * + * + */ + + function get() { + + $sort_type = 0; + $o = ''; + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return login(); + } + + $channel = \App::get_channel(); + $my_perms = get_channel_default_perms(local_channel()); + $role = get_pconfig(local_channel(),'system','permissions_role'); + if($role) { + $x = get_role_perms($role); + if($x['perms_accept']) + $my_perms = $x['perms_accept']; + } + + $yes_no = array(t('No'),t('Yes')); + + if($my_perms) { + $o .= "\n"; + } + + if(argc() == 3) { + + $contact_id = intval(argv(1)); + if(! $contact_id) + return; + + $cmd = argv(2); + + $orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_id = %d AND abook_channel = %d AND abook_self = 0 LIMIT 1", + intval($contact_id), + intval(local_channel()) + ); + + if(! count($orig_record)) { + notice( t('Could not access address book record.') . EOL); + goaway(z_root() . '/connections'); + } + + if($cmd === 'update') { + // pull feed and consume it, which should subscribe to the hub. + proc_run('php',"include/poller.php","$contact_id"); + goaway(z_root() . '/connedit/' . $contact_id); + + } + + if($cmd === 'refresh') { + if($orig_record[0]['xchan_network'] === 'zot') { + if(! zot_refresh($orig_record[0],\App::get_channel())) + notice( t('Refresh failed - channel is currently unavailable.') ); + } + else { + + // if you are on a different network we'll force a refresh of the connection basic info + proc_run('php','include/notifier.php','permission_update',$contact_id); + } + goaway(z_root() . '/connedit/' . $contact_id); + } + + if($cmd === 'block') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) { + $this->connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway(z_root() . '/connedit/' . $contact_id); + } + + if($cmd === 'ignore') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) { + $this->connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway(z_root() . '/connedit/' . $contact_id); + } + + if($cmd === 'archive') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) { + $this->connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway(z_root() . '/connedit/' . $contact_id); + } + + if($cmd === 'hide') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) { + $this->connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway(z_root() . '/connedit/' . $contact_id); + } + + // We'll prevent somebody from unapproving an already approved contact. + // Though maybe somebody will want this eventually (??) + + if($cmd === 'approve') { + if(intval($orig_record[0]['abook_pending'])) { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) { + $this->connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + } + goaway(z_root() . '/connedit/' . $contact_id); + } + + + if($cmd === 'drop') { + + require_once('include/Contact.php'); + + // FIXME + // We need to send either a purge or a refresh packet to the other side (the channel being unfriended). + // The issue is that the abook DB record _may_ get destroyed when we call contact_remove. As the notifier runs + // in the background there could be a race condition preventing this packet from being sent in all cases. + // PLACEHOLDER + + contact_remove(local_channel(), $orig_record[0]['abook_id']); + build_sync_packet(0 /* use the current local_channel */, + array('abook' => array(array( + 'abook_xchan' => $orig_record[0]['abook_xchan'], + 'entry_deleted' => true)) + ) + ); + + info( t('Connection has been removed.') . EOL ); + if(x($_SESSION,'return_url')) + goaway(z_root() . '/' . $_SESSION['return_url']); + goaway(z_root() . '/contacts'); + + } + } + + if(\App::$poi) { + + $contact_id = \App::$poi['abook_id']; + $contact = \App::$poi; + + $buttons = array( + + 'view' => array( + 'label' => t('View Profile'), + 'url' => chanlink_cid($contact['abook_id']), + 'sel' => '', + 'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']), + ), + + 'refresh' => array( + 'label' => t('Refresh Permissions'), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/refresh', + 'sel' => '', + 'title' => t('Fetch updated permissions'), + ), + + 'recent' => array( + 'label' => t('Recent Activity'), + 'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'], + 'sel' => '', + 'title' => t('View recent posts and comments'), + ), + + 'block' => array( + 'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/block', + 'sel' => (intval($contact['abook_blocked']) ? 'active' : ''), + 'title' => t('Block (or Unblock) all communications with this connection'), + 'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''), + ), + + 'ignore' => array( + 'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/ignore', + 'sel' => (intval($contact['abook_ignored']) ? 'active' : ''), + 'title' => t('Ignore (or Unignore) all inbound communications from this connection'), + 'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''), + ), + + 'archive' => array( + 'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/archive', + 'sel' => (intval($contact['abook_archived']) ? 'active' : ''), + 'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'), + 'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''), + ), + + 'hide' => array( + 'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/hide', + 'sel' => (intval($contact['abook_hidden']) ? 'active' : ''), + 'title' => t('Hide or Unhide this connection from your other connections'), + 'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''), + ), + + 'delete' => array( + 'label' => t('Delete'), + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/drop', + 'sel' => '', + 'title' => t('Delete this connection'), + ), + + ); + + $self = false; + + if(intval($contact['abook_self'])) + $self = true; + + require_once('include/contact_selectors.php'); + + $tpl = get_markup_template("abook_edit.tpl"); + + 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 . "'"; + } + } + + $slider_tpl = get_markup_template('contact_slider.tpl'); + $slide = replace_macros($slider_tpl,array( + '$min' => 1, + '$val' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 99), + '$labels' => $label_str, + )); + } + + $rating_val = 0; + $rating_text = ''; + + $xl = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", + dbesc($channel['channel_hash']), + dbesc($contact['xchan_hash']) + ); + + if($xl) { + $rating_val = intval($xl[0]['xlink_rating']); + $rating_text = $xl[0]['xlink_rating_text']; + } + + $poco_rating = get_config('system','poco_rating_enable'); + + // if unset default to enabled + if($poco_rating === false) + $poco_rating = true; + + if($poco_rating) { + $rating = replace_macros(get_markup_template('rating_slider.tpl'),array( + '$min' => -10, + '$val' => $rating_val + )); + } + else { + $rating = false; + } + + + $perms = array(); + $channel = \App::get_channel(); + + $global_perms = get_perms(); + $existing = get_all_perms(local_channel(),$contact['abook_xchan']); + + $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes'))); + + $multiprofs = ((feature_enabled(local_channel(),'multi_profiles')) ? true : false); + + if($slide && !$multiprofs) + $affinity = t('Set Affinity'); + + if(!$slide && $multiprofs) + $affinity = t('Set Profile'); + + if($slide && $multiprofs) + $affinity = t('Set Affinity & Profile'); + + foreach($global_perms as $k => $v) { + $thisperm = (($contact['abook_my_perms'] & $v[1]) ? "1" : ''); + $checkinherited = ((($channel[$v[0]]) && ($channel[$v[0]] != PERMS_SPECIFIC)) ? "1" : ''); + + // For auto permissions (when $self is true) we don't want to look at existing + // permissions because they are enabled for the channel owner + if((! $self) && ($existing[$k])) + $thisperm = "1"; + + $perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),$thisperm, $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4], $checkinherited); + } + + $locstr = ''; + + $locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' + and hubloc_deleted = 0 and site_dead = 0", + dbesc($contact['xchan_hash']) + ); + + if($locs) { + foreach($locs as $l) { + if(!($l['location'])) + continue; + if(strpos($locstr,$l['location']) !== false) + continue; + if(strlen($locstr)) + $locstr .= ', '; + $locstr .= $l['location']; + } + } + else + $locstr = t('none'); + + $o .= replace_macros($tpl,array( + + '$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])), + '$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no), + '$addr' => $contact['xchan_addr'], + '$addr_text' => t('This connection\'s primary address is'), + '$loc_text' => t('Available locations:'), + '$locstr' => $locstr, + '$notself' => (($self) ? '' : '1'), + '$self' => (($self) ? '1' : ''), + '$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'), + '$buttons' => (($self) ? '' : $buttons), + '$lbl_slider' => t('Slide to adjust your degree of friendship'), + '$lbl_rating' => t('Rating'), + '$lbl_rating_label' => t('Slide to adjust your rating'), + '$lbl_rating_txt' => t('Optionally explain your rating'), + '$connfilter' => feature_enabled(local_channel(),'connfilter'), + '$connfilter_label' => t('Custom Filter'), + '$incl' => array('abook_incl',t('Only import posts with this text'), $contact['abook_incl'],t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')), + '$excl' => array('abook_excl',t('Do not import posts with this text'), $contact['abook_excl'],t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')), + '$rating_text' => array('rating_text', t('Optionally explain your rating'),$rating_text,''), + '$rating_info' => t('This information is public!'), + '$rating' => $rating, + '$rating_val' => $rating_val, + '$slide' => $slide, + '$affinity' => $affinity, + '$pending_label' => t('Connection Pending Approval'), + '$is_pending' => (intval($contact['abook_pending']) ? 1 : ''), + '$unapproved' => $unapproved, + '$inherited' => t('inherited'), + '$submit' => t('Submit'), + '$lbl_vis2' => sprintf( t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['xchan_name']), + '$close' => $contact['abook_closeness'], + '$them' => t('Their Settings'), + '$me' => t('My Settings'), + '$perms' => $perms, + '$permlbl' => t('Individual Permissions'), + '$permnote' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can not change those settings here.'), + '$permnote_self' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'), + '$lastupdtext' => t('Last update:'), + '$last_update' => relative_date($contact['abook_connected']), + '$profile_select' => contact_profile_assign($contact['abook_profile']), + '$multiprofs' => $multiprofs, + '$contact_id' => $contact['abook_id'], + '$name' => $contact['xchan_name'], + + )); + + $arr = array('contact' => $contact,'output' => $o); + + call_hooks('contact_edit', $arr); + + return $arr['output']; + + } + + + } + +} diff --git a/Zotlabs/Module/Contactgroup.php b/Zotlabs/Module/Contactgroup.php new file mode 100644 index 000000000..497442ff4 --- /dev/null +++ b/Zotlabs/Module/Contactgroup.php @@ -0,0 +1,54 @@ + 2) && (intval(argv(1))) && (argv(2))) { + $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", + dbesc(base64url_decode(argv(2))), + intval(local_channel()) + ); + if($r) + $change = $r[0]['abook_xchan']; + } + + if((argc() > 1) && (intval(argv(1)))) { + + $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", + intval(argv(1)), + intval(local_channel()) + ); + if(! $r) { + killme(); + } + + $group = $r[0]; + $members = group_get_members($group['id']); + $preselected = array(); + if(count($members)) { + foreach($members as $member) + $preselected[] = $member['xchan_hash']; + } + + if($change) { + if(in_array($change,$preselected)) { + group_rmv_member(local_channel(),$group['name'],$change); + } + else { + group_add_member(local_channel(),$group['name'],$change); + } + } + } + + killme(); + } +} diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php new file mode 100644 index 000000000..aafc1bdb0 --- /dev/null +++ b/Zotlabs/Module/Cover_photo.php @@ -0,0 +1,423 @@ +is_valid()) { + + // We are scaling and cropping the relative pixel locations to the original photo instead of the + // scaled photo we operated on. + + // First load the scaled photo to check its size. (Should probably pass this in the post form and save + // a query.) + + $g = q("select width, height from photo where resource_id = '%s' and uid = %d and scale = 3", + dbesc($image_id), + intval(local_channel()) + ); + + + $scaled_width = $g[0]['width']; + $scaled_height = $g[0]['height']; + + if((! $scaled_width) || (! $scaled_height)) { + logger('potential divide by zero scaling cover photo'); + return; + } + + // unset all other cover photos + + q("update photo set photo_usage = %d where photo_usage = %d and uid = %d", + intval(PHOTO_NORMAL), + intval(PHOTO_COVER), + intval(local_channel()) + ); + + $orig_srcx = ( $r[0]['width'] / $scaled_width ) * $srcX; + $orig_srcy = ( $r[0]['height'] / $scaled_height ) * $srcY; + $orig_srcw = ( $srcW / $scaled_width ) * $r[0]['width']; + $orig_srch = ( $srcH / $scaled_height ) * $r[0]['height']; + + $im->cropImageRect(1200,435,$orig_srcx, $orig_srcy, $orig_srcw, $orig_srch); + + $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['scale'] = 7; + $p['photo_usage'] = PHOTO_COVER; + + $r1 = $im->save($p); + + $im->doScaleImage(850,310); + $p['scale'] = 8; + + $r2 = $im->save($p); + + + $im->doScaleImage(425,160); + $p['scale'] = 9; + + $r3 = $im->save($p); + + if($r1 === false || $r2 === false || $r3 === false) { + // if one failed, delete them all so we can start over. + notice( t('Image resize failed.') . EOL ); + $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 7 ", + dbesc($base_image['resource_id']), + local_channel() + ); + return; + } + + $channel = \App::get_channel(); + $this->send_cover_photo_activity($channel,$base_image,$profile); + + + } + else + notice( t('Unable to process image') . EOL); + } + + goaway(z_root() . '/channel/' . $channel['channel_address']); + + } + + + $hash = photo_new_resource(); + $smallest = 0; + + require_once('include/attach.php'); + + $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Cover Photos'), 'hash' => $hash)); + + logger('attach_store: ' . print_r($res,true)); + + if($res && intval($res['data']['is_photo'])) { + $i = q("select * from photo where resource_id = '%s' and uid = %d and scale = 0", + dbesc($hash), + intval(local_channel()) + ); + + if(! $i) { + notice( t('Image upload failed.') . EOL ); + return; + } + $os_storage = false; + + foreach($i as $ii) { + $smallest = intval($ii['scale']); + $os_storage = intval($ii['os_storage']); + $imagedata = $ii['data']; + $filetype = $ii['type']; + + } + } + + $imagedata = (($os_storage) ? @file_get_contents($imagedata) : $imagedata); + $ph = photo_factory($imagedata, $filetype); + + if(! $ph->is_valid()) { + notice( t('Unable to process image.') . EOL ); + return; + } + + return $this->cover_photo_crop_ui_head($a, $ph, $hash, $smallest); + + } + + function send_cover_photo_activity($channel,$photo,$profile) { + + $arr = array(); + $arr['item_thread_top'] = 1; + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; + $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; + $arr['verb'] = ACTIVITY_UPDATE; + + $arr['object'] = json_encode(array( + 'type' => $arr['obj_type'], + 'id' => z_root() . '/photo/' . $photo['resource_id'] . '-7', + 'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7') + )); + + if($profile && stripos($profile['gender'],t('female')) !== false) + $t = t('%1$s updated her %2$s'); + elseif($profile && stripos($profile['gender'],t('male')) !== false) + $t = t('%1$s updated his %2$s'); + else + $t = t('%1$s updated their %2$s'); + + $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('cover photo') . '[/zrl]'; + + $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-8[/zmg][/zrl]'; + + $arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext; + + $acl = new \Zotlabs\Access\AccessList($channel); + $x = $acl->get(); + $arr['allow_cid'] = $x['allow_cid']; + + $arr['allow_gid'] = $x['allow_gid']; + $arr['deny_cid'] = $x['deny_cid']; + $arr['deny_gid'] = $x['deny_gid']; + + $arr['uid'] = $channel['channel_id']; + $arr['aid'] = $channel['channel_account_id']; + + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; + + post_activity_item($arr); + + + } + + + /* @brief Generate content of profile-photo view + * + * @param $a Current application + * @return void + * + */ + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL ); + return; + } + + $channel = \App::get_channel(); + + $newuser = false; + + if(argc() == 2 && argv(1) === 'new') + $newuser = true; + + if(argv(1) === 'use') { + if (argc() < 3) { + notice( t('Permission denied.') . EOL ); + return; + }; + + // check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); + + $resource_id = argv(2); + + $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC", + intval(local_channel()), + dbesc($resource_id) + ); + if(! $r) { + notice( t('Photo not available.') . EOL ); + return; + } + $havescale = false; + foreach($r as $rr) { + if($rr['scale'] == 7) + $havescale = true; + } + + $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + intval($r[0]['id']), + intval(local_channel()) + + ); + if(! $r) { + notice( t('Photo not available.') . EOL ); + return; + } + + if(intval($r[0]['os_storage'])) + $data = @file_get_contents($r[0]['data']); + else + $data = dbunescbin($r[0]['data']); + + $ph = photo_factory($data, $r[0]['type']); + $smallest = 0; + if($ph->is_valid()) { + // go ahead as if we have just uploaded a new photo to crop + $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d and scale = 0", + dbesc($r[0]['resource_id']), + intval(local_channel()) + ); + + if($i) { + $hash = $i[0]['resource_id']; + foreach($i as $ii) { + $smallest = intval($ii['scale']); + } + } + } + + cover_photo_crop_ui_head($a, $ph, $hash, $smallest); + } + + + if(! x(\App::$data,'imagecrop')) { + + $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, + '$form_security_token' => get_form_security_token("cover_photo"), + // FIXME - yuk + '$select' => sprintf('%s %s', t('or'), ($newuser) ? '' . t('skip this step') . '' : '' . t('select a photo from your photo albums') . '') + )); + + call_hooks('cover_photo_content_end', $o); + + return $o; + } + else { + $filename = \App::$data['imagecrop'] . '-3'; + $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.'), + '$form_security_token' => get_form_security_token("cover_photo"), + '$done' => t('Done Editing') + )); + return $o; + } + + return; // NOTREACHED + } + + /* @brief Generate the UI for photo-cropping + * + * @param $a Current application + * @param $ph Photo-Factory + * @return void + * + */ + + + + function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){ + + $max_length = get_config('system','max_image_length'); + if(! $max_length) + $max_length = MAX_IMAGE_LENGTH; + if($max_length > 0) + $ph->scaleImage($max_length); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + if($width < 300 || $height < 300) { + $ph->scaleImageUp(240); + $width = $ph->getWidth(); + $height = $ph->getHeight(); + } + + + \App::$data['imagecrop'] = $hash; + \App::$data['imagecrop_resolution'] = $smallest; + \App::$page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array()); + return; + } + + +} diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php new file mode 100644 index 000000000..42eb3d0c1 --- /dev/null +++ b/Zotlabs/Module/Dav.php @@ -0,0 +1,150 @@ + 1) + $which = argv(1); + + $profile = 0; + + \App::$page['htmlhead'] .= '' . "\r\n"; + + if ($which) + profile_load($a, $which, $profile); + + $auth = new \Zotlabs\Storage\BasicAuth(); + + $ob_hash = get_observer_hash(); + + if ($ob_hash) { + if (local_channel()) { + $channel = \App::get_channel(); + $auth->setCurrentUser($channel['channel_address']); + $auth->channel_id = $channel['channel_id']; + $auth->channel_hash = $channel['channel_hash']; + $auth->channel_account_id = $channel['channel_account_id']; + if($channel['channel_timezone']) + $auth->setTimezone($channel['channel_timezone']); + } + $auth->observer = $ob_hash; + } + + if ($_GET['davguest']) + $_SESSION['davguest'] = true; + + $_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); + + // A SabreDAV server-object + $server = new \SDAV\Server($rootDirectory); + // prevent overwriting changes each other with a lock backend + $lockBackend = new \SDAV\Locks\Backend\File('store/[data]/locks'); + $lockPlugin = new \SDAV\Locks\Plugin($lockBackend); + + $server->addPlugin($lockPlugin); + + // The next section of code allows us to bypass prompting for http-auth if a + // FILE is being accessed anonymously and permissions allow this. This way + // one can create hotlinks to public media files in their cloud and anonymous + // viewers won't get asked to login. + // If a DIRECTORY is accessed or there are permission issues accessing the + // file and we aren't previously authenticated via zot, prompt for HTTP-auth. + // This will be the default case for mounting a DAV directory. + // In order to avoid prompting for passwords for viewing a DIRECTORY, add + // the URL query parameter 'davguest=1'. + + $isapublic_file = false; + $davguest = ((x($_SESSION, 'davguest')) ? true : false); + + if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) { + try { + $x = RedFileData('/' . \App::$cmd, $auth); + if($x instanceof \Zotlabs\Storage\File) + $isapublic_file = true; + } + catch (Exception $e) { + $isapublic_file = false; + } + } + + if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) { + try { + $auth->Authenticate($server, t('$Projectname channel')); + } + catch (Exception $e) { + logger('mod_cloud: auth exception' . $e->getMessage()); + http_status_exit($e->getHTTPCode(), $e->getMessage()); + } + } + + // require_once('Zotlabs/Storage/Browser.php'); + // provide a directory view for the cloud in Hubzilla + $browser = new \Zotlabs\Storage\Browser($auth); + $auth->setBrowserPlugin($browser); + + // Experimental QuotaPlugin + // require_once('Zotlabs/Storage/QuotaPlugin.php'); + // $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth)); + + // All we need to do now, is to fire up the server + $server->exec(); + + killme(); + } + +} diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php new file mode 100644 index 000000000..b8bac53bb --- /dev/null +++ b/Zotlabs/Module/Directory.php @@ -0,0 +1,425 @@ + 0) ? intval($numtags) : 50); + + if(get_config('system','disable_directory_keywords')) + $kw = 0; + + $query = $url . '?f=&kw=' . $kw . (($safe_mode != 1) ? '&safe=' . $safe_mode : ''); + + if($token) + $query .= '&t=' . $token; + + if(! $globaldir) + $query .= '&hub=' . \App::get_hostname(); + + if($search) + $query .= '&name=' . urlencode($search) . '&keywords=' . urlencode($search); + if(strpos($search,'@')) + $query .= '&address=' . urlencode($search); + if($keywords) + $query .= '&keywords=' . urlencode($keywords); + if($advanced) + $query .= '&query=' . urlencode($advanced); + if(! is_null($pubforums)) + $query .= '&pubforums=' . intval($pubforums); + + $directory_sort_order = get_config('system','directory_sort_order'); + if(! $directory_sort_order) + $directory_sort_order = 'date'; + + $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : $directory_sort_order); + + if($sort_order) + $query .= '&order=' . urlencode($sort_order); + + if(\App::$pager['page'] != 1) + $query .= '&p=' . \App::$pager['page']; + + logger('mod_directory: query: ' . $query); + + $x = z_fetch_url($query); + logger('directory: return from upstream: ' . print_r($x,true), LOGGER_DATA); + + if($x['success']) { + $t = 0; + $j = json_decode($x['body'],true); + if($j) { + + if($j['results']) { + + $entries = array(); + + $photo = 'thumb'; + + foreach($j['results'] as $rr) { + + $profile_link = chanlink_url($rr['url']); + + $pdesc = (($rr['description']) ? $rr['description'] . '
    ' : ''); + $connect_link = ((local_channel()) ? z_root() . '/follow?f=&url=' . urlencode($rr['address']) : ''); + + // Checking status is disabled ATM until someone checks the performance impact more carefully + //$online = remote_online_status($rr['address']); + $online = ''; + + if(in_array($rr['hash'],$contacts)) + $connect_link = ''; + + $location = ''; + if(strlen($rr['locale'])) + $location .= $rr['locale']; + if(strlen($rr['region'])) { + if(strlen($rr['locale'])) + $location .= ', '; + $location .= $rr['region']; + } + if(strlen($rr['country'])) { + if(strlen($location)) + $location .= ', '; + $location .= $rr['country']; + } + + $age = ''; + if(strlen($rr['birthday'])) { + if(($years = age($rr['birthday'],'UTC','')) != 0) + $age = $years; + } + + $page_type = ''; + + if($rr['total_ratings']) + $total_ratings = sprintf( tt("%d rating", "%d ratings", $rr['total_ratings']), $rr['total_ratings']); + else + $total_ratings = ''; + + $profile = $rr; + + if ((x($profile,'locale') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postcode') == 1) + || (x($profile,'country') == 1)) + + $gender = ((x($profile,'gender') == 1) ? t('Gender: ') . $profile['gender']: False); + + $marital = ((x($profile,'marital') == 1) ? t('Status: ') . $profile['marital']: False); + + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage: ') : False); + $homepageurl = ((x($profile,'homepage') == 1) ? $profile['homepage'] : ''); + + $hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False); + + $about = ((x($profile,'about') == 1) ? bbcode($profile['about']) : False); + + $keywords = ((x($profile,'keywords')) ? $profile['keywords'] : ''); + + $out = ''; + + if($keywords) { + $keywords = str_replace(',',' ', $keywords); + $keywords = str_replace(' ',' ', $keywords); + $karr = explode(' ', $keywords); + + if($karr) { + if(local_channel()) { + $r = q("select keywords from profile where uid = %d and is_default = 1 limit 1", + intval(local_channel()) + ); + if($r) { + $keywords = str_replace(',',' ', $r[0]['keywords']); + $keywords = str_replace(' ',' ', $keywords); + $marr = explode(' ', $keywords); + } + } + foreach($karr as $k) { + if(strlen($out)) + $out .= ', '; + if($marr && in_arrayi($k,$marr)) + $out .= '' . $k . ''; + else + $out .= $k; + } + } + + } + + $entry = array( + 'id' => ++$t, + 'profile_link' => $profile_link, + 'public_forum' => $rr['public_forum'], + 'photo' => $rr['photo'], + 'hash' => $rr['hash'], + 'alttext' => $rr['name'] . ((local_channel() || remote_channel()) ? ' ' . $rr['address'] : ''), + 'name' => $rr['name'], + 'age' => $age, + 'age_label' => t('Age:'), + 'profile' => $profile, + 'address' => $rr['address'], + 'nickname' => substr($rr['address'],0,strpos($rr['address'],'@')), + 'location' => $location, + 'location_label' => t('Location:'), + 'gender' => $gender, + 'total_ratings' => $total_ratings, + 'viewrate' => true, + 'canrate' => ((local_channel()) ? true : false), + 'pdesc' => $pdesc, + 'pdesc_label' => t('Description:'), + 'marital' => $marital, + 'homepage' => $homepage, + 'homepageurl' => linkify($homepageurl), + 'hometown' => $hometown, + 'hometown_label' => t('Hometown:'), + 'about' => $about, + 'about_label' => t('About:'), + 'conn_label' => t('Connect'), + 'forum_label' => t('Public Forum:'), + 'connect' => $connect_link, + 'online' => $online, + 'kw' => (($out) ? t('Keywords: ') : ''), + 'keywords' => $out, + 'ignlink' => $suggest ? z_root() . '/directory?ignore=' . $rr['hash'] : '', + 'ignore_label' => t('Don\'t suggest'), + 'common_friends' => (($common[$rr['address']]) ? intval($common[$rr['address']]) : ''), + 'common_label' => t('Common connections:'), + 'common_count' => intval($common[$rr['address']]), + 'safe' => $safe_mode + ); + + $arr = array('contact' => $rr, 'entry' => $entry); + + call_hooks('directory_item', $arr); + + unset($profile); + unset($location); + + if(! $arr['entry']) { + continue; + } + + if($sort_order == '' && $suggest) { + $entries[$addresses[$rr['address']]] = $arr['entry']; // Use the same indexes as originally to get the best suggestion first + } + + else { + $entries[] = $arr['entry']; + } + } + + ksort($entries); // Sort array by key so that foreach-constructs work as expected + + if($j['keywords']) { + \App::$data['directory_keywords'] = $j['keywords']; + } + + logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); + + + if($_REQUEST['aj']) { + if($entries) { + $o = replace_macros(get_markup_template('directajax.tpl'),array( + '$entries' => $entries + )); + } + else { + $o = '
    '; + } + echo $o; + killme(); + } + else { + $maxheight = 94; + + $dirtitle = (($globaldir) ? t('Global Directory') : t('Local Directory')); + + $o .= ""; + $o .= replace_macros($tpl, array( + '$search' => $search, + '$desc' => t('Find'), + '$finddsc' => t('Finding:'), + '$safetxt' => htmlspecialchars($search,ENT_QUOTES,'UTF-8'), + '$entries' => $entries, + '$dirlbl' => $suggest ? t('Channel Suggestions') : $dirtitle, + '$submit' => t('Find'), + '$next' => alt_pager($a,$j['records'], t('next page'), t('previous page')), + '$sort' => t('Sort options'), + '$normal' => t('Alphabetic'), + '$reverse' => t('Reverse Alphabetic'), + '$date' => t('Newest to Oldest'), + '$reversedate' => t('Oldest to Newest'), + '$suggest' => $suggest ? '&suggest=1' : '' + )); + + + } + + } + else { + if($_REQUEST['aj']) { + $o = '
    '; + echo $o; + killme(); + } + if(\App::$pager['page'] == 1 && $j['records'] == 0 && strpos($search,'@')) { + goaway(z_root() . '/chanview/?f=&address=' . $search); + } + info( t("No entries (some entries may be hidden).") . EOL); + } + } + } + } + return $o; + } + + +} diff --git a/Zotlabs/Module/Dirsearch.php b/Zotlabs/Module/Dirsearch.php new file mode 100644 index 000000000..8f60910f1 --- /dev/null +++ b/Zotlabs/Module/Dirsearch.php @@ -0,0 +1,462 @@ + false); + + // logger('request: ' . print_r($_REQUEST,true)); + + + $dirmode = intval(get_config('system','directory_mode')); + + if($dirmode == DIRECTORY_MODE_NORMAL) { + $ret['message'] = t('This site is not a directory server'); + json_return_and_die($ret); + } + + $access_token = $_REQUEST['t']; + + $token = get_config('system','realm_token'); + if($token && $access_token != $token) { + $ret['message'] = t('This directory server requires an access token'); + json_return_and_die($ret); + } + + + if(argc() > 1 && argv(1) === 'sites') { + $ret = $this->list_public_sites(); + json_return_and_die($ret); + } + + $sql_extra = ''; + + + $tables = array('name','address','locale','region','postcode','country','gender','marital','sexual','keywords'); + + if($_REQUEST['query']) { + $advanced = $this->dir_parse_query($_REQUEST['query']); + if($advanced) { + foreach($advanced as $adv) { + if(in_array($adv['field'],$tables)) { + if($adv['field'] === 'name') + $sql_extra .= $this->dir_query_build($adv['logic'],'xchan_name',$adv['value']); + elseif($adv['field'] === 'address') + $sql_extra .= $this->dir_query_build($adv['logic'],'xchan_addr',$adv['value']); + else + $sql_extra .= $this->dir_query_build($adv['logic'],'xprof_' . $adv['field'],$adv['value']); + } + } + } + } + + $hash = ((x($_REQUEST['hash'])) ? $_REQUEST['hash'] : ''); + + $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); + $hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : ''); + $address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); + $locale = ((x($_REQUEST,'locale')) ? $_REQUEST['locale'] : ''); + $region = ((x($_REQUEST,'region')) ? $_REQUEST['region'] : ''); + $postcode = ((x($_REQUEST,'postcode')) ? $_REQUEST['postcode'] : ''); + $country = ((x($_REQUEST,'country')) ? $_REQUEST['country'] : ''); + $gender = ((x($_REQUEST,'gender')) ? $_REQUEST['gender'] : ''); + $marital = ((x($_REQUEST,'marital')) ? $_REQUEST['marital'] : ''); + $sexual = ((x($_REQUEST,'sexual')) ? $_REQUEST['sexual'] : ''); + $keywords = ((x($_REQUEST,'keywords')) ? $_REQUEST['keywords'] : ''); + $agege = ((x($_REQUEST,'agege')) ? intval($_REQUEST['agege']) : 0 ); + $agele = ((x($_REQUEST,'agele')) ? intval($_REQUEST['agele']) : 0 ); + $kw = ((x($_REQUEST,'kw')) ? intval($_REQUEST['kw']) : 0 ); + $forums = ((array_key_exists('pubforums',$_REQUEST)) ? intval($_REQUEST['pubforums']) : 0); + + if(get_config('system','disable_directory_keywords')) + $kw = 0; + + + // by default use a safe search + $safe = ((x($_REQUEST,'safe'))); // ? intval($_REQUEST['safe']) : 1 ); + if ($safe === false) + $safe = 1; + + if(array_key_exists('sync',$_REQUEST)) { + if($_REQUEST['sync']) + $sync = datetime_convert('UTC','UTC',$_REQUEST['sync']); + else + $sync = datetime_convert('UTC','UTC','2010-01-01 01:01:00'); + } + else + $sync = false; + + + if($hub) + $hub_query = " and xchan_hash in (select hubloc_hash from hubloc where hubloc_host = '" . protect_sprintf(dbesc($hub)) . "') "; + else + $hub_query = ''; + + $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : ''); + + $joiner = ' OR '; + if($_REQUEST['and']) + $joiner = ' AND '; + + if($name) + $sql_extra .= $this->dir_query_build($joiner,'xchan_name',$name); + if($address) + $sql_extra .= $this->dir_query_build($joiner,'xchan_addr',$address); + if($city) + $sql_extra .= $this->dir_query_build($joiner,'xprof_locale',$city); + if($region) + $sql_extra .= $this->dir_query_build($joiner,'xprof_region',$region); + if($post) + $sql_extra .= $this->dir_query_build($joiner,'xprof_postcode',$post); + if($country) + $sql_extra .= $this->dir_query_build($joiner,'xprof_country',$country); + if($gender) + $sql_extra .= $this->dir_query_build($joiner,'xprof_gender',$gender); + if($marital) + $sql_extra .= $this->dir_query_build($joiner,'xprof_marital',$marital); + if($sexual) + $sql_extra .= $this->dir_query_build($joiner,'xprof_sexual',$sexual); + if($keywords) + $sql_extra .= $this->dir_query_build($joiner,'xprof_keywords',$keywords); + + + // we only support an age range currently. You must set both agege + // (greater than or equal) and agele (less than or equal) + + if($agele && $agege) { + $sql_extra .= " $joiner ( xprof_age <= " . intval($agele) . " "; + $sql_extra .= " AND xprof_age >= " . intval($agege) . ") "; + } + + + if($hash) { + $sql_extra = " AND xchan_hash like '" . dbesc($hash) . protect_sprintf('%') . "' "; + } + + + $perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 60); + $page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0); + $startrec = (($page+1) * $perpage) - $perpage; + $limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0); + $return_total = ((x($_REQUEST,'return_total')) ? intval($_REQUEST['return_total']) : 0); + + // mtime is not currently working + + $mtime = ((x($_REQUEST,'mtime')) ? datetime_convert('UTC','UTC',$_REQUEST['mtime']) : ''); + + // ok a separate tag table won't work. + // merge them into xprof + + $ret['success'] = true; + + // If &limit=n, return at most n entries + // If &return_total=1, we count matching entries and return that as 'total_items' for use in pagination. + // By default we return one page (default 80 items maximum) and do not count total entries + + $logic = ((strlen($sql_extra)) ? 'false' : 'true'); + + if($hash) + $logic = 'true'; + + if($dirmode == DIRECTORY_MODE_STANDALONE) { + $sql_extra .= " and xchan_addr like '%%" . \App::get_hostname() . "' "; + } + + $safesql = (($safe > 0) ? " and xchan_censored = 0 and xchan_selfcensored = 0 " : ''); + if($safe < 0) + $safesql = " and ( xchan_censored = 1 OR xchan_selfcensored = 1 ) "; + + if($forums) + $safesql .= " and xchan_pubforum = " . ((intval($forums)) ? '1 ' : '0 '); + + if($limit) + $qlimit = " LIMIT $limit "; + else { + $qlimit = " LIMIT " . intval($perpage) . " OFFSET " . intval($startrec); + if($return_total) { + $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 $safesql "); + if($r) { + $ret['total_items'] = $r[0]['total']; + } + } + } + + if($sort_order == 'normal') { + $order = " order by xchan_name asc "; + + // Start the alphabetic search at 'A' + // This will make a handful of channels whose names begin with + // punctuation un-searchable in this mode + + $safesql .= " and ascii(substring(xchan_name FROM 1 FOR 1)) > 64 "; + } + elseif($sort_order == 'reverse') + $order = " order by xchan_name desc "; + elseif($sort_order == 'reversedate') + $order = " order by xchan_name_date asc "; + else + $order = " order by xchan_name_date desc "; + + + if($sync) { + $spkt = array('transactions' => array()); + $r = q("select * from updates where ud_date >= '%s' and ud_guid != '' order by ud_date desc", + dbesc($sync) + ); + if($r) { + foreach($r as $rr) { + $flags = array(); + if($rr['ud_flags'] & UPDATE_FLAGS_DELETED) + $flags[] = 'deleted'; + if($rr['ud_flags'] & UPDATE_FLAGS_FORCED) + $flags[] = 'forced'; + + $spkt['transactions'][] = array( + 'hash' => $rr['ud_hash'], + 'address' => $rr['ud_addr'], + 'transaction_id' => $rr['ud_guid'], + 'timestamp' => $rr['ud_date'], + 'flags' => $flags + ); + } + } + $r = q("select * from xlink where xlink_static = 1 and xlink_updated >= '%s' ", + dbesc($sync) + ); + if($r) { + $spkt['ratings'] = array(); + foreach($r as $rr) { + $spkt['ratings'][] = array( + 'type' => 'rating', + 'encoding' => 'zot', + 'channel' => $rr['xlink_xchan'], + 'target' => $rr['xlink_link'], + 'rating' => intval($rr['xlink_rating']), + 'rating_text' => $rr['xlink_rating_text'], + 'signature' => $rr['xlink_sig'], + 'edited' => $rr['xlink_updated'] + ); + } + } + json_return_and_die($spkt); + } + else { + + $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash + where ( $logic $sql_extra ) $hub_query and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 + $safesql $order $qlimit " + ); + + + + $ret['page'] = $page + 1; + $ret['records'] = count($r); + } + + + + if($r) { + + $entries = array(); + + foreach($r as $rr) { + + $entry = array(); + + $pc = q("select count(xlink_rating) as total_ratings from xlink where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 group by xlink_rating", + dbesc($rr['xchan_hash']) + ); + + if($pc) + $entry['total_ratings'] = intval($pc[0]['total_ratings']); + else + $entry['total_ratings'] = 0; + + $entry['name'] = $rr['xchan_name']; + $entry['hash'] = $rr['xchan_hash']; + + $entry['public_forum'] = (intval($rr['xchan_pubforum']) ? true : false); + + $entry['url'] = $rr['xchan_url']; + $entry['photo_l'] = $rr['xchan_photo_l']; + $entry['photo'] = $rr['xchan_photo_m']; + $entry['address'] = $rr['xchan_addr']; + $entry['description'] = $rr['xprof_desc']; + $entry['locale'] = $rr['xprof_locale']; + $entry['region'] = $rr['xprof_region']; + $entry['postcode'] = $rr['xprof_postcode']; + $entry['country'] = $rr['xprof_country']; + $entry['birthday'] = $rr['xprof_dob']; + $entry['age'] = $rr['xprof_age']; + $entry['gender'] = $rr['xprof_gender']; + $entry['marital'] = $rr['xprof_marital']; + $entry['sexual'] = $rr['xprof_sexual']; + $entry['about'] = $rr['xprof_about']; + $entry['homepage'] = $rr['xprof_homepage']; + $entry['hometown'] = $rr['xprof_hometown']; + $entry['keywords'] = $rr['xprof_keywords']; + + $entries[] = $entry; + + } + + $ret['results'] = $entries; + if($kw) { + $k = dir_tagadelic($kw); + if($k) { + $ret['keywords'] = array(); + foreach($k as $kv) { + $ret['keywords'][] = array('term' => $kv[0],'weight' => $kv[1], 'normalise' => $kv[2]); + } + } + } + } + + json_return_and_die($ret); + } + + function dir_query_build($joiner,$field,$s) { + $ret = ''; + if(trim($s)) + $ret .= dbesc($joiner) . " " . dbesc($field) . " like '" . protect_sprintf( '%' . dbesc($s) . '%' ) . "' "; + return $ret; + } + + function dir_flag_build($joiner,$field,$bit,$s) { + return dbesc($joiner) . " ( " . dbesc($field) . " & " . intval($bit) . " ) " . ((intval($s)) ? '>' : '=' ) . " 0 "; + } + + + function dir_parse_query($s) { + + $ret = array(); + $curr = array(); + $all = explode(' ',$s); + $quoted_string = false; + + if($all) { + foreach($all as $q) { + if($quoted_string === false) { + if($q === 'and') { + $curr['logic'] = 'and'; + continue; + } + if($q === 'or') { + $curr['logic'] = 'or'; + continue; + } + if($q === 'not') { + $curr['logic'] .= ' not'; + continue; + } + if(strpos($q,'=')) { + if(! isset($curr['logic'])) + $curr['logic'] = 'or'; + $curr['field'] = trim(substr($q,0,strpos($q,'='))); + $curr['value'] = trim(substr($q,strpos($q,'=')+1)); + if($curr['value'][0] == '"' && $curr['value'][strlen($curr['value'])-1] != '"') { + $quoted_string = true; + $curr['value'] = substr($curr['value'],1); + continue; + } + elseif($curr['value'][0] == '"' && $curr['value'][strlen($curr['value'])-1] == '"') { + $curr['value'] = substr($curr['value'],1,strlen($curr['value'])-2); + $ret[] = $curr; + $curr = array(); + continue; + } + else { + $ret[] = $curr; + $curr = array(); + continue; + } + } + } + else { + if($q[strlen($q)-1] == '"') { + $curr['value'] .= ' ' . str_replace('"','',trim($q)); + $ret[] = $curr; + $curr = array(); + $quoted_string = false; + } + else + $curr['value'] .= ' ' . trim(q); + } + } + } + logger('dir_parse_query:' . print_r($ret,true),LOGGER_DATA); + return $ret; + } + + + + + + + + function list_public_sites() { + + $rand = db_getfunc('rand'); + $realm = get_directory_realm(); + if($realm == DIRECTORY_REALM) { + $r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') and site_type = %d order by $rand", + dbesc($realm), + intval(SITE_TYPE_ZOT) + ); + } + else { + $r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' and site_type = %d order by $rand", + dbesc($realm), + intval(SITE_TYPE_ZOT) + ); + } + + $ret = array('success' => false); + + if($r) { + $ret['success'] = true; + $ret['sites'] = array(); + $insecure = array(); + + foreach($r as $rr) { + + if($rr['site_access'] == ACCESS_FREE) + $access = 'free'; + elseif($rr['site_access'] == ACCESS_PAID) + $access = 'paid'; + elseif($rr['site_access'] == ACCESS_TIERED) + $access = 'tiered'; + else + $access = 'private'; + + if($rr['site_register'] == REGISTER_OPEN) + $register = 'open'; + elseif($rr['site_register'] == REGISTER_APPROVE) + $register = 'approve'; + else + $register = 'closed'; + + if(strpos($rr['site_url'],'https://') !== false) + $ret['sites'][] = array('url' => $rr['site_url'], 'access' => $access, 'register' => $register, 'sellpage' => $rr['site_sellpage'], 'location' => $rr['site_location'], 'project' => $rr['site_project']); + else + $insecure[] = array('url' => $rr['site_url'], 'access' => $access, 'register' => $register, 'sellpage' => $rr['site_sellpage'], 'location' => $rr['site_location'], 'project' => $rr['site_project']); + } + if($insecure) { + $ret['sites'] = array_merge($ret['sites'],$insecure); + } + } + return $ret; + } + +} diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php new file mode 100644 index 000000000..3d24c6c9a --- /dev/null +++ b/Zotlabs/Module/Display.php @@ -0,0 +1,346 @@ + 1 && argv(1) !== 'load') + $item_hash = argv(1); + + + if($_REQUEST['mid']) + $item_hash = $_REQUEST['mid']; + + + if(! $item_hash) { + \App::$error = 404; + notice( t('Item not found.') . EOL); + return; + } + + $observer_is_owner = false; + + + if(local_channel() && (! $update)) { + + $channel = \App::get_channel(); + + + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + + + $x = array( + 'is_owner' => true, + 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), + 'default_location' => $channel['channel_location'], + 'nickname' => $channel['channel_address'], + 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + + 'acl' => populate_acl($channel_acl), + 'bang' => '', + 'visitor' => true, + 'profile_uid' => local_channel(), + 'return_path' => 'channel/' . $channel['channel_address'], + 'expanded' => true, + 'editor_autocomplete' => true, + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + + $o = '
    '; + $o .= status_editor($a,$x); + $o .= '
    '; + + } + + // This page can be viewed by anybody so the query could be complicated + // First we'll see if there is a copy of the item which is owned by us - if we're logged in locally. + // If that fails (or we aren't logged in locally), + // query an item in which the observer (if logged in remotely) has cid or gid rights + // and if that fails, look for a copy of the post that has no privacy restrictions. + // If we find the post, but we don't find a copy that we're allowed to look at, this fact needs to be reported. + + // find a copy of the item somewhere + + $target_item = null; + + $r = q("select id, uid, mid, parent_mid, item_type, item_deleted from item where mid like '%s' limit 1", + dbesc($item_hash . '%') + ); + + if($r) { + $target_item = $r[0]; + } + + $r = null; + + if($target_item['item_type'] == ITEM_TYPE_WEBPAGE) { + $x = q("select * from channel where channel_id = %d limit 1", + intval($target_item['uid']) + ); + $y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1", + intval($target_item['uid']), + intval($target_item['id']) + ); + if($x && $y) { + goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']); + } + else { + notice( t('Page not found.') . EOL); + return ''; + } + } + + + $simple_update = (($update) ? " AND item_unseen = 1 " : ''); + + if($update && $_SESSION['loadtime']) + $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; + if($load) + $simple_update = ''; + + + + if((! $update) && (! $load)) { + + + $o .= '
    ' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'display', + '$uid' => '0', + '$gid' => '0', + '$cid' => '0', + '$cmin' => '0', + '$cmax' => '99', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$fh' => '0', + '$nouveau' => '0', + '$wall' => '0', + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$search' => '', + '$order' => '', + '$file' => '', + '$cats' => '', + '$tags' => '', + '$dend' => '', + '$dbegin' => '', + '$verb' => '', + '$mid' => $item_hash + )); + + + } + + $observer_hash = get_observer_hash(); + $item_normal = item_normal(); + + $sql_extra = public_permissions_sql($observer_hash); + + if(($update && $load) || ($checkjs->disabled())) { + + $updateable = false; + + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start'])); + + if($load || ($checkjs->disabled())) { + $r = null; + + require_once('include/identity.php'); + $sys = get_sys_channel(); + $sysid = $sys['channel_id']; + + if(local_channel()) { + $r = q("SELECT * from item + WHERE uid = %d + and mid = '%s' + $item_normal + limit 1", + intval(local_channel()), + dbesc($target_item['parent_mid']) + ); + if($r) { + $updateable = true; + + } + + } + if($r === null) { + + // in case somebody turned off public access to sys channel content using permissions + // make that content unsearchable by ensuring the owner_xchan can't match + + if(! perm_is_allowed($sysid,$observer_hash,'view_stream')) + $sysid = 0; + + + $r = q("SELECT * from item + WHERE mid = '%s' + AND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' + AND `item`.`deny_gid` = '' AND item_private = 0 ) + and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) + OR uid = %d ) + $sql_extra ) + $item_normal + limit 1", + dbesc($target_item['parent_mid']), + intval($sysid) + ); + + } + } + } + + elseif($update && !$load) { + $r = null; + + require_once('include/identity.php'); + $sys = get_sys_channel(); + $sysid = $sys['channel_id']; + + if(local_channel()) { + $r = q("SELECT * from item + WHERE uid = %d + and mid = '%s' + $item_normal + $simple_update + limit 1", + intval(local_channel()), + dbesc($target_item['parent_mid']) + ); + if($r) { + $updateable = true; + } + } + if($r === null) { + // in case somebody turned off public access to sys channel content using permissions + // make that content unsearchable by ensuring the owner_xchan can't match + if(! perm_is_allowed($sysid,$observer_hash,'view_stream')) + $sysid = 0; + + $r = q("SELECT * from item + WHERE mid = '%s' + AND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' + AND `item`.`deny_gid` = '' AND item_private = 0 ) + and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) + OR uid = %d ) + $sql_extra ) + $item_normal + $simple_update + limit 1", + dbesc($target_item['parent_mid']), + intval($sysid) + ); + } + $_SESSION['loadtime'] = datetime_convert(); + } + + else { + $r = array(); + } + + if($r) { + + $parents_str = ids_to_querystr($r,'id'); + if($parents_str) { + + $items = q("SELECT `item`.*, `item`.`id` AS `item_id` + FROM `item` + WHERE parent in ( %s ) $item_normal ", + dbesc($parents_str) + ); + + xchan_query($items); + $items = fetch_post_tags($items,true); + $items = conv_sort($items,'created'); + } + } else { + $items = array(); + } + + + if ($checkjs->disabled()) { + $o .= conversation($a, $items, 'display', $update, 'traditional'); + if ($items[0]['title']) + \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; + } + else { + $o .= conversation($a, $items, 'display', $update, 'client'); + } + + if($updateable) { + $x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ", + intval(local_channel()), + intval($r[0]['parent']) + ); + } + + $o .= '
    '; + + return $o; + + + /* + elseif((! $update) && (! { + + $r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `mid` = '%s' LIMIT 1", + dbesc($item_hash), + dbesc($item_hash) + ); + if($r) { + if(intval($r[0]['item_deleted'])) { + notice( t('Item has been removed.') . EOL ); + } + else { + notice( t('Permission denied.') . EOL ); + } + } + else { + notice( t('Item not found.') . EOL ); + } + + } + */ + } + + +} diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php new file mode 100644 index 000000000..e8709c952 --- /dev/null +++ b/Zotlabs/Module/Dreport.php @@ -0,0 +1,145 @@ + 1) ? argv(1) : ''); + + if($mid === 'mail') { + $table = 'mail'; + $mid = ((argc() > 2) ? argv(2) : ''); + } + + + if(! $mid) { + notice( t('Invalid message') . EOL); + return; + } + + switch($table) { + case 'item': + $i = q("select id from item where mid = '%s' and author_xchan = '%s' ", + dbesc($mid), + dbesc($channel['channel_hash']) + ); + break; + case 'mail': + $i = q("select id from mail where mid = '%s' and from_xchan = '%s'", + dbesc($mid), + dbesc($channel['channel_hash']) + ); + break; + default: + break; + } + + if(! $i) { + notice( t('Permission denied') . EOL); + return; + } + + $r = q("select * from dreport where dreport_xchan = '%s' and dreport_mid = '%s'", + dbesc($channel['channel_hash']), + dbesc($mid) + ); + + if(! $r) { + notice( t('no results') . EOL); + return; + } + + $o .= '
    '; + $o .= '

    ' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '

    '; + $o .= ''; + + for($x = 0; $x < count($r); $x++ ) { + $r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' '))); + + // This has two purposes: 1. make the delivery report strings translateable, and + // 2. assign an ordering to item delivery results so we can group them and provide + // a readable report with more interesting events listed toward the top and lesser + // interesting items towards the bottom + + switch($r[$x]['dreport_result']) { + case 'channel sync processed': + $r[$x]['gravity'] = 0; + $r[$x]['dreport_result'] = t('channel sync processed'); + break; + case 'queued': + $r[$x]['gravity'] = 2; + $r[$x]['dreport_result'] = t('queued'); + break; + case 'posted': + $r[$x]['gravity'] = 3; + $r[$x]['dreport_result'] = t('posted'); + break; + case 'accepted for delivery': + $r[$x]['gravity'] = 4; + $r[$x]['dreport_result'] = t('accepted for delivery'); + break; + case 'updated': + $r[$x]['gravity'] = 5; + $r[$x]['dreport_result'] = t('updated'); + case 'update ignored': + $r[$x]['gravity'] = 6; + $r[$x]['dreport_result'] = t('update ignored'); + break; + case 'permission denied': + $r[$x]['dreport_result'] = t('permission denied'); + $r[$x]['gravity'] = 6; + break; + case 'recipient not found': + $r[$x]['dreport_result'] = t('recipient not found'); + break; + case 'mail recalled': + $r[$x]['dreport_result'] = t('mail recalled'); + break; + case 'duplicate mail received': + $r[$x]['dreport_result'] = t('duplicate mail received'); + break; + case 'mail delivered': + $r[$x]['dreport_result'] = t('mail delivered'); + break; + default: + $r[$x]['gravity'] = 1; + break; + } + } + + usort($r,'self::dreport_gravity_sort'); + + + foreach($r as $rr) { + $o .= ''; + } + $o .= '
    ' . $rr['name'] . '' . escape_tags($rr['dreport_result']) . '' . escape_tags($rr['dreport_time']) . '
    '; + $o .= '
    '; + + return $o; + + + + } + + private static function dreport_gravity_sort($a,$b) { + if($a['gravity'] == $b['gravity']) { + if($a['name'] === $b['name']) + return strcmp($a['dreport_time'],$b['dreport_time']); + return strcmp($a['name'],$b['name']); + } + return (($a['gravity'] > $b['gravity']) ? 1 : (-1)); + } + +} diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php new file mode 100644 index 000000000..90016952e --- /dev/null +++ b/Zotlabs/Module/Editblock.php @@ -0,0 +1,198 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { + notice( t('Permission denied.') . EOL); + return; + } + + $is_owner = (($uid && $uid == $owner) ? true : false); + + $o = ''; + + // Figure out which post we're editing + $post_id = ((argc() > 2) ? intval(argv(2)) : 0); + + + if(! ($post_id && $owner)) { + notice( t('Item not found') . EOL); + return; + } + + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", + intval($post_id), + intval($owner) + ); + if($itm) { + $item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1", + intval($itm[0]['id']) + ); + if($item_id) + $block_title = $item_id[0]['sid']; + } + else { + notice( t('Item not found') . EOL); + return; + } + + $plaintext = true; + + $mimeselect = ''; + $mimetype = $itm[0]['mimetype']; + + if($mimetype != 'text/bbcode') + $plaintext = true; + + if(get_config('system','page_mimetype')) + $mimeselect = ''; + else + $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); + + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', + '$ispublic' => ' ', // t('Visible to everybody'), + '$geotag' => '', + '$nickname' => $channel['channel_address'], + '$confirmdelete' => t('Delete block?'), + '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : 'comanche-block') + )); + + $tpl = get_markup_template("jot.tpl"); + + $jotplugins = ''; + $jotnets = ''; + + call_hooks('jot_tool', $jotplugins); + call_hooks('jot_networks', $jotnets); + + $rp = 'blocks/' . $channel['channel_address']; + + $editor = replace_macros($tpl,array( + '$return_path' => $rp, + '$action' => 'item', + '$webpage' => ITEM_TYPE_BLOCK, + '$share' => t('Edit'), + '$bold' => t('Bold'), + '$italic' => t('Italic'), + '$underline' => t('Underline'), + '$quote' => t('Quote'), + '$code' => t('Code'), + '$writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_storage'), + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$weblink' => t('Insert web link'), + '$youtube' => t('Insert YouTube video'), + '$video' => t('Insert Vorbis [.ogg] video'), + '$audio' => t('Insert Vorbis [.ogg] audio'), + '$setloc' => t('Set your location'), + '$noloc' => t('Clear browser location'), + '$wait' => t('Please wait'), + '$permset' => t('Permission settings'), + '$ptyp' => $itm[0]['type'], + '$mimeselect' => $mimeselect, + '$content' => undo_post_tagging($itm[0]['body']), + '$post_id' => $post_id, + '$baseurl' => z_root(), + '$defloc' => $channel['channel_location'], + '$visitor' => false, + '$public' => t('Public post'), + '$jotnets' => $jotnets, + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + '$placeholdertitle' => t('Title (optional)'), + '$pagetitle' => $block_title, + '$category' => '', + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), + '$emtitle' => t('Example: bob@example.com, mary@example.com'), + '$lockstate' => $lockstate, + '$acl' => '', + '$bang' => '', + '$profile_uid' => (intval($channel['channel_id'])), + '$preview' => t('Preview'), + '$jotplugins' => $jotplugins, + '$sourceapp' => $itm[0]['app'], + '$defexpire' => '', + '$feature_expire' => false, + '$expires' => t('Set expiration date'), + '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) + )); + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit Block'), + '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), + '$id' => $itm[0]['id'], + '$editor' => $editor + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php new file mode 100644 index 000000000..cec55f5cc --- /dev/null +++ b/Zotlabs/Module/Editlayout.php @@ -0,0 +1,195 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { + notice( t('Permission denied.') . EOL); + return; + } + + $is_owner = (($uid && $uid == $owner) ? true : false); + + $o = ''; + + // Figure out which post we're editing + $post_id = ((argc() > 2) ? intval(argv(2)) : 0); + + + if(! $post_id) { + notice( t('Item not found') . EOL); + return; + } + + // Now we've got a post and an owner, let's find out if we're allowed to edit it + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", + intval($post_id), + intval($owner) + ); + + $item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1", + intval($itm[0]['id']) + ); + if($item_id) + $layout_title = $item_id[0]['sid']; + + $plaintext = true; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', + '$ispublic' => ' ', // t('Visible to everybody'), + '$geotag' => $geotag, + '$nickname' => $channel['channel_address'], + '$confirmdelete' => t('Delete layout?'), + '$bbco_autocomplete'=> 'comanche' + )); + + + $tpl = get_markup_template("jot.tpl"); + + $jotplugins = ''; + $jotnets = ''; + + call_hooks('jot_tool', $jotplugins); + call_hooks('jot_networks', $jotnets); + + + // FIXME A return path with $_SESSION doesn't always work for observer - it may WSoD + // instead of loading a sensible page. So, send folk to the webpage list. + + $rp = 'layouts/' . $which; + + $editor = replace_macros($tpl,array( + '$return_path' => $rp, + '$action' => 'item', + '$webpage' => ITEM_TYPE_PDL, + '$share' => t('Edit'), + '$bold' => t('Bold'), + '$italic' => t('Italic'), + '$underline' => t('Underline'), + '$quote' => t('Quote'), + '$code' => t('Code'), + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$weblink' => t('Insert web link'), + '$youtube' => t('Insert YouTube video'), + '$video' => t('Insert Vorbis [.ogg] video'), + '$audio' => t('Insert Vorbis [.ogg] audio'), + '$setloc' => t('Set your location'), + '$noloc' => t('Clear browser location'), + '$wait' => t('Please wait'), + '$permset' => t('Permission settings'), + '$ptyp' => $itm[0]['type'], + '$content' => undo_post_tagging($itm[0]['body']), + '$post_id' => $post_id, + '$baseurl' => z_root(), + '$defloc' => $channel['channel_location'], + '$visitor' => false, + '$public' => t('Public post'), + '$jotnets' => $jotnets, + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + '$placeholdertitle' => t('Layout Description (Optional)'), + '$pagetitle' => $layout_title, + '$placeholdpagetitle' => t('Layout Name'), + '$category' => '', + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), + '$emtitle' => t('Example: bob@example.com, mary@example.com'), + '$lockstate' => $lockstate, + '$acl' => '', + '$bang' => '', + '$profile_uid' => (intval($owner)), + '$jotplugins' => $jotplugins, + '$sourceapp' => t(\App::$sourcename), + '$defexpire' => '', + '$feature_expire' => false, + '$expires' => t('Set expiration date'), + )); + + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit Layout'), + '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), + '$id' => $itm[0]['id'], + '$editor' => $editor + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php new file mode 100644 index 000000000..d8b971f6c --- /dev/null +++ b/Zotlabs/Module/Editpost.php @@ -0,0 +1,181 @@ + 1) ? intval(argv(1)) : 0); + + if(! $post_id) { + notice( t('Item not found') . EOL); + return; + } + + $itm = q("SELECT * FROM `item` WHERE `id` = %d AND ( owner_xchan = '%s' OR author_xchan = '%s' ) LIMIT 1", + intval($post_id), + dbesc(get_observer_hash()), + dbesc(get_observer_hash()) + ); + + if(! count($itm)) { + notice( t('Item is not editable') . EOL); + return; + } + + if($itm[0]['resource_type'] === 'event' && $itm[0]['resource_id']) { + goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1'); + } + + + $owner_uid = $itm[0]['uid']; + + + $plaintext = true; + // if(feature_enabled(local_channel(),'richtext')) + // $plaintext = false; + + $channel = \App::get_channel(); + + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', + '$ispublic' => ' ', // t('Visible to everybody'), + '$geotag' => $geotag, + '$nickname' => $channel['channel_address'], + '$expireswhen' => t('Expires YYYY-MM-DD HH:MM'), + '$confirmdelete' => t('Delete item?'), + '$editor_autocomplete'=> true, + '$bbco_autocomplete'=> 'bbcode' + )); + + if(intval($itm[0]['item_obscured'])) { + $key = get_config('system','prvkey'); + if($itm[0]['title']) + $itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key); + if($itm[0]['body']) + $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); + } + + $tpl = get_markup_template("jot.tpl"); + + $jotplugins = ''; + $jotnets = ''; + + call_hooks('jot_tool', $jotplugins); + call_hooks('jot_networks', $jotnets); + + //$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins)); + + $voting = feature_enabled($owner_uid,'consensus_tools'); + + $category = ''; + $catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : ''); + + if ($catsenabled){ + $itm = fetch_post_tags($itm); + + $cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY); + + foreach ($cats as $cat) { + if (strlen($category)) + $category .= ', '; + $category .= $cat['term']; + } + } + + if($itm[0]['attach']) { + $j = json_decode($itm[0]['attach'],true); + if($j) { + foreach($j as $jj) { + $itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n"; + } + } + } + + $cipher = get_pconfig(\App::$profile['profile_uid'],'system','default_cipher'); + if(! $cipher) + $cipher = 'aes256'; + + + $editor = replace_macros($tpl,array( + '$return_path' => $_SESSION['return_url'], + '$action' => 'item', + '$share' => t('Edit'), + '$bold' => t('Bold'), + '$italic' => t('Italic'), + '$underline' => t('Underline'), + '$quote' => t('Quote'), + '$code' => t('Code'), + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$weblink' => t('Insert web link'), + '$youtube' => t('Insert YouTube video'), + '$video' => t('Insert Vorbis [.ogg] video'), + '$audio' => t('Insert Vorbis [.ogg] audio'), + '$setloc' => t('Set your location'), + '$noloc' => t('Clear browser location'), + '$voting' => t('Toggle voting'), + '$feature_voting' => $voting, + '$consensus' => intval($itm[0]['item_consensus']), + '$wait' => t('Please wait'), + '$permset' => t('Permission settings'), + '$ptyp' => $itm[0]['obj_type'], + '$content' => undo_post_tagging($itm[0]['body']), + '$post_id' => $post_id, + '$parent' => (($itm[0]['parent'] != $itm[0]['id']) ? $itm[0]['parent'] : ''), + '$baseurl' => z_root(), + '$defloc' => $channel['channel_location'], + '$visitor' => false, + '$public' => t('Public post'), + '$jotnets' => $jotnets, + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + '$placeholdertitle' => t('Title (optional)'), + '$category' => $category, + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), + '$emtitle' => t('Example: bob@example.com, mary@example.com'), + '$lockstate' => $lockstate, + '$acl' => '', + '$bang' => '', + '$profile_uid' => $owner_uid, + '$preview' => t('Preview'), + '$jotplugins' => $jotplugins, + '$sourceapp' => t(\App::$sourcename), + '$catsenabled' => $catsenabled, + '$defexpire' => datetime_convert('UTC', date_default_timezone_get(),$itm[0]['expires']), + '$feature_expire' => ((feature_enabled(\App::$profile['profile_uid'],'content_expire') && (! $webpage)) ? true : false), + '$expires' => t('Set expiration date'), + '$feature_encrypt' => ((feature_enabled(\App::$profile['profile_uid'],'content_encrypt') && (! $webpage)) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + '$expiryModalOK' => t('OK'), + '$expiryModalCANCEL' => t('Cancel'), + '$bbcode' => true + )); + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit post'), + '$editor' => $editor + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php new file mode 100644 index 000000000..01d9e8aad --- /dev/null +++ b/Zotlabs/Module/Editwebpage.php @@ -0,0 +1,239 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { + notice( t('Permission denied.') . EOL); + return; + } + + $is_owner = (($uid && $uid == $owner) ? true : false); + + $o = ''; + + // Figure out which post we're editing + $post_id = ((argc() > 2) ? intval(argv(2)) : 0); + + + if(! $post_id) { + notice( t('Item not found') . EOL); + return; + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + // We've already figured out which item we want and whose copy we need, + // so we don't need anything fancy here + + $sql_extra = item_permissions_sql($owner); + + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s $sql_extra LIMIT 1", + intval($post_id), + intval($owner) + ); + + if(! $itm) { + notice( t('Permission denied.') . EOL); + return; + } + + if(intval($itm[0]['item_obscured'])) { + $key = get_config('system','prvkey'); + if($itm[0]['title']) + $itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key); + if($itm[0]['body']) + $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); + } + + $item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1", + intval($itm[0]['id']) + ); + if($item_id) + $page_title = $item_id[0]['sid']; + + $plaintext = true; + + $mimetype = $itm[0]['mimetype']; + + if($mimetype === 'application/x-php') { + if((! $uid) || ($uid != $itm[0]['uid'])) { + notice( t('Permission denied.') . EOL); + return; + } + } + + $mimeselect = ''; + + if($mimetype != 'text/bbcode') + $plaintext = true; + + if(get_config('system','page_mimetype')) + $mimeselect = ''; + else + $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); + + $layout = get_config('system','page_layout'); + if($layout) + $layoutselect = ''; + else + $layoutselect = layout_select($itm[0]['uid'],$itm[0]['layout_mid']); + + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$pretext' => '', + '$ispublic' => ' ', // t('Visible to everybody'), + '$geotag' => $geotag, + '$nickname' => $channel['channel_address'], + '$confirmdelete' => t('Delete webpage?'), + '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : '') + )); + + $tpl = get_markup_template("jot.tpl"); + + $jotplugins = ''; + $jotnets = ''; + + call_hooks('jot_tool', $jotplugins); + call_hooks('jot_networks', $jotnets); + + // FIXME A return path with $_SESSION doesn't always work for observer - it may WSoD + // instead of loading a sensible page. So, send folk to the webpage list. + + $rp = 'webpages/' . $which; + + $editor = replace_macros($tpl,array( + '$return_path' => $rp, + '$webpage' => ITEM_TYPE_WEBPAGE, + '$placeholdpagetitle' => t('Page link title'), + '$pagetitle' => $page_title, + '$writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_storage'), + '$action' => 'item', + '$share' => t('Edit'), + '$bold' => t('Bold'), + '$italic' => t('Italic'), + '$underline' => t('Underline'), + '$quote' => t('Quote'), + '$code' => t('Code'), + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$weblink' => t('Insert web link'), + '$youtube' => t('Insert YouTube video'), + '$video' => t('Insert Vorbis [.ogg] video'), + '$audio' => t('Insert Vorbis [.ogg] audio'), + '$setloc' => t('Set your location'), + '$noloc' => ((get_pconfig($uid, 'system', 'use_browser_location')) ? t('Clear browser location') : ''), + '$wait' => t('Please wait'), + '$permset' => t('Permission settings'), + '$ptyp' => $itm[0]['type'], + '$content' => undo_post_tagging($itm[0]['body']), + '$post_id' => $post_id, + '$baseurl' => z_root(), + '$defloc' => $itm[0]['location'], + '$visitor' => ($is_owner) ? true : false, + '$acl' => populate_acl($itm[0],false), + '$showacl' => ($is_owner) ? true : false, + '$public' => t('Public post'), + '$jotnets' => $jotnets, + '$mimeselect' => $mimeselect, + '$layoutselect' => $layoutselect, + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + '$placeholdertitle' => t('Title (optional)'), + '$category' => '', + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), + '$emtitle' => t('Example: bob@example.com, mary@example.com'), + 'lockstate' => (((strlen($itm[0]['allow_cid'])) || (strlen($itm[0]['allow_gid'])) || (strlen($itm[0]['deny_cid'])) || (strlen($itm[0]['deny_gid']))) ? 'lock' : 'unlock'), + '$bang' => '', + '$profile_uid' => (intval($owner)), + '$preview' => t('Preview'), + '$jotplugins' => $jotplugins, + '$sourceapp' => \App::$sourcename, + '$defexpire' => '', + '$feature_expire' => false, + '$expires' => t('Set expiration date'), + '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) + )); + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit Webpage'), + '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), + '$editor' => $editor, + '$id' => $itm[0]['id'] + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php new file mode 100644 index 000000000..a14e320b2 --- /dev/null +++ b/Zotlabs/Module/Events.php @@ -0,0 +1,714 @@ +set($x[0]); + + $created = $x[0]['created']; + $edited = datetime_convert(); + + if($x[0]['allow_cid'] === '<' . $channel['channel_hash'] . '>' + && $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '') { + $share = false; + } + else { + $share = true; + } + } + else { + $created = $edited = datetime_convert(); + if($share) { + $acl->set_from_array($_POST); + } + else { + $acl->set(array('allow_cid' => '<' . $channel['channel_hash'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '')); + } + } + + $post_tags = array(); + $channel = \App::get_channel(); + $ac = $acl->get(); + + if(strlen($categories)) { + $cats = explode(',',$categories); + foreach($cats as $cat) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => TERM_CATEGORY, + 'otype' => TERM_OBJ_POST, + 'term' => trim($cat), + 'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)) + ); + } + } + + $datarray = array(); + $datarray['start'] = $start; + $datarray['finish'] = $finish; + $datarray['summary'] = $summary; + $datarray['description'] = $desc; + $datarray['location'] = $location; + $datarray['type'] = $type; + $datarray['adjust'] = $adjust; + $datarray['nofinish'] = $nofinish; + $datarray['uid'] = local_channel(); + $datarray['account'] = get_account_id(); + $datarray['event_xchan'] = $channel['channel_hash']; + $datarray['allow_cid'] = $ac['allow_cid']; + $datarray['allow_gid'] = $ac['allow_gid']; + $datarray['deny_cid'] = $ac['deny_cid']; + $datarray['deny_gid'] = $ac['deny_gid']; + $datarray['private'] = (($acl->is_private()) ? 1 : 0); + $datarray['id'] = $event_id; + $datarray['created'] = $created; + $datarray['edited'] = $edited; + + if(intval($_REQUEST['preview'])) { + $html = format_event_html($datarray); + echo $html; + killme(); + } + + $event = event_store_event($datarray); + + + if($post_tags) + $datarray['term'] = $post_tags; + + $item_id = event_store_item($datarray,$event); + + if($item_id) { + $r = q("select * from item where id = %d", + intval($item_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($r[0]['resource_id']), + intval($channel['channel_id']) + ); + if($z) { + build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); + } + } + } + + if($share) + proc_run('php',"include/notifier.php","event","$item_id"); + + } + + + + function get() { + + if(argc() > 2 && argv(1) == 'ical') { + $event_id = argv(2); + + require_once('include/security.php'); + $sql_extra = permissions_sql(local_channel()); + + $r = q("select * from event where event_hash = '%s' $sql_extra limit 1", + dbesc($event_id) + ); + if($r) { + header('Content-type: text/calendar'); + header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' ); + echo ical_wrapper($r); + killme(); + } + else { + notice( t('Event not found.') . EOL ); + return; + } + } + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + nav_set_selected('all_events'); + + if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { + $r = q("update event set ignore = 1 where id = %d and uid = %d", + intval(argv(2)), + intval(local_channel()) + ); + } + + if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { + $r = q("update event set ignore = 0 where id = %d and uid = %d", + intval(argv(2)), + intval(local_channel()) + ); + } + + $first_day = get_pconfig(local_channel(),'system','cal_first_day'); + $first_day = (($first_day) ? $first_day : 0); + + $htpl = get_markup_template('event_head.tpl'); + \App::$page['htmlhead'] .= replace_macros($htpl,array( + '$baseurl' => z_root(), + '$module_url' => '/events', + '$modparams' => 1, + '$lang' => \App::$language, + '$first_day' => $first_day + )); + + $o = ''; + + $channel = \App::get_channel(); + + $mode = 'view'; + $y = 0; + $m = 0; + $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : ''); + + + // logger('args: ' . print_r(\App::$argv,true)); + + + + if(argc() > 1) { + if(argc() > 2 && argv(1) === 'add') { + $mode = 'add'; + $item_id = intval(argv(2)); + } + if(argc() > 2 && argv(1) === 'drop') { + $mode = 'drop'; + $event_id = argv(2); + } + if(argc() > 2 && intval(argv(1)) && intval(argv(2))) { + $mode = 'view'; + $y = intval(argv(1)); + $m = intval(argv(2)); + } + if(argc() <= 2) { + $mode = 'view'; + $event_id = argv(1); + } + } + + if($mode === 'add') { + event_addtocal($item_id,local_channel()); + killme(); + } + + if($mode == 'view') { + + /* edit/create form */ + if($event_id) { + $r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1", + dbesc($event_id), + intval(local_channel()) + ); + if(count($r)) + $orig_event = $r[0]; + } + + $channel = \App::get_channel(); + + // Passed parameters overrides anything found in the DB + if(!x($orig_event)) + $orig_event = array(); + + // In case of an error the browser is redirected back here, with these parameters filled in with the previous values + /* + if(x($_REQUEST,'nofinish')) $orig_event['nofinish'] = $_REQUEST['nofinish']; + if(x($_REQUEST,'adjust')) $orig_event['adjust'] = $_REQUEST['adjust']; + if(x($_REQUEST,'summary')) $orig_event['summary'] = $_REQUEST['summary']; + if(x($_REQUEST,'description')) $orig_event['description'] = $_REQUEST['description']; + if(x($_REQUEST,'location')) $orig_event['location'] = $_REQUEST['location']; + if(x($_REQUEST,'start')) $orig_event['start'] = $_REQUEST['start']; + if(x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish']; + if(x($_REQUEST,'type')) $orig_event['type'] = $_REQUEST['type']; + */ + + $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); + $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); + $t_orig = ((x($orig_event)) ? $orig_event['summary'] : ''); + $d_orig = ((x($orig_event)) ? $orig_event['description'] : ''); + $l_orig = ((x($orig_event)) ? $orig_event['location'] : ''); + $eid = ((x($orig_event)) ? $orig_event['id'] : 0); + $event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']); + $mid = ((x($orig_event)) ? $orig_event['mid'] : ''); + + if(! x($orig_event)) + $sh_checked = ''; + else + $sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (! $orig_event['allow_cid'])) && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' ); + + if($orig_event['event_xchan']) + $sh_checked .= ' disabled="disabled" '; + + $sdt = ((x($orig_event)) ? $orig_event['start'] : 'now'); + + $fdt = ((x($orig_event)) ? $orig_event['finish'] : '+1 hour'); + + $tz = date_default_timezone_get(); + if(x($orig_event)) + $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC'); + + $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); + $smonth = datetime_convert('UTC', $tz, $sdt, 'm'); + $sday = datetime_convert('UTC', $tz, $sdt, 'd'); + $shour = datetime_convert('UTC', $tz, $sdt, 'H'); + $sminute = datetime_convert('UTC', $tz, $sdt, 'i'); + + $stext = datetime_convert('UTC',$tz,$sdt); + $stext = substr($stext,0,14) . "00:00"; + + $fyear = datetime_convert('UTC', $tz, $fdt, 'Y'); + $fmonth = datetime_convert('UTC', $tz, $fdt, 'm'); + $fday = datetime_convert('UTC', $tz, $fdt, 'd'); + $fhour = datetime_convert('UTC', $tz, $fdt, 'H'); + $fminute = datetime_convert('UTC', $tz, $fdt, 'i'); + + $ftext = datetime_convert('UTC',$tz,$fdt); + $ftext = substr($ftext,0,14) . "00:00"; + + $type = ((x($orig_event)) ? $orig_event['type'] : 'event'); + + $f = get_config('system','event_input_format'); + if(! $f) + $f = 'ymd'; + + $catsenabled = feature_enabled(local_channel(),'categories'); + + $category = ''; + + if($catsenabled && x($orig_event)){ + $itm = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d limit 1", + dbesc($orig_event['event_hash']), + intval(local_channel()) + ); + $itm = fetch_post_tags($itm); + if($itm) { + $cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY); + foreach ($cats as $cat) { + if(strlen($category)) + $category .= ', '; + $category .= $cat['term']; + } + } + } + + require_once('include/acl_selectors.php'); + + $acl = new \Zotlabs\Access\AccessList($channel); + $perm_defaults = $acl->get(); + + $tpl = get_markup_template('event_form.tpl'); + + $form = replace_macros($tpl,array( + '$post' => z_root() . '/events', + '$eid' => $eid, + '$type' => $type, + '$xchan' => $event_xchan, + '$mid' => $mid, + '$event_hash' => $event_id, + '$summary' => array('summary', (($event_id) ? t('Edit event title') : t('Event title')), $t_orig, t('Required'), '*'), + '$catsenabled' => $catsenabled, + '$placeholdercategory' => t('Categories (comma-separated list)'), + '$c_text' => (($event_id) ? t('Edit Category') : t('Category')), + '$category' => $category, + '$required' => '*', + '$s_dsel' => datetimesel($f,new \DateTime(),\DateTime::createFromFormat('Y',$syear+5),\DateTime::createFromFormat('Y-m-d H:i',"$syear-$smonth-$sday $shour:$sminute"), (($event_id) ? t('Edit start date and time') : t('Start date and time')), 'start_text',true,true,'','',true,$first_day), + '$n_text' => t('Finish date and time are not known or not relevant'), + '$n_checked' => $n_checked, + '$f_dsel' => datetimesel($f,new \DateTime(),\DateTime::createFromFormat('Y',$fyear+5),\DateTime::createFromFormat('Y-m-d H:i',"$fyear-$fmonth-$fday $fhour:$fminute"), (($event_id) ? t('Edit finish date and time') : t('Finish date and time')),'finish_text',true,true,'start_text','',false,$first_day), + '$nofinish' => array('nofinish', t('Finish date and time are not known or not relevant'), $n_checked, '', array(t('No'),t('Yes')), 'onclick="enableDisableFinishDate();"'), + '$adjust' => array('adjust', t('Adjust for viewer timezone'), $a_checked, t('Important for events that happen in a particular place. Not practical for global holidays.'), array(t('No'),t('Yes'))), + '$a_text' => t('Adjust for viewer timezone'), + '$d_text' => (($event_id) ? t('Edit Description') : t('Description')), + '$d_orig' => $d_orig, + '$l_text' => (($event_id) ? t('Edit Location') : t('Location')), + '$l_orig' => $l_orig, + '$t_orig' => $t_orig, + '$sh_text' => t('Share this event'), + '$sh_checked' => $sh_checked, + '$share' => array('share', t('Share this event'), $sh_checked, '', array(t('No'),t('Yes'))), + '$preview' => t('Preview'), + '$permissions' => t('Permission settings'), + '$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults),false)), + '$submit' => t('Submit'), + '$advanced' => t('Advanced Options') + + )); + /* end edit/create form */ + + $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); + $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m'); + if(! $y) + $y = intval($thisyear); + if(! $m) + $m = intval($thismonth); + + $export = false; + if(argc() === 4 && argv(3) === 'export') + $export = true; + + // Put some limits on dates. The PHP date functions don't seem to do so well before 1900. + // An upper limit was chosen to keep search engines from exploring links millions of years in the future. + + if($y < 1901) + $y = 1900; + if($y > 2099) + $y = 2100; + + $nextyear = $y; + $nextmonth = $m + 1; + if($nextmonth > 12) { + $nextmonth = 1; + $nextyear ++; + } + + $prevyear = $y; + if($m > 1) + $prevmonth = $m - 1; + else { + $prevmonth = 12; + $prevyear --; + } + + $dim = get_dim($y,$m); + $start = sprintf('%d-%d-%d %d:%d:%d',$y,$m,1,0,0,0); + $finish = sprintf('%d-%d-%d %d:%d:%d',$y,$m,$dim,23,59,59); + + + if (argv(1) === 'json'){ + if (x($_GET,'start')) $start = $_GET['start']; + if (x($_GET,'end')) $finish = $_GET['end']; + } + + $start = datetime_convert('UTC','UTC',$start); + $finish = datetime_convert('UTC','UTC',$finish); + + $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); + $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); + + if (x($_GET,'id')){ + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1", + intval(local_channel()), + intval($_GET['id']) + ); + } elseif($export) { + $r = q("SELECT * from event where uid = %d + AND (( `adjust` = 0 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' ) + OR ( `adjust` = 1 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )) ", + intval(local_channel()), + dbesc($start), + dbesc($finish), + dbesc($adjust_start), + dbesc($adjust_finish) + ); + } + else { + // fixed an issue with "nofinish" events not showing up in the calendar. + // There's still an issue if the finish date crosses the end of month. + // Noting this for now - it will need to be fixed here and in Friendica. + // Ultimately the finish date shouldn't be involved in the query. + + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on event_hash = resource_id + where resource_type = 'event' and event.uid = %d $ignored + AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' ) + OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) ", + intval(local_channel()), + dbesc($start), + dbesc($finish), + dbesc($adjust_start), + dbesc($adjust_finish) + ); + + } + + $links = array(); + + if($r && ! $export) { + xchan_query($r); + $r = fetch_post_tags($r,true); + + $r = sort_by_date($r); + } + + if($r) { + foreach($r as $rr) { + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + if(! x($links,$j)) + $links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j; + } + } + + $events=array(); + + $last_date = ''; + $fmt = t('l, F j'); + + if($r) { + + foreach($r as $rr) { + + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt)); + $d = day_translate($d); + + $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c')); + if ($rr['nofinish']){ + $end = null; + } else { + $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c')); + } + + + $is_first = ($d !== $last_date); + + $last_date = $d; + + $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false); + + $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'',''); + + $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8')); + if(! $title) { + list($title, $_trash) = explode("$rr['id'], + 'hash' => $rr['event_hash'], + 'start'=> $start, + 'end' => $end, + 'drop' => $drop, + 'allDay' => false, + 'title' => $title, + + 'j' => $j, + 'd' => $d, + 'edit' => $edit, + 'is_first'=>$is_first, + 'item'=>$rr, + 'html'=>$html, + 'plink' => array($rr['plink'],t('Link to Source'),'',''), + ); + + + } + } + + if($export) { + header('Content-type: text/calendar'); + header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' ); + echo ical_wrapper($r); + killme(); + } + + if (\App::$argv[1] === 'json'){ + echo json_encode($events); killme(); + } + + // links: array('href', 'text', 'extra css classes', 'title') + if (x($_GET,'id')){ + $tpl = get_markup_template("event.tpl"); + } + else { + $tpl = get_markup_template("events-js.tpl"); + } + + $o = replace_macros($tpl, array( + '$baseurl' => z_root(), + '$new_event' => array(z_root().'/events',(($event_id) ? t('Edit Event') : t('Create Event')),'',''), + '$previus' => array(z_root()."/events/$prevyear/$prevmonth",t('Previous'),'',''), + '$next' => array(z_root()."/events/$nextyear/$nextmonth",t('Next'),'',''), + '$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''), + '$calendar' => cal($y,$m,$links, ' eventcal'), + '$events' => $events, + '$upload' => t('Import'), + '$submit' => t('Submit'), + '$prev' => t('Previous'), + '$next' => t('Next'), + '$today' => t('Today'), + '$form' => $form, + '$expandform' => ((x($_GET,'expandform')) ? true : false), + )); + + if (x($_GET,'id')){ echo $o; killme(); } + + return $o; + } + + if($mode === 'drop' && $event_id) { + $r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1", + dbesc($event_id), + intval(local_channel()) + ); + + $sync_event = $r[0]; + + if($r) { + $r = q("delete from event where event_hash = '%s' and uid = %d limit 1", + dbesc($event_id), + intval(local_channel()) + ); + if($r) { + $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", + dbesc($event_id), + intval(local_channel()) + ); + $sync_event['event_deleted'] = 1; + build_sync_packet(0,array('event' => array($sync_event))); + + info( t('Event removed') . EOL); + } + else { + notice( t('Failed to remove event' ) . EOL); + } + goaway(z_root() . '/events'); + } + } + + } + +} diff --git a/Zotlabs/Module/Fbrowser.php b/Zotlabs/Module/Fbrowser.php new file mode 100644 index 000000000..eef3cb67d --- /dev/null +++ b/Zotlabs/Module/Fbrowser.php @@ -0,0 +1,136 @@ + + */ + +require_once('include/photo/photo_driver.php'); + +/** + * @param App $a + */ + +class Fbrowser extends \Zotlabs\Web\Controller { + + function get(){ + + if (!local_channel()) + killme(); + + if (\App::$argc==1) + killme(); + + //echo "
    "; var_dump(\App::$argv); killme();	
    +		
    +		switch(\App::$argv[1]){
    +			case "image":
    +				$path = array( array(z_root()."/fbrowser/image/", t("Photos")));
    +				$albums = false;
    +				$sql_extra = "";
    +				$sql_extra2 = " ORDER BY created DESC LIMIT 0, 10";
    +				
    +				if (\App::$argc==2){
    +					$albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d ",
    +						intval(local_channel())
    +					);
    +					// anon functions only from 5.3.0... meglio tardi che mai..
    +					$albums = array_map( "self::folder1" , $albums);
    +					
    +				}
    +				
    +				$album = "";
    +				if (\App::$argc==3){
    +					$album = hex2bin(\App::$argv[2]);
    +					$sql_extra = sprintf("AND `album` = '%s' ",dbesc($album));
    +					$sql_extra2 = "";
    +					$path[]=array(z_root()."/fbrowser/image/".\App::$argv[2]."/", $album);
    +				}
    +					
    +				$r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `description`  
    +						FROM `photo` WHERE `uid` = %d $sql_extra
    +						GROUP BY `resource_id` $sql_extra2",
    +					intval(local_channel())					
    +				);
    +				
    +				$files = array_map("self::files1", $r);
    +				
    +				$tpl = get_markup_template("filebrowser.tpl");
    +				echo replace_macros($tpl, array(
    +					'$type' => 'image',
    +					'$baseurl' => z_root(),
    +					'$path' => $path,
    +					'$folders' => $albums,
    +					'$files' =>$files,
    +					'$cancel' => t('Cancel'),
    +				));
    +					
    +					
    +				break;
    +			case "file":
    +				if (\App::$argc==2){
    +					$files = q("SELECT id, filename, filetype FROM `attach` WHERE `uid` = %d ",
    +						intval(local_channel())
    +					);
    +					
    +					$files = array_map("self::files2", $files);
    +					//echo "
    "; var_dump($files); killme();
    +				
    +								
    +					$tpl = get_markup_template("filebrowser.tpl");
    +					echo replace_macros($tpl, array(
    +						'$type' => 'file',
    +						'$baseurl' => z_root(),
    +						'$path' => array( array(z_root()."/fbrowser/image/", t("Files")) ),
    +						'$folders' => false,
    +						'$files' =>$files,
    +						'$cancel' => t('Cancel'),
    +					));
    +					
    +				}
    +			
    +				break;
    +		}
    +		
    +	
    +		killme();
    +		
    +	}
    +
    +	private static function folder1($el){
    +		return array(bin2hex($el['album']),$el['album']);
    +	}	
    +
    +
    +	private static function files1($rr){ 
    +
    +		$ph = photo_factory('');
    +		$types = $ph->supportedTypes();
    +		$ext = $types[$rr['type']];
    +	
    +		$filename_e = $rr['filename'];
    +			
    +		return array( 
    +			z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['hiq'] . '.' .$ext, 
    +			$filename_e, 
    +			z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['loq'] . '.'. $ext
    +		);
    +	}
    +
    +	private static function files2($rr){
    +		list($m1,$m2) = explode("/",$rr['filetype']);
    +		$filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip");
    +	
    +		if(\App::get_template_engine() === 'internal') {
    +			$filename_e = template_escape($rr['filename']);
    +		}
    +		else {
    +			$filename_e = $rr['filename'];
    +		}
    +	
    +		return array( z_root() . '/attach/' . $rr['id'], $filename_e, z_root() . '/images/icons/16/' . $filetype . '.png'); 
    +	}
    +
    +	
    +}
    diff --git a/Zotlabs/Module/Feed.php b/Zotlabs/Module/Feed.php
    new file mode 100644
    index 000000000..9d33ba2c3
    --- /dev/null
    +++ b/Zotlabs/Module/Feed.php
    @@ -0,0 +1,48 @@
    + 1) {
    +			$r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1",
    +				dbesc(argv(1))
    +			);
    +			if(!($r && count($r)))
    +				killme();
    +	
    +			$channel = $r[0];
    +	
    +			if((intval(get_config('system','block_public'))) && (! get_account_id()))
    +				killme();
    +	 
    +			logger('mod_feed: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $channel['channel_address']);
    +	
    +			echo get_public_feed($channel,$params);
    +	
    +			killme();
    +		}
    +	
    +	}
    +	
    +	
    +	
    +}
    diff --git a/Zotlabs/Module/Ffsapi.php b/Zotlabs/Module/Ffsapi.php
    new file mode 100644
    index 000000000..f3ade73c2
    --- /dev/null
    +++ b/Zotlabs/Module/Ffsapi.php
    @@ -0,0 +1,71 @@
    +
    +	
    +	var baseurl = '$baseurl';
    +	
    +	var data = {
    +	  "origin": baseurl,
    +	  // currently required
    +	  "name": '$name',
    +	  "iconURL": baseurl+"/images/hz-16.png",
    +	  "icon32URL": baseurl+"/images/hz-32.png",
    +	  "icon64URL": baseurl+"/images/hz-64.png",
    +	
    +	  // at least one of these must be defined
    +	  // "workerURL": baseurl+"/worker.js",
    +	  // "sidebarURL": baseurl+"/sidebar.htm",
    +	  "shareURL": baseurl+"/rpost?f=&url=%{url}",
    +	
    +	  // status buttons are scheduled for Firefox 26 or 27
    +	  //"statusURL": baseurl+"/statusPanel.html",
    +	
    +	  // social bookmarks are available in Firefox 26
    +	  "markURL": baseurl+"/rbmark?f=&url=%{url}&title=%{title}",
    +	  // icons should be 32x32 pixels
    +	  // "markedIcon": baseurl+"/images/checkbox-checked-32.png",
    +	  // "unmarkedIcon": baseurl+"/images/checkbox-unchecked-32.png",
    +	  "unmarkedIcon": baseurl+"/images/hz-bookmark-32.png",
    +	
    +	  // should be available for display purposes
    +	  "description": "$description",
    +	  "author": "$author",
    +	  "homepageURL": "$homepage",
    +	
    +	  // optional
    +	  "version": "1.0"
    +	}
    +	
    +	function activate(node) {
    +	  var event = new CustomEvent("ActivateSocialFeature");
    +	  var jdata = JSON.stringify(data);
    +	  node.setAttribute("data-service", JSON.stringify(data));
    +	  node.dispatchEvent(event);
    +	}
    +	
    +	
    +	
    +	
    +EOT;
    +	
    +	return $s;
    +	
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Fhublocs.php b/Zotlabs/Module/Fhublocs.php
    new file mode 100644
    index 000000000..f5b439421
    --- /dev/null
    +++ b/Zotlabs/Module/Fhublocs.php
    @@ -0,0 +1,85 @@
    + 1) ? intval(\App::$argv[1]) : 0);
    +	
    +		logger('filer: tag ' . $term . ' item ' . $item_id);
    +	
    +		if($item_id && strlen($term)){
    +			// file item
    +			store_item_tag(local_channel(),$item_id,TERM_OBJ_POST,TERM_FILE,$term,'');
    +	
    +			// protect the entire conversation from periodic expiration
    +	
    +			$r = q("select parent from item where id = %d and uid = %d limit 1",
    +				intval($item_id),
    +				intval(local_channel())
    +			);
    +			if($r) {
    +				$x = q("update item set item_retained = 1 where id = %d and uid = %d",
    +					intval($r[0]['parent']),
    +					intval(local_channel())
    +				);
    +			}
    +		} 
    +		else {
    +			$filetags = array();
    +			$r = q("select distinct(term) from term where uid = %d and type = %d order by term asc",
    +				intval(local_channel()),
    +				intval(TERM_FILE)
    +			);
    +			if(count($r)) {
    +				foreach($r as $rr)
    +					$filetags[] = $rr['term'];
    +			}
    +			$tpl = get_markup_template("filer_dialog.tpl");
    +			$o = replace_macros($tpl, array(
    +				'$field' => array('term', t("Save to Folder:"), '', '', $filetags, t('- select -')),
    +				'$submit' => t('Save'),
    +			));
    +			
    +			echo $o;
    +		}
    +		killme();
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Filerm.php b/Zotlabs/Module/Filerm.php
    new file mode 100644
    index 000000000..eb9a42c1e
    --- /dev/null
    +++ b/Zotlabs/Module/Filerm.php
    @@ -0,0 +1,39 @@
    + 1) ? intval(\App::$argv[1]) : 0);
    +	
    +		logger('filerm: tag ' . $term . ' item ' . $item_id);
    +	
    +		if($item_id && strlen($term)) {
    +			$r = q("delete from term where uid = %d and type = %d and oid = %d and term = '%s'",
    +				intval(local_channel()),
    +				intval(($category) ? TERM_CATEGORY : TERM_FILE),
    +				intval($item_id),
    +				dbesc($term)
    +			);
    +		}
    +	
    +		if(x($_SESSION,'return_url'))
    +			goaway(z_root() . '/' . $_SESSION['return_url']);
    +		
    +		killme();
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php
    new file mode 100644
    index 000000000..934a1e6a4
    --- /dev/null
    +++ b/Zotlabs/Module/Filestorage.php
    @@ -0,0 +1,173 @@
    +set_from_array($_REQUEST);
    +		$x = $acl->get();
    +	
    +		$cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource);
    +	
    +		//get the object before permissions change so we can catch eventual former allowed members
    +		$object = get_file_activity_object($channel_id, $resource, $cloudPath);
    +	
    +		attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse);
    +	
    +		file_activity($channel_id, $object, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], 'post', $notify);
    +	
    +		goaway($cloudPath);
    +	}
    +	
    +		function get() {
    +	
    +		if(argc() > 1)
    +			$which = argv(1);
    +		else {
    +			notice( t('Requested profile is not available.') . EOL );
    +			\App::$error = 404;
    +			return;
    +		}
    +	
    +		$r = q("select * from channel where channel_address = '%s'",
    +			dbesc($which)
    +		);
    +		if($r) {
    +			$channel = $r[0];
    +			$owner = intval($r[0]['channel_id']);
    +		}
    +	
    +		$observer = \App::get_observer();
    +		$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
    +	
    +		$perms = get_all_perms($owner, $ob_hash);
    +	
    +		if(! $perms['view_storage']) {
    +			notice( t('Permission denied.') . EOL);
    +			return;
    +		}
    +	
    +		// Since we have ACL'd files in the wild, but don't have ACL here yet, we
    +		// need to return for anyone other than the owner, despite the perms check for now.
    +	
    +		$is_owner = (((local_channel()) && ($owner  == local_channel())) ? true : false);
    +		if(! $is_owner) {
    +			info( t('Permission Denied.') . EOL );
    +			return;
    +		}
    +	
    +		if(argc() > 3 && argv(3) === 'delete') {
    +			if(! $perms['write_storage']) {
    +				notice( t('Permission denied.') . EOL);
    +				return;
    +			}
    +	
    +			$file = intval(argv(2));
    +			$r = q("SELECT hash FROM attach WHERE id = %d AND uid = %d LIMIT 1",
    +				dbesc($file),
    +				intval($owner)
    +			);
    +			if(! $r) {
    +				notice( t('File not found.') . EOL);
    +				goaway(z_root() . '/cloud/' . $which);
    +			}
    +	
    +			$f = $r[0];
    +			$channel = \App::get_channel();
    +	
    +			$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
    +	
    +			attach_delete($owner, $f['hash']);
    +	
    +			goaway($parentpath);
    +		}
    +	
    +		if(argc() > 3 && argv(3) === 'edit') {
    +			require_once('include/acl_selectors.php');
    +			if(! $perms['write_storage']) {
    +				notice( t('Permission denied.') . EOL);
    +				return;
    +			}
    +			$file = intval(argv(2));
    +	
    +			$r = q("select id, uid, folder, filename, revision, flags, is_dir, os_storage, hash, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and uid = %d limit 1",
    +				intval($file),
    +				intval($owner)
    +			);
    +	
    +			$f = $r[0];
    +			$channel = \App::get_channel();
    +	
    +			$cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : '');
    +			$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
    +	
    +			$aclselect_e = populate_acl($f, false);
    +			$is_a_dir = (intval($f['is_dir']) ? true : false);
    +	
    +			$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock'); 
    +	
    +			// Encode path that is used for link so it's a valid URL
    +			// Keep slashes as slashes, otherwise mod_rewrite doesn't work correctly
    +			$encoded_path = str_replace('%2F', '/', rawurlencode($cloudpath));
    +	
    +			$o = replace_macros(get_markup_template('attach_edit.tpl'), array(
    +				'$header' => t('Edit file permissions'),
    +				'$file' => $f,
    +				'$cloudpath' => z_root() . '/' . $encoded_path,
    +				'$parentpath' => $parentpath,
    +				'$uid' => $channel['channel_id'],
    +				'$channelnick' => $channel['channel_address'],
    +				'$permissions' => t('Permissions'),
    +				'$aclselect' => $aclselect_e,
    +				'$lockstate' => $lockstate,
    +				'$permset' => t('Set/edit permissions'),
    +				'$recurse' => array('recurse', t('Include all files and sub folders'), 0, '', array(t('No'), t('Yes'))),
    +				'$backlink' => t('Return to file list'),
    +				'$isadir' => $is_a_dir,
    +				'$cpdesc' => t('Copy/paste this code to attach file to a post'),
    +				'$cpldesc' => t('Copy/paste this URL to link file from a web page'),
    +				'$submit' => t('Submit'),
    +				'$attach_btn_title' => t('Share this file'),
    +				'$link_btn_title' => t('Show URL to this file'),
    +				'$notify' => array('notify', t('Notify your contacts about this file'), 0, '', array(t('No'), t('Yes')))
    +			));
    +	
    +			echo $o;
    +			killme();
    +		}
    +	
    +		goaway(z_root() . '/cloud/' . $which);
    +	}
    +	
    +}
    diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php
    new file mode 100644
    index 000000000..d3114557b
    --- /dev/null
    +++ b/Zotlabs/Module/Follow.php
    @@ -0,0 +1,65 @@
    + $v) {
    +			if(strpos($k,'abook_') === 0) {
    +				$clone[$k] = $v;
    +			}
    +		}
    +		unset($clone['abook_id']);
    +		unset($clone['abook_account']);
    +		unset($clone['abook_channel']);
    +	
    +		$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
    +		if($abconfig)
    +			$clone['abconfig'] = $abconfig;
    +	
    +		build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
    +	
    +	
    +		// If we can view their stream, pull in some posts
    +	
    +		if(($result['abook']['abook_their_perms'] & PERMS_R_STREAM) || ($result['abook']['xchan_network'] === 'rss'))
    +			proc_run('php','include/onepoll.php',$result['abook']['abook_id']);
    +	
    +		goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1');
    +	
    +	}
    +	
    +		function get() {
    +	
    +		if(! local_channel()) {
    +			return login();
    +		}
    +	}
    +}
    diff --git a/Zotlabs/Module/Fsuggest.php b/Zotlabs/Module/Fsuggest.php
    new file mode 100644
    index 000000000..143fd34e1
    --- /dev/null
    +++ b/Zotlabs/Module/Fsuggest.php
    @@ -0,0 +1,117 @@
    +' . t('Suggest Friends') . '';
    +	
    +		$o .= '
    ' . sprintf( t('Suggest a friend for %s'), $contact['name']) . '
    '; + + $o .= '
    '; + + // FIXME contact_selector deprecated, removed + // $o .= contact_selector('suggest','suggest-select', false, + // array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true)); + + + $o .= '
    '; + $o .= '
    '; + + return $o; + } +} diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php new file mode 100644 index 000000000..6999e77e8 --- /dev/null +++ b/Zotlabs/Module/Getfile.php @@ -0,0 +1,102 @@ + $d1) || ($time < $d2)) { + logger('time outside allowable range'); + killme(); + } + + if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) { + logger('verify failed.'); + killme(); + } + + + $r = attach_by_hash($resource,$revision); + + if(! $r['success']) { + notice( $r['message'] . EOL); + return; + } + + + $unsafe_types = array('text/html','text/css','application/javascript'); + + if(in_array($r['data']['filetype'],$unsafe_types)) { + header('Content-type: text/plain'); + } + else { + header('Content-type: ' . $r['data']['filetype']); + } + + header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); + if(intval($r['data']['os_storage'])) { + $fname = dbunescbin($r['data']['data']); + if(strpos($fname,'store') !== false) + $istream = fopen($fname,'rb'); + else + $istream = fopen('store/' . $channel['channel_address'] . '/' . $fname,'rb'); + $ostream = fopen('php://output','wb'); + if($istream && $ostream) { + pipe_streams($istream,$ostream); + fclose($istream); + fclose($ostream); + } + } + else + echo dbunescbin($r['data']['data']); + killme(); + + + + } +} diff --git a/Zotlabs/Module/Group.php b/Zotlabs/Module/Group.php new file mode 100644 index 000000000..144797baf --- /dev/null +++ b/Zotlabs/Module/Group.php @@ -0,0 +1,244 @@ + t('Submit')); + + if((argc() == 2) && (argv(1) === 'new')) { + + return replace_macros($tpl, $context + array( + '$title' => t('Create a group of channels.'), + '$gname' => array('groupname',t('Privacy group name: '), '', ''), + '$gid' => 'new', + '$public' => array('public',t('Members are visible to other channels'), false, ''), + '$form_security_token' => get_form_security_token("group_edit"), + )); + + + } + + if((argc() == 3) && (argv(1) === 'drop')) { + check_form_security_token_redirectOnErr('/group', 'group_drop', 't'); + + if(intval(argv(2))) { + $r = q("SELECT `name` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval(argv(2)), + intval(local_channel()) + ); + if($r) + $result = group_rmv(local_channel(),$r[0]['name']); + if($result) + info( t('Privacy group removed.') . EOL); + else + notice( t('Unable to remove privacy group.') . EOL); + } + goaway(z_root() . '/group'); + // NOTREACHED + } + + + if((argc() > 2) && intval(argv(1)) && argv(2)) { + + check_form_security_token_ForbiddenOnErr('group_member_change', 't'); + + $r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1", + dbesc(base64url_decode(argv(2))), + intval(local_channel()) + ); + if(count($r)) + $change = base64url_decode(argv(2)); + + } + + if((argc() > 1) && (intval(argv(1)))) { + + require_once('include/acl_selectors.php'); + $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", + intval(argv(1)), + intval(local_channel()) + ); + if(! $r) { + notice( t('Privacy group not found.') . EOL ); + goaway(z_root() . '/connections'); + } + $group = $r[0]; + + + $members = group_get_members($group['id']); + + $preselected = array(); + if(count($members)) { + foreach($members as $member) + if(! in_array($member['xchan_hash'],$preselected)) + $preselected[] = $member['xchan_hash']; + } + + if($change) { + + if(in_array($change,$preselected)) { + group_rmv_member(local_channel(),$group['name'],$change); + } + else { + group_add_member(local_channel(),$group['name'],$change); + } + + $members = group_get_members($group['id']); + + $preselected = array(); + if(count($members)) { + foreach($members as $member) + $preselected[] = $member['xchan_hash']; + } + } + + $drop_tpl = get_markup_template('group_drop.tpl'); + $drop_txt = replace_macros($drop_tpl, array( + '$id' => $group['id'], + '$delete' => t('Delete'), + '$form_security_token' => get_form_security_token("group_drop"), + )); + + + $context = $context + array( + '$title' => t('Privacy group editor'), + '$gname' => array('groupname',t('Privacy group name: '),$group['name'], ''), + '$gid' => $group['id'], + '$drop' => $drop_txt, + '$public' => array('public',t('Members are visible to other channels'), $group['visible'], ''), + '$form_security_token' => get_form_security_token('group_edit'), + ); + + } + + if(! isset($group)) + return; + + $groupeditor = array( + 'label_members' => t('Members'), + 'members' => array(), + 'label_contacts' => t('All Connected Channels'), + 'contacts' => array(), + ); + + $sec_token = addslashes(get_form_security_token('group_member_change')); + $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); + foreach($members as $member) { + if($member['xchan_url']) { + $member['archived'] = (intval($member['abook_archived']) ? true : false); + $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;'; + $groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); + } + else + group_rmv_member(local_channel(),$group['name'],$member['xchan_hash']); + } + + $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", + intval(local_channel()) + ); + + if(count($r)) { + $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); + foreach($r as $member) { + if(! in_array($member['xchan_hash'],$preselected)) { + $member['archived'] = (intval($member['abook_archived']) ? true : false); + $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;'; + $groupeditor['contacts'][] = micropro($member,true,'mpall', $textmode); + } + } + } + + $context['$groupeditor'] = $groupeditor; + $context['$desc'] = t('Click on a channel to add or remove.'); + + if($change) { + $tpl = get_markup_template('groupeditor.tpl'); + echo replace_macros($tpl, $context); + killme(); + } + + return replace_macros($tpl, $context); + + } + + +} diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php new file mode 100644 index 000000000..2636e676b --- /dev/null +++ b/Zotlabs/Module/Hcard.php @@ -0,0 +1,60 @@ + 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $profile = ''; + $channel = \App::get_channel(); + + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", + intval($profile), + intval(local_channel()) + ); + if(! $r) + $profile = ''; + $profile = $r[0]['profile_guid']; + } + + \App::$page['htmlhead'] .= '' . "\r\n" ; + + if(! $profile) { + $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", + dbesc(argv(1)) + ); + if($x) { + \App::$profile = $x[0]; + } + } + + profile_load($a,$which,$profile); + + + } + + + function get() { + + require_once('include/widgets.php'); + return widget_profile(array()); + + + + } + + + +} diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php new file mode 100644 index 000000000..4842c56c6 --- /dev/null +++ b/Zotlabs/Module/Help.php @@ -0,0 +1,146 @@ +'; + $o .= '
    '; + $o .= '

    ' . t('Documentation Search') . ' - ' . htmlspecialchars($_REQUEST['search']) . '

    '; + $o .= '
    '; + $o .= '
    '; + + $r = search_doc_files($_REQUEST['search']); + if($r) { + $o .= '
      '; + foreach($r as $rr) { + $dirname = dirname($rr['sid']); + $fname = basename($rr['sid']); + $fname = substr($fname,0,strrpos($fname,'.')); + $path = trim(substr($dirname,4),'/'); + + $o .= '
    • ' . ucwords(str_replace('_',' ',notags($fname))) . '
      ' . + str_replace('$Projectname',\Zotlabs\Project\System::get_platform_name(),substr($rr['text'],0,200)) . '...

    • '; + + } + $o .= '
    '; + $o .= '
    '; + $o .= ''; + } + return $o; + } + + + global $lang; + + $doctype = 'markdown'; + + $text = ''; + + if(argc() > 1) { + $path = ''; + for($x = 1; $x < argc(); $x ++) { + if(strlen($path)) + $path .= '/'; + $path .= argv($x); + } + $title = basename($path); + + $text = load_doc_file('doc/' . $path . '.md'); + \App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title))); + + if(! $text) { + $text = load_doc_file('doc/' . $path . '.bb'); + if($text) + $doctype = 'bbcode'; + \App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('_',' ',notags($title))); + } + if(! $text) { + $text = load_doc_file('doc/' . $path . '.html'); + if($text) + $doctype = 'html'; + \App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title))); + } + } + + if(! $text) { + $text = load_doc_file('doc/Site.md'); + \App::$page['title'] = t('Help'); + } + if(! $text) { + $doctype = 'bbcode'; + $text = load_doc_file('doc/main.bb'); + \App::$page['title'] = t('Help'); + } + + if(! strlen($text)) { + header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . t('Not Found')); + $tpl = get_markup_template("404.tpl"); + return replace_macros($tpl, array( + '$message' => t('Page not found.' ) + )); + } + + if($doctype === 'html') + $content = $text; + if($doctype === 'markdown') { + require_once('library/markdown.php'); + # escape #include tags + $text = preg_replace('/#include/ism', '%%include', $text); + $content = Markdown($text); + $content = preg_replace('/%%include/ism', '#include', $content); + } + if($doctype === 'bbcode') { + require_once('include/bbcode.php'); + $content = bbcode($text); + // bbcode retargets external content to new windows. This content is internal. + $content = str_replace(' target="_blank"','',$content); + } + + $content = preg_replace_callback("/#include (.*?)\;/ism", 'self::preg_callback_help_include', $content); + + return replace_macros(get_markup_template("help.tpl"), array( + '$title' => t('$Projectname Documentation'), + '$content' => translate_projectname($content) + )); + + } + + + private static function preg_callback_help_include($matches) { + + if($matches[1]) { + $include = str_replace($matches[0],load_doc_file($matches[1]),$matches[0]); + if(preg_match('/\.bb$/', $matches[1]) || preg_match('/\.txt$/', $matches[1])) { + require_once('include/bbcode.php'); + $include = bbcode($include); + $include = str_replace(' target="_blank"','',$include); + } + elseif(preg_match('/\.md$/', $matches[1])) { + require_once('library/markdown.php'); + $include = Markdown($include); + } + return $include; + } + + } + + +} diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php new file mode 100644 index 000000000..f3ba96fdd --- /dev/null +++ b/Zotlabs/Module/Home.php @@ -0,0 +1,89 @@ + 1 && argv(1) === 'splash') ? true : false); + + $channel = \App::get_channel(); + if(local_channel() && $channel && $channel['xchan_url'] && ! $splash) { + $dest = $channel['channel_startpage']; + if(! $dest) + $dest = get_pconfig(local_channel(),'system','startpage'); + if(! $dest) + $dest = get_config('system','startpage'); + if(! $dest) + $dest = z_root() . '/network'; + + goaway($dest); + } + + if(get_account_id() && ! $splash) { + goaway(z_root() . '/new_channel'); + } + + } + + + function get($update = 0, $load = false) { + + $o = ''; + + + if(x($_SESSION,'theme')) + unset($_SESSION['theme']); + if(x($_SESSION,'mobile_theme')) + unset($_SESSION['mobile_theme']); + + $splash = ((argc() > 1 && argv(1) === 'splash') ? true : false); + + call_hooks('home_content',$o); + if($o) + return $o; + + $frontpage = get_config('system','frontpage'); + if($frontpage) { + if(strpos($frontpage,'include:') !== false) { + $file = trim(str_replace('include:' , '', $frontpage)); + if(file_exists($file)) { + \App::$page['template'] = 'full'; + \App::$page['title'] = t('$Projectname'); + $o .= file_get_contents($file); + return $o; + } + } + if(strpos($frontpage,'http') !== 0) + $frontpage = z_root() . '/' . $frontpage; + if(intval(get_config('system','mirror_frontpage'))) { + $o = '' . t('$Projectname') . ''; + echo $o; + killme(); + } + goaway($frontpage); + } + + + $sitename = get_config('system','sitename'); + if($sitename) + $o .= '

    ' . sprintf( t("Welcome to %s") ,$sitename) . '

    '; + + $loginbox = get_config('system','login_on_homepage'); + if(intval($loginbox) || $loginbox === false) + $o .= login((\App::$config['system']['register_policy'] == REGISTER_CLOSED) ? 0 : 1); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Id.php b/Zotlabs/Module/Id.php new file mode 100644 index 000000000..6a94b57f5 --- /dev/null +++ b/Zotlabs/Module/Id.php @@ -0,0 +1,319 @@ + t('First Name'), + 'namePerson/last' => t('Last Name'), + 'namePerson/friendly' => t('Nickname'), + 'namePerson' => t('Full Name'), + 'contact/internet/email' => t('Email'), + 'contact/email' => t('Email'), + 'media/image/aspect11' => t('Profile Photo'), + 'media/image' => t('Profile Photo'), + 'media/image/default' => t('Profile Photo'), + 'media/image/16x16' => t('Profile Photo 16px'), + 'media/image/32x32' => t('Profile Photo 32px'), + 'media/image/48x48' => t('Profile Photo 48px'), + 'media/image/64x64' => t('Profile Photo 64px'), + 'media/image/80x80' => t('Profile Photo 80px'), + 'media/image/128x128' => t('Profile Photo 128px'), + 'timezone' => t('Timezone'), + 'contact/web/default' => t('Homepage URL'), + 'language/pref' => t('Language'), + 'birthDate/birthYear' => t('Birth Year'), + 'birthDate/birthMonth' => t('Birth Month'), + 'birthDate/birthday' => t('Birth Day'), + 'birthDate' => t('Birthdate'), + 'gender' => t('Gender'), +); + + +/** + * @brief Entrypoint for the OpenID implementation. + * + * @param App &$a + */ + +class Id extends \Zotlabs\Web\Controller { + + function init() { + + logger('id: ' . print_r($_REQUEST, true)); + + if(argc() > 1) { + $which = argv(1); + } else { + \App::$error = 404; + return; + } + + $profile = ''; + $channel = \App::get_channel(); + profile_load($a,$which,$profile); + + $op = new MysqlProvider; + $op->server(); + } + + /** + * @brief Returns user data needed for OpenID. + * + * If no $handle is provided we will use local_channel() by default. + * + * @param string $handle (default null) + * @return boolean|array + */ + static public function getUserData($handle = null) { + if (! local_channel()) { + notice( t('Permission denied.') . EOL); + \App::$page['content'] = login(); + + return false; + } + + // logger('handle: ' . $handle); + + if ($handle) { + $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1", + dbesc($handle) + ); + } else { + $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d", + intval(local_channel()) + ); + } + + if (! r) + return false; + + $x = q("select * from account where account_id = %d limit 1", + intval($r[0]['channel_account_id']) + ); + if ($x) + $r[0]['email'] = $x[0]['account_email']; + + $p = q("select * from profile where is_default = 1 and uid = %d limit 1", + intval($r[0]['channel_account_id']) + ); + + $gender = ''; + if ($p[0]['gender'] == t('Male')) + $gender = 'M'; + if ($p[0]['gender'] == t('Female')) + $gender = 'F'; + + $r[0]['firstName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],0,strpos($r[0]['channel_name'],' ')) : $r[0]['channel_name']); + $r[0]['lastName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],strpos($r[0]['channel_name'],' ')+1) : ''); + $r[0]['namePerson'] = $r[0]['channel_name']; + $r[0]['pphoto'] = $r[0]['xchan_photo_l']; + $r[0]['pphoto16'] = z_root() . '/photo/profile/16/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['pphoto32'] = z_root() . '/photo/profile/32/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['pphoto48'] = z_root() . '/photo/profile/48/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['pphoto64'] = z_root() . '/photo/profile/64/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['pphoto80'] = z_root() . '/photo/profile/80/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['pphoto128'] = z_root() . '/photo/profile/128/' . $r[0]['channel_id'] . '.jpg'; + $r[0]['timezone'] = $r[0]['channel_timezone']; + $r[0]['url'] = $r[0]['xchan_url']; + $r[0]['language'] = (($x[0]['account_language']) ? $x[0]['account_language'] : 'en'); + $r[0]['birthyear'] = ((intval(substr($p[0]['dob'],0,4))) ? intval(substr($p[0]['dob'],0,4)) : ''); + $r[0]['birthmonth'] = ((intval(substr($p[0]['dob'],5,2))) ? intval(substr($p[0]['dob'],5,2)) : ''); + $r[0]['birthday'] = ((intval(substr($p[0]['dob'],8,2))) ? intval(substr($p[0]['dob'],8,2)) : ''); + $r[0]['birthdate'] = (($r[0]['birthyear'] && $r[0]['birthmonth'] && $r[0]['birthday']) ? $p[0]['dob'] : ''); + $r[0]['gender'] = $gender; + + return $r[0]; + + /* + * if(isset($_POST['login'],$_POST['password'])) { + * $login = mysql_real_escape_string($_POST['login']); + * $password = sha1($_POST['password']); + * $q = mysql_query("SELECT * FROM Users WHERE login = '$login' AND password = '$password'"); + * if($data = mysql_fetch_assoc($q)) { + * return $data; + * } + * if($handle) { + * echo 'Wrong login/password.'; + * } + * } + * if($handle) { + * ?> + *
    + * + * Login:
    + * Password:
    + * + *
    + * 'firstName', + 'namePerson/last' => 'lastName', + 'namePerson/friendly' => 'channel_address', + 'namePerson' => 'namePerson', + 'contact/internet/email' => 'email', + 'contact/email' => 'email', + 'media/image/aspect11' => 'pphoto', + 'media/image' => 'pphoto', + 'media/image/default' => 'pphoto', + 'media/image/16x16' => 'pphoto16', + 'media/image/32x32' => 'pphoto32', + 'media/image/48x48' => 'pphoto48', + 'media/image/64x64' => 'pphoto64', + 'media/image/80x80' => 'pphoto80', + 'media/image/128x128' => 'pphoto128', + 'timezone' => 'timezone', + 'contact/web/default' => 'url', + 'language/pref' => 'language', + 'birthDate/birthYear' => 'birthyear', + 'birthDate/birthMonth' => 'birthmonth', + 'birthDate/birthday' => 'birthday', + 'birthDate' => 'birthdate', + 'gender' => 'gender', + ); + + function setup($identity, $realm, $assoc_handle, $attributes) { + global $attrMap; + + // logger('identity: ' . $identity); + // logger('realm: ' . $realm); + // logger('assoc_handle: ' . $assoc_handle); + // logger('attributes: ' . print_r($attributes,true)); + + $data = \Zotlabs\Module\Id::getUserData($assoc_handle); + + + /** @FIXME this needs to be a template with localised strings */ + + $o .= '
    ' + . '' + . '' + . '' + . "$realm wishes to authenticate you."; + if($attributes['required'] || $attributes['optional']) { + $o .= " It also requests following information (required fields marked with *):" + . '
      '; + + foreach($attributes['required'] as $attr) { + if(isset($this->attrMap[$attr])) { + $o .= '
    • ' + . ' ' + . $this->attrMap[$attr] . ' *
    • '; + } + } + + foreach($attributes['optional'] as $attr) { + if(isset($this->attrMap[$attr])) { + $o .= '
    • ' + . ' ' + . $this->attrMap[$attr] . '
    • '; + } + } + $o .= '
    '; + } + $o .= '
    ' + . ' ' + . ' ' + . ' ' + . '
    '; + + \App::$page['content'] .= $o; + } + + function checkid($realm, &$attributes) { + + logger('checkid: ' . $realm); + logger('checkid attrs: ' . print_r($attributes,true)); + + if(isset($_POST['cancel'])) { + $this->cancel(); + } + + $data = \Zotlabs\Module\Id::getUserData(); + if(! $data) { + return false; + } + + $q = get_pconfig(local_channel(), 'openid', $realm); + + $attrs = array(); + if($q) { + $attrs = $q; + } elseif(isset($_POST['attributes'])) { + $attrs = array_keys($_POST['attributes']); + } elseif(!isset($_POST['once']) && !isset($_POST['always'])) { + return false; + } + + $attributes = array(); + foreach($attrs as $attr) { + if(isset($this->attrFieldMap[$attr])) { + $attributes[$attr] = $data[$this->attrFieldMap[$attr]]; + } + } + + if(isset($_POST['always'])) { + set_pconfig(local_channel(),'openid',$realm,array_keys($attributes)); + } + + return z_root() . '/id/' . $data['channel_address']; + } + + function assoc_handle() { + logger('assoc_handle'); + $channel = \App::get_channel(); + + return z_root() . '/channel/' . $channel['channel_address']; + } + + function setAssoc($handle, $data) { + logger('setAssoc'); + $channel = channelx_by_nick(basename($handle)); + if($channel) + set_pconfig($channel['channel_id'],'openid','associate',$data); + } + + function getAssoc($handle) { + logger('getAssoc: ' . $handle); + + $channel = channelx_by_nick(basename($handle)); + if($channel) + return get_pconfig($channel['channel_id'], 'openid', 'associate'); + + return false; + } + + function delAssoc($handle) { + logger('delAssoc'); + $channel = channelx_by_nick(basename($handle)); + if($channel) + return del_pconfig($channel['channel_id'], 'openid', 'associate'); + } + } + diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php new file mode 100644 index 000000000..bdf5042dd --- /dev/null +++ b/Zotlabs/Module/Impel.php @@ -0,0 +1,207 @@ + false); + + if(! local_channel()) + json_return_and_die($ret); + + logger('impel: ' . print_r($_REQUEST,true), LOGGER_DATA); + + $elm = $_REQUEST['element']; + $x = base64url_decode($elm); + if(! $x) + json_return_and_die($ret); + + $j = json_decode($x,true); + if(! $j) + json_return_and_die($ret); + + $channel = \App::get_channel(); + + $arr = array(); + $is_menu = false; + + // a portable menu has its links rewritten with the local baseurl + $portable_menu = false; + + switch($j['type']) { + case 'webpage': + $arr['item_type'] = ITEM_TYPE_WEBPAGE; + $namespace = 'WEBPAGE'; + $installed_type = t('webpage'); + break; + case 'block': + $arr['item_type'] = ITEM_TYPE_BLOCK; + $namespace = 'BUILDBLOCK'; + $installed_type = t('block'); + break; + case 'layout': + $arr['item_type'] = ITEM_TYPE_PDL; + $namespace = 'PDL'; + $installed_type = t('layout'); + break; + case 'portable-menu': + $portable_menu = true; + // fall through + case 'menu': + $is_menu = true; + $installed_type = t('menu'); + break; + default: + logger('mod_impel: unrecognised element type' . print_r($j,true)); + break; + } + + if($is_menu) { + $m = array(); + $m['menu_channel_id'] = local_channel(); + $m['menu_name'] = $j['pagetitle']; + $m['menu_desc'] = $j['desc']; + if($j['created']) + $m['menu_created'] = datetime_convert($j['created']); + if($j['edited']) + $m['menu_edited'] = datetime_convert($j['edited']); + + $m['menu_flags'] = 0; + if($j['flags']) { + if(in_array('bookmark',$j['flags'])) + $m['menu_flags'] |= MENU_BOOKMARK; + if(in_array('system',$j['flags'])) + $m['menu_flags'] |= MENU_SYSTEM; + + } + + $menu_id = menu_create($m); + + if($menu_id) { + if(is_array($j['items'])) { + foreach($j['items'] as $it) { + $mitem = array(); + + $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']); + $mitem['mitem_desc'] = escape_tags($it['desc']); + $mitem['mitem_order'] = intval($it['order']); + if(is_array($it['flags'])) { + $mitem['mitem_flags'] = 0; + if(in_array('zid',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_ZID; + if(in_array('new-window',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN; + if(in_array('chatroom',$it['flags'])) + $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM; + } + menu_add_item($menu_id,local_channel(),$mitem); + } + if($j['edited']) { + $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", + dbesc(datetime_convert('UTC','UTC',$j['edited'])), + intval($menu_id), + intval(local_channel()) + ); + } + } + $ret['success'] = true; + } + $x = $ret; + } + else { + $arr['uid'] = local_channel(); + $arr['aid'] = $channel['channel_account_id']; + $arr['title'] = $j['title']; + $arr['body'] = $j['body']; + $arr['term'] = $j['term']; + $arr['layout_mid'] = $j['layout_mid']; + $arr['created'] = datetime_convert('UTC','UTC', $j['created']); + $arr['edited'] = datetime_convert('UTC','UTC',$j['edited']); + $arr['owner_xchan'] = get_observer_hash(); + $arr['author_xchan'] = (($j['author_xchan']) ? $j['author_xchan'] : get_observer_hash()); + $arr['mimetype'] = (($j['mimetype']) ? $j['mimetype'] : 'text/bbcode'); + + if(! $j['mid']) + $j['mid'] = item_message_id(); + + $arr['mid'] = $arr['parent_mid'] = $j['mid']; + + + if($j['pagetitle']) { + require_once('library/urlify/URLify.php'); + $pagetitle = strtolower(URLify::transliterate($j['pagetitle'])); + } + + + + // 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; + } + } + + $remote_id = 0; + + $z = q("select * from item_id where sid = '%s' and service = '%s' and uid = %d limit 1", + dbesc($pagetitle), + dbesc($namespace), + intval(local_channel()) + ); + + $i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", + dbesc($arr['mid']), + intval(local_channel()) + ); + + if($z && $i) { + $remote_id = $z[0]['id']; + $arr['id'] = $i[0]['id']; + // don't update if it has the same timestamp as the original + if($arr['edited'] > $i[0]['edited']) + $x = item_store_update($arr,$execflag); + } + else { + if(($i) && (intval($i[0]['item_deleted']))) { + // was partially deleted already, finish it off + q("delete from item where mid = '%s' and uid = %d", + dbesc($arr['mid']), + intval(local_channel()) + ); + } + $x = item_store($arr,$execflag); + } + + if($x['success']) { + $item_id = $x['item_id']; + update_remote_id($channel,$item_id,$arr['item_type'],$pagetitle,$namespace,$remote_id,$arr['mid']); + } + } + + if($x['success']) { + $ret['success'] = true; + info( sprintf( t('%s element installed'), $installed_type)); + } + else { + notice( sprintf( t('%s element installation failed'), $installed_type)); + } + + //??? should perhaps return ret? + json_return_and_die(true); + + } + +} diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php new file mode 100644 index 000000000..dadbf8ff1 --- /dev/null +++ b/Zotlabs/Module/Import.php @@ -0,0 +1,553 @@ + $max_identities) { + notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL); + return; + } + } + + + $data = null; + $seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0); + $import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0); + $src = $_FILES['filename']['tmp_name']; + $filename = basename($_FILES['filename']['name']); + $filesize = intval($_FILES['filename']['size']); + $filetype = $_FILES['filename']['type']; + + $completed = ((array_key_exists('import_step',$_SESSION)) ? intval($_SESSION['import_step']) : 0); + if($completed) + logger('saved import step: ' . $_SESSION['import_step']); + + if($src) { + + // This is OS specific and could also fail if your tmpdir isn't very large + // mostly used for Diaspora which exports gzipped files. + + if(strpos($filename,'.gz')){ + @rename($src,$src . '.gz'); + @system('gunzip ' . escapeshellarg($src . '.gz')); + } + + if($filesize) { + $data = @file_get_contents($src); + } + unlink($src); + } + + if(! $src) { + $old_address = ((x($_REQUEST,'old_address')) ? $_REQUEST['old_address'] : ''); + if(! $old_address) { + logger('mod_import: nothing to import.'); + notice( t('Nothing to import.') . EOL); + return; + } + + $email = ((x($_REQUEST,'email')) ? $_REQUEST['email'] : ''); + $password = ((x($_REQUEST,'password')) ? $_REQUEST['password'] : ''); + + $channelname = substr($old_address,0,strpos($old_address,'@')); + $servername = substr($old_address,strpos($old_address,'@')+1); + + $scheme = 'https://'; + $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname; + if($import_posts) + $api_path .= '&posts=1'; + $binary = false; + $redirects = 0; + $opts = array('http_auth' => $email . ':' . $password); + $url = $scheme . $servername . $api_path; + $ret = z_fetch_url($url, $binary, $redirects, $opts); + if(! $ret['success']) + $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts); + if($ret['success']) + $data = $ret['body']; + else + notice( t('Unable to download data from old server') . EOL); + + } + + if(! $data) { + logger('mod_import: empty file.'); + notice( t('Imported file is empty.') . EOL); + return; + } + + $data = json_decode($data,true); + + // logger('import: data: ' . print_r($data,true)); + // print_r($data); + + + if(array_key_exists('user',$data) && array_key_exists('version',$data)) { + require_once('include/Import/import_diaspora.php'); + import_diaspora($data); + return; + } + + $moving = false; + + if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { + $v1 = substr($data['compatibility']['database'],-4); + $v2 = substr(DB_UPDATE_VERSION,-4); + if($v2 > $v1) { + $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); + notice($t); + } + if(array_key_exists('server_role',$data['compatibility']) && $data['compatibility']['server_role'] == 'basic') + $moving = true; + } + + if($moving) + $seize = 1; + + // import channel + + if(array_key_exists('channel',$data)) { + + if($completed < 1) { + $channel = import_channel($data['channel'], $account_id, $seize); + + } + else { + $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", + intval($account_id), + dbesc($channel['channel_guid']) + ); + if($r) + $channel = $r[0]; + } + if(! $channel) { + logger('mod_import: channel not found. ', print_r($channel,true)); + notice( t('Cloned channel not found. Import failed.') . EOL); + return; + } + } + + if(! $channel) + $channel = \App::get_channel(); + + if(! $channel) { + logger('mod_import: channel not found. ', print_r($channel,true)); + notice( t('No channel. Import failed.') . EOL); + return; + } + + + if($completed < 2) { + if(is_array($data['config'])) { + import_config($channel,$data['config']); + } + + logger('import step 2'); + $_SESSION['import_step'] = 2; + } + + + if($completed < 3) { + + if($data['photo']) { + require_once('include/photo/photo_driver.php'); + import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],$account_id,$channel['channel_id']); + } + + if(is_array($data['profile'])) + import_profiles($channel,$data['profile']); + + logger('import step 3'); + $_SESSION['import_step'] = 3; + } + + + if($completed < 4) { + + if(is_array($data['hubloc']) && (! $moving)) { + import_hublocs($channel,$data['hubloc'],$seize); + + } + logger('import step 4'); + $_SESSION['import_step'] = 4; + } + + if($completed < 5) { + // create new hubloc for the new channel at this site + + $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, + hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey ) + values ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", + dbesc($channel['channel_guid']), + dbesc($channel['channel_guid_sig']), + dbesc($channel['channel_hash']), + dbesc($channel['channel_address'] . '@' . \App::get_hostname()), + dbesc('zot'), + intval(($seize) ? 1 : 0), + dbesc(z_root()), + dbesc(base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))), + dbesc(\App::get_hostname()), + dbesc(z_root() . '/post'), + dbesc(get_config('system','pubkey')) + ); + + // reset the original primary hubloc if it is being seized + + if($seize) { + $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", + dbesc($channel['channel_hash']), + dbesc(z_root()) + ); + } + logger('import step 5'); + $_SESSION['import_step'] = 5; + } + + + if($completed < 6) { + + // import xchans and contact photos + + if($seize) { + + // replace any existing xchan we may have on this site if we're seizing control + + $r = q("delete from xchan where xchan_hash = '%s'", + dbesc($channel['channel_hash']) + ); + + $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )", + dbesc($channel['channel_hash']), + dbesc($channel['channel_guid']), + dbesc($channel['channel_guid_sig']), + dbesc($channel['channel_pubkey']), + dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']), + dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']), + dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']), + dbesc($channel['channel_address'] . '@' . \App::get_hostname()), + dbesc(z_root() . '/channel/' . $channel['channel_address']), + dbesc(z_root() . '/follow?f=&url=%s'), + dbesc(z_root() . '/poco/' . $channel['channel_address']), + dbesc($channel['channel_name']), + dbesc('zot'), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + 0,0,0,0,0,0,0 + ); + } + logger('import step 6'); + $_SESSION['import_step'] = 6; + } + + if($completed < 7) { + + $xchans = $data['xchan']; + if($xchans) { + foreach($xchans as $xchan) { + + $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']); + if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) { + logger('forged xchan: ' . print_r($xchan,true)); + continue; + } + + if(! array_key_exists('xchan_hidden',$xchan)) { + $xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0); + $xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0); + $xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0); + $xchan['xchan_selfcensored'] = (($xchan['xchan_flags'] & 0x0008) ? 1 : 0); + $xchan['xchan_system'] = (($xchan['xchan_flags'] & 0x0010) ? 1 : 0); + $xchan['xchan_pubforum'] = (($xchan['xchan_flags'] & 0x0020) ? 1 : 0); + $xchan['xchan_deleted'] = (($xchan['xchan_flags'] & 0x1000) ? 1 : 0); + } + + $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", + dbesc($xchan['xchan_hash']) + ); + if($r) + continue; + + dbesc_array($xchan); + + $r = dbq("INSERT INTO xchan (`" + . implode("`, `", array_keys($xchan)) + . "`) VALUES ('" + . implode("', '", array_values($xchan)) + . "')" ); + + + require_once('include/photo/photo_driver.php'); + $photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']); + if($photos[4]) + $photodate = NULL_DATE; + else + $photodate = $xchan['xchan_photo_date']; + + $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' + where xchan_hash = '%s'", + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($photodate), + dbesc($xchan['xchan_hash']) + ); + + } + } + logger('import step 7'); + $_SESSION['import_step'] = 7; + + } + + + + // FIXME - ensure we have an xchan if somebody is trying to pull a fast one + + if($completed < 8) { + $friends = 0; + $feeds = 0; + + // import contacts + $abooks = $data['abook']; + if($abooks) { + foreach($abooks as $abook) { + + $abconfig = null; + if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) + $abconfig = $abook['abconfig']; + + unset($abook['abook_id']); + unset($abook['abook_rating']); + unset($abook['abook_rating_text']); + $abook['abook_account'] = $account_id; + $abook['abook_channel'] = $channel['channel_id']; + if(! array_key_exists('abook_blocked',$abook)) { + $abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0); + $abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0); + $abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0); + $abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0); + $abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0); + $abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0); + $abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0); + $abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0); + } + + if($abook['abook_self']) { + $role = get_pconfig($channel['channel_id'],'system','permissions_role'); + if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) { + q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ", + dbesc($abook['abook_xchan']) + ); + } + } + else { + if($max_friends !== false && $friends > $max_friends) + continue; + if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds)) + continue; + } + + dbesc_array($abook); + $r = dbq("INSERT INTO abook (`" + . implode("`, `", array_keys($abook)) + . "`) VALUES ('" + . implode("', '", array_values($abook)) + . "')" ); + + $friends ++; + if(intval($abook['abook_feed'])) + $feeds ++; + + if($abconfig) { + // @fixme does not handle sync of del_abconfig + foreach($abconfig as $abc) { + if($abc['chan'] === $channel['channel_hash']) + set_abconfig($abc['chan'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']); + } + } + + + + } + } + logger('import step 8'); + $_SESSION['import_step'] = 8; + } + + + + if($completed < 9) { + $groups = $data['group']; + if($groups) { + $saved = array(); + foreach($groups as $group) { + $saved[$group['hash']] = array('old' => $group['id']); + unset($group['id']); + $group['uid'] = $channel['channel_id']; + dbesc_array($group); + $r = dbq("INSERT INTO groups (`" + . implode("`, `", array_keys($group)) + . "`) VALUES ('" + . implode("', '", array_values($group)) + . "')" ); + } + $r = q("select * from `groups` where uid = %d", + intval($channel['channel_id']) + ); + if($r) { + foreach($r as $rr) { + $saved[$rr['hash']]['new'] = $rr['id']; + } + } + } + + + $group_members = $data['group_member']; + if($group_members) { + foreach($group_members as $group_member) { + unset($group_member['id']); + $group_member['uid'] = $channel['channel_id']; + foreach($saved as $x) { + if($x['old'] == $group_member['gid']) + $group_member['gid'] = $x['new']; + } + dbesc_array($group_member); + $r = dbq("INSERT INTO group_member (`" + . implode("`, `", array_keys($group_member)) + . "`) VALUES ('" + . implode("', '", array_values($group_member)) + . "')" ); + } + } + logger('import step 9'); + $_SESSION['import_step'] = 9; + } + + if(is_array($data['obj'])) + import_objs($channel,$data['obj']); + + if(is_array($data['likes'])) + import_likes($channel,$data['likes']); + + if(is_array($data['app'])) + import_apps($channel,$data['app']); + + if(is_array($data['chatroom'])) + import_chatrooms($channel,$data['chatroom']); + + if(is_array($data['conv'])) + import_conv($channel,$data['conv']); + + if(is_array($data['mail'])) + import_mail($channel,$data['mail']); + + if(is_array($data['event'])) + import_events($channel,$data['event']); + + if(is_array($data['event_item'])) + import_items($channel,$data['event_item']); + + if(is_array($data['menu'])) + import_menus($channel,$data['menu']); + + $addon = array('channel' => $channel,'data' => $data); + call_hooks('import_channel',$addon); + + $saved_notification_flags = notifications_off($channel['channel_id']); + + if($import_posts && array_key_exists('item',$data) && $data['item']) + import_items($channel,$data['item']); + + notifications_on($channel['channel_id'],$saved_notification_flags); + + + if(array_key_exists('item_id',$data) && $data['item_id']) + import_item_ids($channel,$data['item_id']); + + + // FIXME - ensure we have a self entry if somebody is trying to pull a fast one + + // send out refresh requests + // notify old server that it may no longer be primary. + + proc_run('php','include/notifier.php','location',$channel['channel_id']); + + // This will indirectly perform a refresh_all *and* update the directory + + proc_run('php', 'include/directory.php', $channel['channel_id']); + + + notice( t('Import completed.') . EOL); + + change_channel($channel['channel_id']); + + unset($_SESSION['import_step']); + goaway(z_root() . '/network' ); + + } + + + function post() { + + $account_id = get_account_id(); + if(! $account_id) + return; + + $this->import_account($account_id); + } + + function get() { + + if(! get_account_id()) { + notice( t('You must be logged in to use this feature.')); + return ''; + } + + $o = replace_macros(get_markup_template('channel_import.tpl'),array( + '$title' => t('Import Channel'), + '$desc' => t('Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file.'), + '$label_filename' => t('File to Upload'), + '$choice' => t('Or provide the old server/hub details'), + '$label_old_address' => t('Your old identity address (xyz@example.com)'), + '$label_old_email' => t('Your old login email address'), + '$label_old_pass' => t('Your old login password'), + '$common' => t('For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media.'), + '$label_import_primary' => t('Make this hub my primary location'), + '$label_import_posts' => t('Import existing posts if possible (experimental - limited by available memory'), + '$pleasewait' => t('This process may take several minutes to complete. Please submit the form only once and leave this page open until finished.'), + '$email' => '', + '$pass' => '', + '$submit' => t('Submit') + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Import_items.php b/Zotlabs/Module/Import_items.php new file mode 100644 index 000000000..a862836c5 --- /dev/null +++ b/Zotlabs/Module/Import_items.php @@ -0,0 +1,129 @@ + $email . ':' . $password); + $url = $scheme . $servername . $api_path; + $ret = z_fetch_url($url, $binary, $redirects, $opts); + if(! $ret['success']) + $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts); + if($ret['success']) + $data = $ret['body']; + else + notice( t('Unable to download data from old server') . EOL); + + } + + if(! $data) { + logger('mod_import: empty file.'); + notice( t('Imported file is empty.') . EOL); + return; + } + + $data = json_decode($data,true); + + // logger('import: data: ' . print_r($data,true)); + // print_r($data); + + + if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { + $v1 = substr($data['compatibility']['database'],-4); + $v2 = substr(DB_UPDATE_VERSION,-4); + if($v2 > $v1) { + $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); + notice($t); + } + } + + $channel = \App::get_channel(); + + + if(array_key_exists('item',$data) && $data['item']) { + import_items($channel,$data['item']); + } + + if(array_key_exists('item_id',$data) && $data['item_id']) { + import_item_ids($channel,$data['item_id']); + } + + info( t('Import completed') . EOL); + return; + } + + + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied') . EOL); + return login(); + } + + $o = replace_macros(get_markup_template('item_import.tpl'),array( + '$title' => t('Import Items'), + '$desc' => t('Use this form to import existing posts and content from an export file.'), + '$label_filename' => t('File to Upload'), + '$submit' => t('Submit') + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Invite.php b/Zotlabs/Module/Invite.php new file mode 100644 index 000000000..3d7438484 --- /dev/null +++ b/Zotlabs/Module/Invite.php @@ -0,0 +1,152 @@ + $max_invites) { + notice( t('Total invitation limit exceeded.') . EOL); + return; + }; + + + $recips = ((x($_POST,'recipients')) ? explode("\n",$_POST['recipients']) : array()); + $message = ((x($_POST,'message')) ? notags(trim($_POST['message'])) : ''); + + $total = 0; + + if(get_config('system','invitation_only')) { + $invonly = true; + $x = get_pconfig(local_channel(),'system','invites_remaining'); + if((! $x) && (! is_site_admin())) + return; + } + + foreach($recips as $recip) { + + $recip = trim($recip); + if(! $recip) + continue; + + if(! valid_email($recip)) { + notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL); + continue; + } + + else + $nmessage = $message; + + $account = \App::get_account(); + + + $res = mail($recip, sprintf( t('Please join us on $Projectname'), \App::$config['sitename']), + $nmessage, + "From: " . $account['account_email'] . "\n" + . 'Content-type: text/plain; charset=UTF-8' . "\n" + . 'Content-transfer-encoding: 8bit' ); + + if($res) { + $total ++; + $current_invites ++; + set_pconfig(local_channel(),'system','sent_invites',$current_invites); + if($current_invites > $max_invites) { + notice( t('Invitation limit exceeded. Please contact your site administrator.') . EOL); + return; + } + } + else { + notice( sprintf( t('%s : Message delivery failed.'), $recip) . EOL); + } + + } + notice( sprintf( tt("%d message sent.", "%d messages sent.", $total) , $total) . EOL); + return; + } + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + $tpl = get_markup_template('invite.tpl'); + $invonly = false; + + if(get_config('system','invitation_only')) { + $invonly = true; + $x = get_pconfig(local_channel(),'system','invites_remaining'); + if((! $x) && (! is_site_admin())) { + notice( t('You have no more invitations available') . EOL); + return ''; + } + } + + if($invonly && ($x || is_site_admin())) { + $invite_code = autoname(8) . rand(1000,9999); + $nmessage = str_replace('$invite_code',$invite_code,$message); + + $r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ", + dbesc($invite_code), + dbesc(datetime_convert()) + ); + + if(! is_site_admin()) { + $x --; + if($x >= 0) + set_pconfig(local_channel(),'system','invites_remaining',$x); + else + return; + } + } + + $ob = \App::get_observer(); + if(! $ob) + return $o; + + $channel = \App::get_channel(); + + $o = replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("send_invite"), + '$invite' => t('Send invitations'), + '$addr_text' => t('Enter email addresses, one per line:'), + '$msg_text' => t('Your message:'), + '$default_message' => t('Please join my community on $Projectname.') . "\r\n" . "\r\n" + . $linktxt + . (($invonly) ? "\r\n" . "\r\n" . t('You will need to supply this invitation code:') . " " . $invite_code . "\r\n" . "\r\n" : '') + . t('1. Register at any $Projectname location (they are all inter-connected)') + . "\r\n" . "\r\n" . z_root() . '/register' + . "\r\n" . "\r\n" . t('2. Enter my $Projectname network address into the site searchbar.') + . "\r\n" . "\r\n" . $ob['xchan_addr'] . ' (' . t('or visit') . " " . z_root() . '/channel/' . $channel['channel_address'] . ')' + . "\r\n" . "\r\n" + . t('3. Click [Connect]') + . "\r\n" . "\r\n" , + '$submit' => t('Submit') + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php new file mode 100644 index 000000000..2c7a7b572 --- /dev/null +++ b/Zotlabs/Module/Item.php @@ -0,0 +1,1265 @@ + 1); + echo json_encode($json); + killme(); + } + + call_hooks('post_local_start', $_REQUEST); + + // logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA); + + $api_source = ((x($_REQUEST,'api_source') && $_REQUEST['api_source']) ? true : false); + + $consensus = intval($_REQUEST['consensus']); + + // 'origin' (if non-zero) indicates that this network is where the message originated, + // for the purpose of relaying comments to other conversation members. + // If using the API from a device (leaf node) you must set origin to 1 (default) or leave unset. + // If the API is used from another network with its own distribution + // and deliveries, you may wish to set origin to 0 or false and allow the other + // network to relay comments. + + // If you are unsure, it is prudent (and important) to leave it unset. + + $origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1); + + // To represent message-ids on other networks - this will create an item_id record + + $namespace = (($api_source && array_key_exists('namespace',$_REQUEST)) ? strip_tags($_REQUEST['namespace']) : ''); + $remote_id = (($api_source && array_key_exists('remote_id',$_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : ''); + + $owner_hash = null; + + $message_id = ((x($_REQUEST,'message_id') && $api_source) ? strip_tags($_REQUEST['message_id']) : ''); + $created = ((x($_REQUEST,'created')) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['created']) : datetime_convert()); + $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); + $app = ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''); + $return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : ''); + $preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0); + $categories = ((x($_REQUEST,'category')) ? escape_tags($_REQUEST['category']) : ''); + $webpage = ((x($_REQUEST,'webpage')) ? intval($_REQUEST['webpage']) : 0); + $pagetitle = ((x($_REQUEST,'pagetitle')) ? escape_tags(urlencode($_REQUEST['pagetitle'])) : ''); + $layout_mid = ((x($_REQUEST,'layout_mid')) ? escape_tags($_REQUEST['layout_mid']): ''); + $plink = ((x($_REQUEST,'permalink')) ? escape_tags($_REQUEST['permalink']) : ''); + $obj_type = ((x($_REQUEST,'obj_type')) ? escape_tags($_REQUEST['obj_type']) : ACTIVITY_OBJ_NOTE); + + // allow API to bulk load a bunch of imported items with sending out a bunch of posts. + $nopush = ((x($_REQUEST,'nopush')) ? intval($_REQUEST['nopush']) : 0); + + /* + * Check service class limits + */ + if ($uid && !(x($_REQUEST,'parent')) && !(x($_REQUEST,'post_id'))) { + $ret = $this->item_check_service_class($uid,(($_REQUEST['webpage'] == ITEM_TYPE_WEBPAGE) ? true : false)); + if (!$ret['success']) { + notice( t($ret['message']) . EOL) ; + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + } + + if($pagetitle) { + require_once('library/urlify/URLify.php'); + $pagetitle = strtolower(URLify::transliterate($pagetitle)); + } + + + $item_flags = $item_restrict = 0; + + $route = ''; + $parent_item = null; + $parent_contact = null; + $thr_parent = ''; + $parid = 0; + $r = false; + + if($parent || $parent_mid) { + + if(! x($_REQUEST,'type')) + $_REQUEST['type'] = 'net-comment'; + + if($obj_type == ACTIVITY_OBJ_POST) + $obj_type = ACTIVITY_OBJ_COMMENT; + + if($parent) { + $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", + intval($parent) + ); + } + elseif($parent_mid && $uid) { + // This is coming from an API source, and we are logged in + $r = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", + dbesc($parent_mid), + intval($uid) + ); + } + // if this isn't the real parent of the conversation, find it + if($r !== false && count($r)) { + $parid = $r[0]['parent']; + $parent_mid = $r[0]['mid']; + if($r[0]['id'] != $r[0]['parent']) { + $r = q("SELECT * FROM `item` WHERE `id` = `parent` AND `parent` = %d LIMIT 1", + intval($parid) + ); + } + } + + if(($r === false) || (! count($r))) { + notice( t('Unable to locate original post.') . EOL); + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + + // can_comment_on_post() needs info from the following xchan_query + xchan_query($r); + + $parent_item = $r[0]; + $parent = $r[0]['id']; + + // multi-level threading - preserve the info but re-parent to our single level threading + + $thr_parent = $parent_mid; + + $route = $parent_item['route']; + + } + + if(! $observer) + $observer = \App::get_observer(); + + if($parent) { + logger('mod_item: item_post parent=' . $parent); + $can_comment = false; + if((array_key_exists('owner',$parent_item)) && intval($parent_item['owner']['abook_self'])) + $can_comment = perm_is_allowed($profile_uid,$observer['xchan_hash'],'post_comments'); + else + $can_comment = can_comment_on_post($observer['xchan_hash'],$parent_item); + + if(! $can_comment) { + notice( t('Permission denied.') . EOL) ; + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + } + else { + if(! perm_is_allowed($profile_uid,$observer['xchan_hash'],($webpage) ? 'write_pages' : 'post_wall')) { + notice( t('Permission denied.') . EOL) ; + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + } + + + // is this an edited post? + + $orig_post = null; + + if($namespace && $remote_id) { + // It wasn't an internally generated post - see if we've got an item matching this remote service id + $i = q("select iid from item_id where service = '%s' and sid = '%s' limit 1", + dbesc($namespace), + dbesc($remote_id) + ); + if($i) + $post_id = $i[0]['iid']; + } + + $iconfig = null; + + if($post_id) { + $i = q("SELECT * FROM `item` WHERE `uid` = %d AND `id` = %d LIMIT 1", + intval($profile_uid), + intval($post_id) + ); + if(! count($i)) + killme(); + $orig_post = $i[0]; + $iconfig = q("select * from iconfig where iid = %d", + intval($post_id) + ); + } + + + if(! $channel) { + if($uid && $uid == $profile_uid) { + $channel = \App::get_channel(); + } + else { + // posting as yourself but not necessarily to a channel you control + $r = q("select * from channel left join account on channel_account_id = account_id where channel_id = %d LIMIT 1", + intval($profile_uid) + ); + if($r) + $channel = $r[0]; + } + } + + + if(! $channel) { + logger("mod_item: no channel."); + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + + $owner_xchan = null; + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($channel['channel_hash']) + ); + if($r && count($r)) { + $owner_xchan = $r[0]; + } + else { + logger("mod_item: no owner."); + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + + $walltowall = false; + $walltowall_comment = false; + + if($remote_xchan) + $observer = $remote_observer; + + if($observer) { + logger('mod_item: post accepted from ' . $observer['xchan_name'] . ' for ' . $owner_xchan['xchan_name'], LOGGER_DEBUG); + + // wall-to-wall detection. + // For top-level posts, if the author and owner are different it's a wall-to-wall + // For comments, We need to additionally look at the parent and see if it's a wall post that originated locally. + + if($observer['xchan_name'] != $owner_xchan['xchan_name']) { + if(($parent_item) && ($parent_item['item_wall'] && $parent_item['item_origin'])) { + $walltowall_comment = true; + $walltowall = true; + } + if(! $parent) { + $walltowall = true; + } + } + } + + $acl = new \Zotlabs\Access\AccessList($channel); + + + $public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($channel['channel_r_stream'],true)); + if($webpage) + $public_policy = ''; + if($public_policy) + $private = 1; + + if($orig_post) { + $private = 0; + // webpages are allowed to change ACLs after the fact. Normal conversation items aren't. + if($webpage) { + $acl->set_from_array($_REQUEST); + } + else { + $acl->set($orig_post); + $public_policy = $orig_post['public_policy']; + $private = $orig_post['item_private']; + } + + if($private || $public_policy || $acl->is_private()) + $private = 1; + + + $location = $orig_post['location']; + $coord = $orig_post['coord']; + $verb = $orig_post['verb']; + $app = $orig_post['app']; + $title = escape_tags(trim($_REQUEST['title'])); + $body = trim($_REQUEST['body']); + $item_flags = $orig_post['item_flags']; + + $item_origin = $orig_post['item_origin']; + $item_unseen = $orig_post['item_unseen']; + $item_starred = $orig_post['item_starred']; + $item_uplink = $orig_post['item_uplink']; + $item_consensus = $orig_post['item_consensus']; + $item_wall = $orig_post['item_wall']; + $item_thread_top = $orig_post['item_thread_top']; + $item_notshown = $orig_post['item_notshown']; + $item_nsfw = $orig_post['item_nsfw']; + $item_relay = $orig_post['item_relay']; + $item_mentionsme = $orig_post['item_mentionsme']; + $item_nocomment = $orig_post['item_nocomment']; + $item_obscured = $orig_post['item_obscured']; + $item_verified = $orig_post['item_verified']; + $item_retained = $orig_post['item_retained']; + $item_rss = $orig_post['item_rss']; + $item_deleted = $orig_post['item_deleted']; + $item_type = $orig_post['item_type']; + $item_hidden = $orig_post['item_hidden']; + $item_unpublished = $orig_post['item_unpublished']; + $item_delayed = $orig_post['item_delayed']; + $item_pending_remove = $orig_post['item_pending_remove']; + $item_blocked = $orig_post['item_blocked']; + + + + $postopts = $orig_post['postopts']; + $created = $orig_post['created']; + $mid = $orig_post['mid']; + $parent_mid = $orig_post['parent_mid']; + $plink = $orig_post['plink']; + + } + else { + if(! $walltowall) { + if((array_key_exists('contact_allow',$_REQUEST)) + || (array_key_exists('group_allow',$_REQUEST)) + || (array_key_exists('contact_deny',$_REQUEST)) + || (array_key_exists('group_deny',$_REQUEST))) { + $acl->set_from_array($_REQUEST); + } + elseif(! $api_source) { + + // if no ACL has been defined and we aren't using the API, the form + // didn't send us any parameters. This means there's no ACL or it has + // been reset to the default audience. + // If $api_source is set and there are no ACL parameters, we default + // to the channel permissions which were set in the ACL contructor. + + $acl->set(array('allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '')); + } + } + + + $location = notags(trim($_REQUEST['location'])); + $coord = notags(trim($_REQUEST['coord'])); + $verb = notags(trim($_REQUEST['verb'])); + $title = escape_tags(trim($_REQUEST['title'])); + $body = trim($_REQUEST['body']); + $body .= trim($_REQUEST['attachment']); + $postopts = ''; + + $private = intval($acl->is_private() || ($public_policy)); + + // If this is a comment, set the permissions from the parent. + + if($parent_item) { + $private = 0; + $acl->set($parent_item); + $private = intval($acl->is_private() || $parent_item['item_private']); + $public_policy = $parent_item['public_policy']; + $owner_hash = $parent_item['owner_xchan']; + } + + if(! strlen($body)) { + if($preview) + killme(); + info( t('Empty post discarded.') . EOL ); + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + } + + + $expires = NULL_DATE; + + if(feature_enabled($profile_uid,'content_expire')) { + if(x($_REQUEST,'expire')) { + $expires = datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expire']); + if($expires <= datetime_convert()) + $expires = NULL_DATE; + } + } + + $mimetype = notags(trim($_REQUEST['mimetype'])); + if(! $mimetype) + $mimetype = 'text/bbcode'; + + if($preview) { + $body = z_input_filter($profile_uid,$body,$mimetype); + } + + + // Verify ability to use html or php!!! + + $execflag = false; + + if($mimetype !== 'text/bbcode') { + $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; + } + else { + notice( t('Executable content type not permitted to this channel.') . EOL); + if(x($_REQUEST,'return')) + goaway(z_root() . "/" . $return_path ); + killme(); + } + } + } + + $gacl = $acl->get(); + $str_contact_allow = $gacl['allow_cid']; + $str_group_allow = $gacl['allow_gid']; + $str_contact_deny = $gacl['deny_cid']; + $str_group_deny = $gacl['deny_gid']; + + if($mimetype === 'text/bbcode') { + + require_once('include/text.php'); + + // Markdown doesn't work correctly. Do not re-enable unless you're willing to fix it and support it. + + // Sample that will probably give you grief - you must preserve the linebreaks + // and provide the correct markdown interpretation and you cannot allow unfiltered HTML + + // Markdown + // ======== + // + // **bold** abcde + // fghijkl + // *italic* + // + + // if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) { + // require_once('include/bb2diaspora.php'); + // $body = escape_tags(trim($body)); + // $body = str_replace("\n",'
    ', $body); + // $body = preg_replace_callback('/\[share(.*?)\]/ism','\share_shield',$body); + // $body = diaspora2bb($body,true); + // $body = preg_replace_callback('/\[share(.*?)\]/ism','\share_unshield',$body); + // } + + // BBCODE alert: the following functions assume bbcode input + // and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.) + // we may need virtual or template classes to implement the possible alternatives + + // Work around doubled linefeeds in Tinymce 3.5b2 + // First figure out if it's a status post that would've been + // created using tinymce. Otherwise leave it alone. + + $plaintext = true; + + // $plaintext = ((feature_enabled($profile_uid,'richtext')) ? false : true); + // if((! $parent) && (! $api_source) && (! $plaintext)) { + // $body = fix_mce_lf($body); + // } + + + + // If we're sending a private top-level message with a single @-taggable channel as a recipient, @-tag it, if our pconfig is set. + + + if((! $parent) && (get_pconfig($profile_uid,'system','tagifonlyrecip')) && (substr_count($str_contact_allow,'<') == 1) && ($str_group_allow == '') && ($str_contact_deny == '') && ($str_group_deny == '')) { + $x = q("select abook_id, abook_their_perms from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc(str_replace(array('<','>'),array('',''),$str_contact_allow)), + intval($profile_uid) + ); + if($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL)) + $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; + } + + /** + * fix naked links by passing through a callback to see if this is a red site + * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. + * First protect any url inside certain bbcode tags so we don't double link it. + */ + + + $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body); + $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body); + $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body); + + $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", '\red_zrl_callback', $body); + + $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body); + $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body); + $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body); + + + // fix any img tags that should be zmg + + $body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body); + + + $body = bb_translate_video($body); + + /** + * Fold multi-line [code] sequences + */ + + $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body); + + $body = scale_external_images($body,false); + + + // Look for tags and linkify them + $results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid); + + if($results) { + + // Set permissions based on tag replacements + set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $parent_item, $private); + + $post_tags = array(); + foreach($results as $result) { + $success = $result['success']; + if($success['replaced']) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } + } + } + + + /** + * + * When a photo was uploaded into the message using the (profile wall) ajax + * uploader, The permissions are initially set to disallow anybody but the + * owner from seeing it. This is because the permissions may not yet have been + * set for the post. If it's private, the photo permissions should be set + * appropriately. But we didn't know the final permissions on the post until + * now. So now we'll look for links of uploaded photos and attachments that are in the + * post and set them to the same permissions as the post itself. + * + * If the post was end-to-end encrypted we can't find images and attachments in the body, + * use our media_str input instead which only contains these elements - but only do this + * when encrypted content exists because the photo/attachment may have been removed from + * the post and we should keep it private. If it's encrypted we have no way of knowing + * so we'll set the permissions regardless and realise that the media may not be + * referenced in the post. + * + * What is preventing us from being able to upload photos into comments is dealing with + * the photo and attachment permissions, since we don't always know who was in the + * distribution for the top level post. + * + * We might be able to provide this functionality with a lot of fiddling: + * - if the top level post is public (make the photo public) + * - if the top level post was written by us or a wall post that belongs to us (match the top level post) + * - if the top level post has privacy mentions, add those to the permissions. + * - otherwise disallow the photo *or* make the photo public. This is the part that gets messy. + */ + + if(! $preview) { + $this->fix_attached_photo_permissions($profile_uid,$owner_xchan['xchan_hash'],((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); + + $this->fix_attached_file_permissions($channel,$observer['xchan_hash'],((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); + + } + + + $attachments = ''; + $match = false; + + if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) { + $attachments = array(); + $i = 0; + foreach($match[2] as $mtch) { + $attach_link = ''; + $hash = substr($mtch,0,strpos($mtch,',')); + $rev = intval(substr($mtch,strpos($mtch,','))); + $r = attach_by_hash_nodata($hash,$rev); + if($r['success']) { + $attachments[] = array( + 'href' => z_root() . '/attach/' . $r['data']['hash'], + 'length' => $r['data']['filesize'], + 'type' => $r['data']['filetype'], + 'title' => urlencode($r['data']['filename']), + 'revision' => $r['data']['revision'] + ); + } + $ext = substr($r['data']['filename'],strrpos($r['data']['filename'],'.')); + if(strpos($r['data']['filetype'],'audio/') !== false) + $attach_link = '[audio]' . z_root() . '/attach/' . $r['data']['hash'] . '/' . $r['data']['revision'] . (($ext) ? $ext : '') . '[/audio]'; + elseif(strpos($r['data']['filetype'],'video/') !== false) + $attach_link = '[video]' . z_root() . '/attach/' . $r['data']['hash'] . '/' . $r['data']['revision'] . (($ext) ? $ext : '') . '[/video]'; + $body = str_replace($match[1][$i],$attach_link,$body); + $i++; + } + } + + } + + // BBCODE end alert + + if(strlen($categories)) { + $cats = explode(',',$categories); + foreach($cats as $cat) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => TERM_CATEGORY, + 'otype' => TERM_OBJ_POST, + 'term' => trim($cat), + 'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)) + ); + } + } + + if($orig_post) { + // preserve original tags + $t = q("select * from term where oid = %d and otype = %d and uid = %d and type in ( %d, %d, %d )", + intval($orig_post['id']), + intval(TERM_OBJ_POST), + intval($profile_uid), + intval(TERM_UNKNOWN), + intval(TERM_FILE), + intval(TERM_COMMUNITYTAG) + ); + if($t) { + foreach($t as $t1) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => $t1['type'], + 'otype' => TERM_OBJ_POST, + 'term' => $t1['term'], + 'url' => $t1['url'], + ); + } + } + } + + + $item_unseen = ((local_channel() != $profile_uid) ? 1 : 0); + $item_wall = (($post_type === 'wall' || $post_type === 'wall-comment') ? 1 : 0); + $item_origin = (($origin) ? 1 : 0); + $item_consensus = (($consensus) ? 1 : 0); + + + // determine if this is a wall post + + if($parent) { + $item_wall = $parent_item['item_wall']; + } + else { + if(! $webpage) { + $item_wall = 1; + } + } + + + if($moderated) + $item_blocked = ITEM_MODERATED; + + + if(! strlen($verb)) + $verb = ACTIVITY_POST ; + + $notify_type = (($parent) ? 'comment-new' : 'wall-new' ); + + if(! $mid) { + $mid = (($message_id) ? $message_id : item_message_id()); + } + if(! $parent_mid) { + $parent_mid = $mid; + } + + if($parent_item) + $parent_mid = $parent_item['mid']; + + // Fallback so that we alway have a thr_parent + + if(!$thr_parent) + $thr_parent = $mid; + + $datarray = array(); + + $item_thread_top = ((! $parent) ? 1 : 0); + + if ((! $plink) && ($item_thread_top)) { + $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid; + } + + + + + + $datarray['aid'] = $channel['channel_account_id']; + $datarray['uid'] = $profile_uid; + + $datarray['owner_xchan'] = (($owner_hash) ? $owner_hash : $owner_xchan['xchan_hash']); + $datarray['author_xchan'] = $observer['xchan_hash']; + $datarray['created'] = $created; + $datarray['edited'] = (($orig_post) ? datetime_convert() : $created); + $datarray['expires'] = $expires; + $datarray['commented'] = (($orig_post) ? datetime_convert() : $created); + $datarray['received'] = (($orig_post) ? datetime_convert() : $created); + $datarray['changed'] = (($orig_post) ? datetime_convert() : $created); + $datarray['mid'] = $mid; + $datarray['parent_mid'] = $parent_mid; + $datarray['mimetype'] = $mimetype; + $datarray['title'] = $title; + $datarray['body'] = $body; + $datarray['app'] = $app; + $datarray['location'] = $location; + $datarray['coord'] = $coord; + $datarray['verb'] = $verb; + $datarray['obj_type'] = $obj_type; + $datarray['allow_cid'] = $str_contact_allow; + $datarray['allow_gid'] = $str_group_allow; + $datarray['deny_cid'] = $str_contact_deny; + $datarray['deny_gid'] = $str_group_deny; + $datarray['item_private'] = $private; + $datarray['item_wall'] = $item_wall; + $datarray['attach'] = $attachments; + $datarray['thr_parent'] = $thr_parent; + $datarray['postopts'] = $postopts; + $datarray['item_unseen'] = $item_unseen; + $datarray['item_wall'] = $item_wall; + $datarray['item_origin'] = $item_origin; + $datarray['item_type'] = $webpage; + $datarray['item_thread_top'] = $item_thread_top; + $datarray['item_unseen'] = $item_unseen; + $datarray['item_starred'] = $item_starred; + $datarray['item_uplink'] = $item_uplink; + $datarray['item_consensus'] = $item_consensus; + $datarray['item_notshown'] = $item_notshown; + $datarray['item_nsfw'] = $item_nsfw; + $datarray['item_relay'] = $item_relay; + $datarray['item_mentionsme'] = $item_mentionsme; + $datarray['item_nocomment'] = $item_nocomment; + $datarray['item_obscured'] = $item_obscured; + $datarray['item_verified'] = $item_verified; + $datarray['item_retained'] = $item_retained; + $datarray['item_rss'] = $item_rss; + $datarray['item_deleted'] = $item_deleted; + $datarray['item_hidden'] = $item_hidden; + $datarray['item_unpublished'] = $item_unpublished; + $datarray['item_delayed'] = $item_delayed; + $datarray['item_pending_remove'] = $item_pending_remove; + $datarray['item_blocked'] = $item_blocked; + + $datarray['layout_mid'] = $layout_mid; + $datarray['public_policy'] = $public_policy; + $datarray['comment_policy'] = map_scope($channel['channel_w_comment']); + $datarray['term'] = $post_tags; + $datarray['plink'] = $plink; + $datarray['route'] = $route; + + if($iconfig) + $datarray['iconfig'] = $iconfig; + + // preview mode - prepare the body for display and send it via json + + if($preview) { + require_once('include/conversation.php'); + + $datarray['owner'] = $owner_xchan; + $datarray['author'] = $observer; + $datarray['attach'] = json_encode($datarray['attach']); + $o = conversation($a,array($datarray),'search',false,'preview'); + // logger('preview: ' . $o, LOGGER_DEBUG); + echo json_encode(array('preview' => $o)); + killme(); + } + if($orig_post) + $datarray['edit'] = true; + + if(feature_enabled($profile_uid,'suppress_duplicates') && (! $orig_post)) { + + $z = q("select created from item where uid = %d and body = '%s'", + intval($profile_uid), + dbesc($body) + ); + + if($z) { + foreach($z as $zz) { + if($zz['created'] > datetime_convert('UTC','UTC', 'now - 2 minutes')) { + $datarray['cancel'] = 1; + notice( t('Duplicate post suppressed.') . EOL); + logger('Duplicate post. Faking plugin cancel.'); + } + } + } + } + + call_hooks('post_local',$datarray); + + if(x($datarray,'cancel')) { + logger('mod_item: post cancelled by plugin or duplicate suppressed.'); + if($return_path) + goaway(z_root() . "/" . $return_path); + + $json = array('cancel' => 1); + $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; + echo json_encode($json); + killme(); + } + + + 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($orig_post) { + $datarray['id'] = $post_id; + + item_store_update($datarray,$execflag); + + update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + + if(! $parent) { + $r = q("select * from item where id = %d", + intval($post_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $rid = q("select * from item_id where iid = %d", + intval($post_id) + ); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); + } + } + if(! $nopush) + proc_run('php', "include/notifier.php", 'edit_post', $post_id); + + if((x($_REQUEST,'return')) && strlen($return_path)) { + logger('return: ' . $return_path); + goaway(z_root() . "/" . $return_path ); + } + killme(); + } + else + $post_id = 0; + + $post = item_store($datarray,$execflag); + + $post_id = $post['item_id']; + + if($post_id) { + logger('mod_item: saved item ' . $post_id); + + if($parent) { + + // only send comment notification if this is a wall-to-wall comment, + // otherwise it will happen during delivery + + if(($datarray['owner_xchan'] != $datarray['author_xchan']) && (intval($parent_item['item_wall']))) { + notification(array( + 'type' => NOTIFY_COMMENT, + 'from_xchan' => $datarray['author_xchan'], + 'to_xchan' => $datarray['owner_xchan'], + 'item' => $datarray, + 'link' => z_root() . '/display/' . $datarray['mid'], + 'verb' => ACTIVITY_POST, + 'otype' => 'item', + 'parent' => $parent, + 'parent_mid' => $parent_item['mid'] + )); + + } + } + else { + $parent = $post_id; + + if(($datarray['owner_xchan'] != $datarray['author_xchan']) && ($datarray['item_type'] == ITEM_TYPE_POST)) { + notification(array( + 'type' => NOTIFY_WALL, + 'from_xchan' => $datarray['author_xchan'], + 'to_xchan' => $datarray['owner_xchan'], + 'item' => $datarray, + 'link' => z_root() . '/display/' . $datarray['mid'], + 'verb' => ACTIVITY_POST, + 'otype' => 'item' + )); + } + + if($uid && $uid == $profile_uid && (is_item_normal($datarray))) { + q("update channel set channel_lastpost = '%s' where channel_id = %d", + dbesc(datetime_convert()), + intval($uid) + ); + } + } + + // photo comments turn the corresponding item visible to the profile wall + // This way we don't see every picture in your new photo album posted to your wall at once. + // They will show up as people comment on them. + + if(intval($parent_item['item_hidden'])) { + $r = q("UPDATE item SET item_hidden = 0 WHERE id = %d", + intval($parent_item['id']) + ); + } + } + else { + logger('mod_item: unable to retrieve post that was just stored.'); + notice( t('System error. Post not saved.') . EOL); + goaway(z_root() . "/" . $return_path ); + // NOTREACHED + } + + + update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + + if(($parent) && ($parent != $post_id)) { + // Store the comment signature information in case we need to relay to Diaspora + $ditem = $datarray; + $ditem['author'] = $observer; + store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); + } + else { + $r = q("select * from item where id = %d", + intval($post_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $rid = q("select * from item_id where iid = %d", + intval($post_id) + ); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); + } + } + + $datarray['id'] = $post_id; + $datarray['llink'] = z_root() . '/display/' . $channel['channel_address'] . '/' . $post_id; + + call_hooks('post_local_end', $datarray); + + if(! $nopush) + proc_run('php', 'include/notifier.php', $notify_type, $post_id); + + logger('post_complete'); + + + + + + + // figure out how to return, depending on from whence we came + + if($api_source) + return $post; + + if($return_path) { + goaway(z_root() . "/" . $return_path); + } + + $json = array('success' => 1); + if(x($_REQUEST,'jsreload') && strlen($_REQUEST['jsreload'])) + $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; + + logger('post_json: ' . print_r($json,true), LOGGER_DEBUG); + + echo json_encode($json); + killme(); + // NOTREACHED + } + + + function get() { + + if((! local_channel()) && (! remote_channel())) + return; + + require_once('include/security.php'); + + if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { + + require_once('include/items.php'); + $i = q("select id, uid, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", + intval(argv(2)) + ); + + if($i) { + $can_delete = false; + $local_delete = false; + if(local_channel() && local_channel() == $i[0]['uid']) + $local_delete = true; + + $sys = get_sys_channel(); + if(is_site_admin() && $sys['channel_id'] == $i[0]['uid']) + $can_delete = true; + + $ob_hash = get_observer_hash(); + if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) + $can_delete = true; + + if(! ($can_delete || $local_delete)) { + notice( t('Permission denied.') . EOL); + return; + } + + // if this is a different page type or it's just a local delete + // but not by the item author or owner, do a simple deletion + + if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) { + drop_item($i[0]['id']); + } + else { + // complex deletion that needs to propagate and be performed in phases + drop_item($i[0]['id'],true,DROPITEM_PHASE1); + tag_deliver($i[0]['uid'],$i[0]['id']); + } + } + } + } + + + function fix_attached_photo_permissions($uid,$xchan_hash,$body, + $str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny) { + + if(get_pconfig($uid,'system','force_public_uploads')) { + $str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = ''; + } + + $match = null; + // match img and zmg image links + if(preg_match_all("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/",$body,$match)) { + $images = $match[2]; + if($images) { + foreach($images as $image) { + if(! stristr($image,z_root() . '/photo/')) + continue; + $image_uri = substr($image,strrpos($image,'/') + 1); + if(strpos($image_uri,'-') !== false) + $image_uri = substr($image_uri,0, strpos($image_uri,'-')); + if(strpos($image_uri,'.') !== false) + $image_uri = substr($image_uri,0, strpos($image_uri,'.')); + if(! strlen($image_uri)) + continue; + $srch = '<' . $xchan_hash . '>'; + + $r = q("select folder from attach where hash = '%s' and uid = %d limit 1", + dbesc($image_uri), + intval($uid) + ); + if($r && $r[0]['folder']) { + $f = q("select * from attach where hash = '%s' and is_dir = 1 and uid = %d limit 1", + dbesc($r[0]['folder']), + intval($uid) + ); + if(($f) && (($f[0]['allow_cid']) || ($f[0]['allow_gid']) || ($f[0]['deny_cid']) || ($f[0]['deny_gid']))) { + $str_contact_allow = $f[0]['allow_cid']; + $str_group_allow = $f[0]['allow_gid']; + $str_contact_deny = $f[0]['deny_cid']; + $str_group_deny = $f[0]['deny_gid']; + } + } + + $r = q("SELECT id FROM photo + WHERE allow_cid = '%s' AND allow_gid = '' AND deny_cid = '' AND deny_gid = '' + AND resource_id = '%s' AND uid = %d LIMIT 1", + dbesc($srch), + dbesc($image_uri), + intval($uid) + ); + + if($r) { + $r = q("UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' + WHERE resource_id = '%s' AND uid = %d ", + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + dbesc($image_uri), + intval($uid) + ); + + // also update the linked item (which is probably invisible) + + $r = q("select id from item + WHERE allow_cid = '%s' AND allow_gid = '' AND deny_cid = '' AND deny_gid = '' + AND resource_id = '%s' and resource_type = 'photo' AND uid = %d LIMIT 1", + dbesc($srch), + dbesc($image_uri), + intval($uid) + ); + if($r) { + $private = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? true : false); + + $r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d + WHERE id = %d AND uid = %d", + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + intval($private), + intval($r[0]['id']), + intval($uid) + ); + } + $r = q("select id from attach where hash = '%s' and uid = %d limit 1", + dbesc($image_uri), + intval($uid) + ); + if($r) { + q("update attach SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' + WHERE id = %d AND uid = %d", + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + intval($r[0]['id']), + intval($uid) + ); + } + } + } + } + } + } + + + function fix_attached_file_permissions($channel,$observer_hash,$body, + $str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny) { + + if(get_pconfig($channel['channel_id'],'system','force_public_uploads')) { + $str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = ''; + } + + $match = false; + + if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",$body,$match)) { + $attaches = $match[1]; + if($attaches) { + foreach($attaches as $attach) { + $hash = substr($attach,0,strpos($attach,',')); + $rev = intval(substr($attach,strpos($attach,','))); + attach_store($channel,$observer_hash,$options = 'update', array( + 'hash' => $hash, + 'revision' => $rev, + 'allow_cid' => $str_contact_allow, + 'allow_gid' => $str_group_allow, + 'deny_cid' => $str_contact_deny, + 'deny_gid' => $str_group_deny + )); + } + } + } + } + + function item_check_service_class($channel_id,$iswebpage) { + $ret = array('success' => false, 'message' => ''); + + if ($iswebpage) { + $r = q("select count(i.id) as total from item i + right join channel c on (i.author_xchan=c.channel_hash and i.uid=c.channel_id ) + and i.parent=i.id and i.item_type = %d and i.item_deleted = 0 and i.uid= %d ", + intval(ITEM_TYPE_WEBPAGE), + intval($channel_id) + ); + } + else { + $r = q("select count(id) as total from item where parent = id and item_wall = 1 and uid = %d " . item_normal(), + intval($channel_id) + ); + } + + if(! $r) { + $ret['message'] = t('Unable to obtain post information from database.'); + return $ret; + } + + if (!$iswebpage) { + $max = service_class_fetch($channel_id,'total_items'); + if(! service_class_allows($channel_id,'total_items',$r[0]['total'])) { + $result['message'] .= upgrade_message() . sprintf( t('You have reached your limit of %1$.0f top level posts.'),$max); + return $result; + } + } + else { + $max = service_class_fetch($channel_id,'total_pages'); + if(! service_class_allows($channel_id,'total_pages',$r[0]['total'])) { + $result['message'] .= upgrade_message() . sprintf( t('You have reached your limit of %1$.0f webpages.'),$max); + return $result; + } + } + + $ret['success'] = true; + return $ret; + } + + +} diff --git a/Zotlabs/Module/Lang.php b/Zotlabs/Module/Lang.php new file mode 100644 index 000000000..69f10fe6d --- /dev/null +++ b/Zotlabs/Module/Lang.php @@ -0,0 +1,12 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $_SESSION['return_url'] = \App::$query_string; + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + // Block design features from visitors + + if((! $uid) || ($uid != $owner)) { + notice( t('Permission denied.') . EOL); + return; + } + + // Get the observer, check their permissions + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + //This feature is not exposed in redbasic ui since it is not clear why one would want to + //download a json encoded pdl file - we dont have a possibility to import it. + //Use the buildin share/install feature instead. + if((argc() > 3) && (argv(2) === 'share') && (argv(3))) { + $r = q("select sid, service, mimetype, title, body from item_id + left join item on item.id = item_id.iid + where item_id.uid = %d and item.mid = '%s' and service = 'PDL' order by sid asc", + intval($owner), + dbesc(argv(3)) + ); + if($r) { + header('Content-type: application/x-hubzilla-layout'); + header('Content-disposition: attachment; filename="' . $r[0]['sid'] . '.pdl"'); + echo json_encode($r); + killme(); + } + } + + // Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages + // Nickname is set to the observers xchan, and profile_uid to the owners. + // This lets you post pages at other people's channels. + + $x = array( + 'webpage' => ITEM_TYPE_PDL, + 'is_owner' => true, + 'nickname' => \App::$profile['channel_address'], + 'bang' => '', + 'showacl' => false, + 'visitor' => false, + 'nopreview' => 1, + 'ptlabel' => t('Layout Name'), + 'profile_uid' => intval($owner), + 'expanded' => true, + 'placeholdertitle' => t('Layout Description (Optional)'), + 'novoting' => true, + 'bbco_autocomplete' => 'comanche' + ); + + if($_REQUEST['title']) + $x['title'] = $_REQUEST['title']; + if($_REQUEST['body']) + $x['body'] = $_REQUEST['body']; + if($_REQUEST['pagetitle']) + $x['pagetitle'] = $_REQUEST['pagetitle']; + + $editor = status_editor($a,$x); + + $r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id + where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc", + intval($owner), + intval(ITEM_TYPE_PDL) + ); + + $pages = null; + + if($r) { + $pages = array(); + foreach($r as $rr) { + $element_arr = array( + 'type' => 'layout', + 'title' => $rr['title'], + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'pagetitle' => $rr['sid'], + 'mid' => $rr['mid'] + ); + $pages[$rr['iid']][] = array( + 'url' => $rr['iid'], + 'title' => $rr['sid'], + 'descr' => $rr['title'], + 'mid' => $rr['mid'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]' + ); + } + } + + //Build the base URL for edit links + $url = z_root() . '/editlayout/' . $which; + + $o .= replace_macros(get_markup_template('layoutlist.tpl'), array( + '$title' => t('Layouts'), + '$create' => t('Create'), + '$help' => array('text' => t('Help'), 'url' => 'help/comanche', 'title' => t('Comanche page description language help')), + '$editor' => $editor, + '$baseurl' => $url, + '$name' => t('Layout Name'), + '$descr' => t('Layout Description'), + '$created' => t('Created'), + '$edited' => t('Edited'), + '$edit' => t('Edit'), + '$share' => t('Share'), + '$download' => t('Download PDL file'), + '$pages' => $pages, + '$channel' => $which, + '$view' => t('View'), + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php new file mode 100644 index 000000000..ac8791950 --- /dev/null +++ b/Zotlabs/Module/Like.php @@ -0,0 +1,547 @@ +' . t('Like/Dislike') . ''; + $o .= EOL . EOL; + + if(! $observer) { + $_SESSION['return_url'] = \App::$query_string; + $o .= t('This action is restricted to members.') . EOL; + $o .= t('Please login with your $Projectname ID or register as a new $Projectname member to continue.') . EOL; + return $o; + } + } + + $verb = notags(trim($_GET['verb'])); + + if(! $verb) + $verb = 'like'; + + switch($verb) { + case 'like': + case 'unlike': + $activity = ACTIVITY_LIKE; + break; + case 'dislike': + case 'undislike': + $activity = ACTIVITY_DISLIKE; + break; + case 'agree': + case 'unagree': + $activity = ACTIVITY_AGREE; + break; + case 'disagree': + case 'undisagree': + $activity = ACTIVITY_DISAGREE; + break; + case 'abstain': + case 'unabstain': + $activity = ACTIVITY_ABSTAIN; + break; + case 'attendyes': + case 'unattendyes': + $activity = ACTIVITY_ATTEND; + break; + case 'attendno': + case 'unattendno': + $activity = ACTIVITY_ATTENDNO; + break; + case 'attendmaybe': + case 'unattendmaybe': + $activity = ACTIVITY_ATTENDMAYBE; + break; + default: + return; + break; + } + + $extended_like = false; + $object = $target = null; + $post_type = ''; + $objtype = ''; + + if(argc() == 3) { + + if(! $observer) + killme(); + + $extended_like = true; + $obj_type = argv(1); + $obj_id = argv(2); + $public = true; + + if($obj_type == 'profile') { + $r = q("select * from profile where profile_guid = '%s' limit 1", + dbesc(argv(2)) + ); + if(! $r) + killme(); + $owner_uid = $r[0]['uid']; + if($r[0]['is_default']) + $public = true; + if(! $public) { + $d = q("select abook_xchan from abook where abook_profile = '%s' and abook_channel = %d", + dbesc($r[0]['profile_guid']), + intval($owner_uid) + ); + if(! $d) { + // forgery - illegal + if($interactive) { + notice( t('Invalid request.') . EOL); + return $o; + } + killme(); + } + // $d now contains a list of those who can see this profile - only send the status notification + // to them. + $allow_cid = $allow_gid = $deny_cid = $deny_gid = ''; + foreach($d as $dd) { + $allow_cid .= '<' . $dd['abook_xchan'] . '>'; + } + } + $post_type = t('channel'); + $objtype = ACTIVITY_OBJ_PROFILE; + + $profile = $r[0]; + } + elseif($obj_type == 'thing') { + + $r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc(argv(2)) + ); + + if(! $r) { + if($interactive) { + notice( t('Invalid request.') . EOL); + return $o; + } + killme(); + } + + $owner_uid = $r[0]['obj_channel']; + + $allow_cid = $r[0]['allow_cid']; + $allow_gid = $r[0]['allow_gid']; + $deny_cid = $r[0]['deny_cid']; + $deny_gid = $r[0]['deny_gid']; + if($allow_cid || $allow_gid || $deny_cid || $deny_gid) + $public = false; + + $post_type = t('thing'); + $objtype = ACTIVITY_OBJ_PROFILE; + $tgttype = ACTIVITY_OBJ_THING; + + $links = array(); + $links[] = array('rel' => 'alternate', 'type' => 'text/html', + 'href' => z_root() . '/thing/' . $r[0]['obj_obj']); + if($r[0]['imgurl']) + $links[] = array('rel' => 'photo', 'href' => $r[0]['obj_imgurl']); + + $target = json_encode(array( + 'type' => $tgttype, + 'title' => $r[0]['obj_term'], + 'id' => z_root() . '/thing/' . $r[0]['obj_obj'], + 'link' => $links + )); + + $plink = '[zrl=' . z_root() . '/thing/' . $r[0]['obj_obj'] . ']' . $r[0]['obj_term'] . '[/zrl]'; + + } + + if(! ($owner_uid && $r)) { + if($interactive) { + notice( t('Invalid request.') . EOL); + return $o; + } + killme(); + } + + // The resultant activity is going to be a wall-to-wall post, so make sure this is allowed + + $perms = get_all_perms($owner_uid,$observer['xchan_hash']); + + if(! ($perms['post_like'] && $perms['view_profile'])) { + if($interactive) { + notice( t('Permission denied.') . EOL); + return $o; + } + killme(); + } + + $ch = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", + intval($owner_uid) + ); + if(! $ch) { + if($interactive) { + notice( t('Channel unavailable.') . EOL); + return $o; + } + killme(); + } + + if(! $plink) + $plink = '[zrl=' . z_root() . '/profile/' . $ch[0]['channel_address'] . ']' . $post_type . '[/zrl]'; + + $links = array(); + $links[] = array('rel' => 'alternate', 'type' => 'text/html', + 'href' => z_root() . '/profile/' . $ch[0]['channel_address']); + $links[] = array('rel' => 'photo', 'type' => $ch[0]['xchan_photo_mimetype'], + 'href' => $ch[0]['xchan_photo_l']); + + $object = json_encode(array( + 'type' => ACTIVITY_OBJ_PROFILE, + 'title' => $ch[0]['channel_name'], + 'id' => $ch[0]['xchan_url'] . '/' . $ch[0]['xchan_hash'], + 'link' => $links + )); + + + // second like of the same thing is "undo" for the first like + + $z = q("select * from likes where channel_id = %d and liker = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' limit 1", + intval($ch[0]['channel_id']), + dbesc($observer['xchan_hash']), + dbesc($activity), + dbesc(($tgttype)?$tgttype:$objtype), + dbesc($obj_id) + ); + + if($z) { + $z[0]['deleted'] = 1; + build_sync_packet($ch[0]['channel_id'],array('likes' => $z)); + + q("delete from likes where id = %d limit 1", + intval($z[0]['id']) + ); + if($z[0]['i_mid']) { + $r = q("select id from item where mid = '%s' and uid = %d limit 1", + dbesc($z[0]['i_mid']), + intval($ch[0]['channel_id']) + ); + if($r) + drop_item($r[0]['id'],false); + if($interactive) { + notice( t('Previous action reversed.') . EOL); + return $o; + } + } + killme(); + } + } + else { + + // this is used to like an item or comment + + $item_id = ((argc() == 2) ? notags(trim(argv(1))) : 0); + + logger('like: verb ' . $verb . ' item ' . $item_id, LOGGER_DEBUG); + + // get the item. Allow linked photos (which are normally hidden) to be liked + + $r = q("SELECT * FROM item WHERE id = %d + and item_type = 0 and item_deleted = 0 and item_unpublished = 0 + and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1", + intval($item_id) + ); + + if(! $item_id || (! $r)) { + logger('like: no item ' . $item_id); + killme(); + } + + + $item = $r[0]; + $owner_uid = $item['uid']; + $owner_aid = $item['aid']; + + + $sys = get_sys_channel(); + + + // if this is a "discover" item, (item['uid'] is the sys channel), + // fallback to the item comment policy, which should've been + // respected when generating the conversation thread. + // Even if the activity is rejected by the item owner, it should still get attached + // to the local discover conversation on this site. + + if(($owner_uid != $sys['channel_id']) && (! perm_is_allowed($owner_uid,$observer['xchan_hash'],'post_comments'))) { + notice( t('Permission denied') . EOL); + killme(); + } + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['owner_xchan']) + ); + if($r) + $thread_owner = $r[0]; + else + killme(); + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['author_xchan']) + ); + if($r) + $item_author = $r[0]; + else + killme(); + + + $verbs = " '".dbesc($activity)."' "; + + $multi_undo = false; + + // event participation and consensus items are essentially radio toggles. If you make a subsequent choice, + // we need to eradicate your first choice. + + if($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) { + $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' "; + $multi_undo = 1; + } + if($activity === ACTIVITY_AGREE || $activity === ACTIVITY_DISAGREE || $activity === ACTIVITY_ABSTAIN) { + $verbs = " '" . dbesc(ACTIVITY_AGREE) . "','" . dbesc(ACTIVITY_DISAGREE) . "','" . dbesc(ACTIVITY_ABSTAIN) . "' "; + $multi_undo = true; + } + + $item_normal = item_normal(); + + $r = q("SELECT id, parent, uid, verb FROM item WHERE verb in ( $verbs ) $item_normal + AND author_xchan = '%s' AND thr_parent = '%s' and uid = %d ", + dbesc($observer['xchan_hash']), + dbesc($item['mid']), + intval($owner_uid) + ); + + if($r) { + // already liked it. Drop that item. + require_once('include/items.php'); + foreach($r as $rr) { + drop_item($rr['id'],false,DROPITEM_PHASE1); + // set the changed timestamp on the parent so we'll see the update without a page reload + $z = q("update item set changed = '%s' where id = %d and uid = %d", + dbesc(datetime_convert()), + intval($rr['parent']), + intval($rr['uid']) + ); + // Prior activity was a duplicate of the one we're submitting, just undo it; + // don't fall through and create another + if(activity_match($rr['verb'],$activity)) + $multi_undo = false; + + // drop_item was not done interactively, so we need to invoke the notifier + // in order to push the changes to connections + + proc_run('php','include/notifier.php','drop',$rr['id']); + + } + + if($interactive) + return; + + if(! $multi_undo) + killme(); + } + } + + $mid = item_message_id(); + + $arr = array(); + + if($extended_like) { + $arr['item_thread_top'] = 1; + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; + } + else { + $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); + if($item['obj_type'] === ACTIVITY_OBJ_EVENT) + $post_type = t('event'); + + $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink'])); + $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); + + $body = $item['body']; + + $object = json_encode(array( + 'type' => $objtype, + 'id' => $item['mid'], + 'parent' => (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']), + 'link' => $links, + 'title' => $item['title'], + 'content' => $item['body'], + 'created' => $item['created'], + 'edited' => $item['edited'], + 'author' => array( + 'name' => $item_author['xchan_name'], + 'address' => $item_author['xchan_addr'], + 'guid' => $item_author['xchan_guid'], + 'guid_sig' => $item_author['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']), + array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])), + ), + )); + + if(! intval($item['item_thread_top'])) + $post_type = 'comment'; + + $arr['item_origin'] = 1; + $arr['item_notshown'] = 1; + + if(intval($item['item_wall'])) + $arr['item_wall'] = 1; + + // if this was a linked photo and was hidden, unhide it. + + if(intval($item['item_hidden'])) { + $r = q("update item set item_hidden = 0 where id = %d", + intval($item['id']) + ); + } + + } + + if($verb === 'like') + $bodyverb = t('%1$s likes %2$s\'s %3$s'); + if($verb === 'dislike') + $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); + if($verb === 'agree') + $bodyverb = t('%1$s agrees with %2$s\'s %3$s'); + if($verb === 'disagree') + $bodyverb = t('%1$s doesn\'t agree with %2$s\'s %3$s'); + if($verb === 'abstain') + $bodyverb = t('%1$s abstains from a decision on %2$s\'s %3$s'); + if($verb === 'attendyes') + $bodyverb = t('%1$s is attending %2$s\'s %3$s'); + if($verb === 'attendno') + $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); + if($verb === 'attendmaybe') + $bodyverb = t('%1$s may attend %2$s\'s %3$s'); + + if(! isset($bodyverb)) + killme(); + + + + if($extended_like) { + $ulink = '[zrl=' . $ch[0]['xchan_url'] . ']' . $ch[0]['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $private = (($public) ? 0 : 1); + } + else { + $arr['parent'] = $item['id']; + $arr['thr_parent'] = $item['mid']; + $ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]'; + $allow_cid = $item['allow_cid']; + $allow_gid = $item['allow_gid']; + $deny_cid = $item['deny_cid']; + $deny_gid = $item['deny_gid']; + $private = $item['private']; + + } + + + $arr['mid'] = $mid; + $arr['aid'] = (($extended_like) ? $ch[0]['channel_account_id'] : $owner_aid); + $arr['uid'] = $owner_uid; + $arr['item_flags'] = $item_flags; + $arr['item_wall'] = $item_wall; + $arr['parent_mid'] = (($extended_like) ? $mid : $item['mid']); + $arr['owner_xchan'] = (($extended_like) ? $ch[0]['xchan_hash'] : $thread_owner['xchan_hash']); + $arr['author_xchan'] = $observer['xchan_hash']; + + + $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); + if($obj_type === 'thing' && $r[0]['imgurl']) { + $arr['body'] .= "\n\n[zmg=80x80]" . $r[0]['imgurl'] . '[/zmg]'; + } + if($obj_type === 'profile') { + if($public) { + $arr['body'] .= "\n\n" . '[embed]' . z_root() . '/profile/' . $ch[0]['channel_address'] . '[/embed]'; + } + else + $arr['body'] .= "\n\n[zmg=80x80]" . $profile['thumb'] . '[/zmg]'; + } + + + $arr['verb'] = $activity; + $arr['obj_type'] = $objtype; + $arr['object'] = $object; + + if($target) { + $arr['tgt_type'] = $tgttype; + $arr['target'] = $target; + } + + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; + + + $post = item_store($arr); + $post_id = $post['item_id']; + + $arr['id'] = $post_id; + + call_hooks('post_local_end', $arr); + + + if($extended_like) { + $r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", + intval($ch[0]['channel_id']), + dbesc($observer['xchan_hash']), + dbesc($ch[0]['channel_hash']), + intval($post_id), + dbesc($mid), + dbesc($activity), + dbesc(($tgttype)? $tgttype : $objtype), + dbesc($obj_id), + dbesc(($target) ? $target : $object) + ); + $r = q("select * from likes where liker = '%s' and likee = '%s' and i_mid = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' ", + dbesc($observer['xchan_hash']), + dbesc($ch[0]['channel_hash']), + dbesc($mid), + dbesc($activity), + dbesc(($tgttype)? $tgttype : $objtype), + dbesc($obj_id) + ); + if($r) + build_sync_packet($ch[0]['channel_id'],array('likes' => $r)); + + } + + + proc_run('php',"include/notifier.php","like","$post_id"); + + if($interactive) { + notice( t('Action completed.') . EOL); + $o .= t('Thank you.'); + return $o; + } + + killme(); + } + + + +} diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php new file mode 100644 index 000000000..a1008f7c4 --- /dev/null +++ b/Zotlabs/Module/Linkinfo.php @@ -0,0 +1,381 @@ + true, 'nobody' => true)); + if($result['success']) { + $hdrs=array(); + $h = explode("\n",$result['header']); + foreach ($h as $l) { + list($k,$v) = array_map("trim", explode(":", trim($l), 2)); + $hdrs[$k] = $v; + } + if (array_key_exists('Content-Type', $hdrs)) + $type = $hdrs['Content-Type']; + if($type) { + $zrl = is_matrix_url($url); + if(stripos($type,'image/') !== false) { + if($zrl) + echo $br . '[zmg]' . $url . '[/zmg]' . $br; + else + echo $br . '[img]' . $url . '[/img]' . $br; + killme(); + } + if(stripos($type,'video/') !== false) { + if($zrl) + echo $br . '[zvideo]' . $url . '[/zvideo]' . $br; + else + echo $br . '[video]' . $url . '[/video]' . $br; + killme(); + } + if(stripos($type,'audio/') !== false) { + if($zrl) + echo $br . '[zaudio]' . $url . '[/zaudio]' . $br; + else + echo $br . '[audio]' . $url . '[/audio]' . $br; + killme(); + } + } + } + + $template = $br . '#^[url=%s]%s[/url]%s' . $br; + + $arr = array('url' => $url, 'text' => ''); + + call_hooks('parse_link', $arr); + + if(strlen($arr['text'])) { + echo $arr['text']; + killme(); + } + + $x = oembed_process($url); + if($x) { + echo $x; + killme(); + } + + if($url && $title && $text) { + + $text = $br . '[quote]' . trim($text) . '[/quote]' . $br; + + $title = str_replace(array("\r","\n"),array('',''),$title); + + $result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags; + + logger('linkinfo (unparsed): returns: ' . $result); + + echo $result; + killme(); + } + + $siteinfo = parseurl_getsiteinfo($url); + + // If this is a Red site, use zrl rather than url so they get zids sent to them by default + + if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Project\System::get_platform_name() . ' ') === 0)) + $template = str_replace('url','zrl',$template); + + if($siteinfo["title"] == "") { + echo sprintf($template,$url,$url,'') . $str_tags; + killme(); + } else { + $text = $siteinfo["text"]; + $title = $siteinfo["title"]; + } + + $image = ""; + + if(sizeof($siteinfo["images"]) > 0){ + /* Execute below code only if image is present in siteinfo */ + + $total_images = 0; + $max_images = get_config('system','max_bookmark_images'); + if($max_images === false) + $max_images = 2; + else + $max_images = intval($max_images); + + foreach ($siteinfo["images"] as $imagedata) { + if ($url) { + $image .= sprintf('[url=%s]', $url); + } + $image .= '[img='.$imagedata["width"].'x'.$imagedata["height"].']'.$imagedata["src"].'[/img]'; + if ($url) { + $image .= '[/url]'; + } + $image .= "\n"; + $total_images ++; + if($max_images && $max_images >= $total_images) + break; + } + } + + if(strlen($text)) { + $text = $br.'[quote]'.trim($text).'[/quote]'.$br ; + } + + if($image) { + $text = $br.$br.$image.$text; + } + $title = str_replace(array("\r","\n"),array('',''),$title); + + $result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags; + + logger('linkinfo: returns: ' . $result, LOGGER_DEBUG); + + echo trim($result); + killme(); + + } + + + function deletexnode(&$doc, $node) { + $xpath = new DomXPath($doc); + $list = $xpath->query("//".$node); + foreach ($list as $child) + $child->parentNode->removeChild($child); + } + + function completeurl($url, $scheme) { + $urlarr = parse_url($url); + + if (isset($urlarr["scheme"])) + return($url); + + $schemearr = parse_url($scheme); + + $complete = $schemearr["scheme"]."://".$schemearr["host"]; + + if ($schemearr["port"] != "") + $complete .= ":".$schemearr["port"]; + + if(strpos($urlarr['path'],'/') !== 0) + $complete .= '/'; + + $complete .= $urlarr["path"]; + + if ($urlarr["query"] != "") + $complete .= "?".$urlarr["query"]; + + if ($urlarr["fragment"] != "") + $complete .= "#".$urlarr["fragment"]; + + return($complete); + } + + + function parseurl_getsiteinfo($url) { + $siteinfo = array(); + + + $result = z_fetch_url($url,false,0,array('novalidate' => true)); + if(! $result['success']) + return $siteinfo; + + $header = $result['header']; + $body = $result['body']; + + $body = mb_convert_encoding($body, 'UTF-8', 'UTF-8'); + $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); + + $doc = new DOMDocument(); + @$doc->loadHTML($body); + + $this->deletexnode($doc, 'style'); + $this->deletexnode($doc, 'script'); + $this->deletexnode($doc, 'option'); + $this->deletexnode($doc, 'h1'); + $this->deletexnode($doc, 'h2'); + $this->deletexnode($doc, 'h3'); + $this->deletexnode($doc, 'h4'); + $this->deletexnode($doc, 'h5'); + $this->deletexnode($doc, 'h6'); + $this->deletexnode($doc, 'ol'); + $this->deletexnode($doc, 'ul'); + + $xpath = new DomXPath($doc); + + //$list = $xpath->query("head/title"); + $list = $xpath->query("//title"); + foreach ($list as $node) + $siteinfo["title"] = html_entity_decode($node->nodeValue, ENT_QUOTES, "UTF-8"); + + //$list = $xpath->query("head/meta[@name]"); + $list = $xpath->query("//meta[@name]"); + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) + foreach ($node->attributes as $attribute) + $attr[$attribute->name] = $attribute->value; + + $attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"); + + switch (strtolower($attr["name"])) { + case 'generator': + $siteinfo['generator'] = $attr['content']; + break; + case "fulltitle": + $siteinfo["title"] = $attr["content"]; + break; + case "description": + $siteinfo["text"] = $attr["content"]; + break; + case "dc.title": + $siteinfo["title"] = $attr["content"]; + break; + case "dc.description": + $siteinfo["text"] = $attr["content"]; + break; + } + } + + //$list = $xpath->query("head/meta[@property]"); + $list = $xpath->query("//meta[@property]"); + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) + foreach ($node->attributes as $attribute) + $attr[$attribute->name] = $attribute->value; + + $attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"); + + switch (strtolower($attr["property"])) { + case "og:image": + $siteinfo["image"] = $attr["content"]; + break; + case "og:title": + $siteinfo["title"] = $attr["content"]; + break; + case "og:description": + $siteinfo["text"] = $attr["content"]; + break; + } + } + + if ($siteinfo["image"] == "") { + $list = $xpath->query("//img[@src]"); + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) + foreach ($node->attributes as $attribute) + $attr[$attribute->name] = $attribute->value; + + $src = $this->completeurl($attr["src"], $url); + $photodata = @getimagesize($src); + + if (($photodata) && ($photodata[0] > 150) and ($photodata[1] > 150)) { + if ($photodata[0] > 300) { + $photodata[1] = round($photodata[1] * (300 / $photodata[0])); + $photodata[0] = 300; + } + if ($photodata[1] > 300) { + $photodata[0] = round($photodata[0] * (300 / $photodata[1])); + $photodata[1] = 300; + } + $siteinfo["images"][] = array("src"=>$src, + "width"=>$photodata[0], + "height"=>$photodata[1]); + } + + } + } else { + $src = $this->completeurl($siteinfo["image"], $url); + + unset($siteinfo["image"]); + + $photodata = @getimagesize($src); + + if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10)) + $siteinfo["images"][] = array("src"=>$src, + "width"=>$photodata[0], + "height"=>$photodata[1]); + } + + if ($siteinfo["text"] == "") { + $text = ""; + + $list = $xpath->query("//div[@class='article']"); + foreach ($list as $node) + if (strlen($node->nodeValue) > 40) + $text .= " ".trim($node->nodeValue); + + if ($text == "") { + $list = $xpath->query("//div[@class='content']"); + foreach ($list as $node) + if (strlen($node->nodeValue) > 40) + $text .= " ".trim($node->nodeValue); + } + + // If none text was found then take the paragraph content + if ($text == "") { + $list = $xpath->query("//p"); + foreach ($list as $node) + if (strlen($node->nodeValue) > 40) + $text .= " ".trim($node->nodeValue); + } + + if ($text != "") { + $text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text)); + + while (strpos($text, " ")) + $text = trim(str_replace(" ", " ", $text)); + + $siteinfo["text"] = html_entity_decode(substr($text,0,350), ENT_QUOTES, "UTF-8").'...'; + } + } + + return($siteinfo); + } + + + private static function arr_add_hashes(&$item,$k) { + $item = '#' . $item; + } + + + + +} diff --git a/Zotlabs/Module/Locs.php b/Zotlabs/Module/Locs.php new file mode 100644 index 000000000..4b5d58df5 --- /dev/null +++ b/Zotlabs/Module/Locs.php @@ -0,0 +1,132 @@ + t('Manage Channel Locations'), + '$loc' => t('Location'), + '$addr' => t('Address'), + '$mkprm' => t('Primary'), + '$drop' => t('Drop'), + '$submit' => t('Submit'), + '$sync' => t('Sync Now'), + '$sync_text' => t('Please wait several minutes between consecutive operations.'), + '$drop_text' => t('When possible, drop a location by logging into that website/hub and removing your channel.'), + '$last_resort' => t('Use this form to drop the location if the hub is no longer operating.'), + '$hubs' => $r + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Login.php b/Zotlabs/Module/Login.php new file mode 100644 index 000000000..ff75e5268 --- /dev/null +++ b/Zotlabs/Module/Login.php @@ -0,0 +1,13 @@ + get_config('system','sitename'), + '$siteurl' => z_root(), + '$username' => sprintf( t('Site Member (%s)'), $email), + '$email' => $email, + '$reset_link' => z_root() . '/lostpass?verify=' . $hash + )); + + $subject = email_header_encode(sprintf( t('Password reset requested at %s'),get_config('system','sitename')), 'UTF-8'); + + $res = mail($email, $subject , + $message, + 'From: Administrator@' . $_SERVER['SERVER_NAME'] . "\n" + . 'Content-type: text/plain; charset=UTF-8' . "\n" + . 'Content-transfer-encoding: 8bit' ); + + + goaway(z_root()); + } + + + function get() { + + + if(x($_GET,'verify')) { + $verify = $_GET['verify']; + + $r = q("SELECT * FROM account WHERE account_reset = '%s' LIMIT 1", + dbesc($verify) + ); + if(! $r) { + notice( t("Request could not be verified. (You may have previously submitted it.) Password reset failed.") . EOL); + goaway(z_root()); + return; + } + + $aid = $r[0]['account_id']; + $email = $r[0]['account_email']; + + $new_password = autoname(6) . mt_rand(100,9999); + + $salt = random_string(32); + $password_encoded = hash('whirlpool', $salt . $new_password); + + $r = q("UPDATE account SET account_salt = '%s', account_password = '%s', account_reset = '', account_flags = (account_flags & ~%d) where account_id = %d", + dbesc($salt), + dbesc($password_encoded), + intval(ACCOUNT_UNVERIFIED), + intval($aid) + ); + + if($r) { + $tpl = get_markup_template('pwdreset.tpl'); + $o .= replace_macros($tpl,array( + '$lbl1' => t('Password Reset'), + '$lbl2' => t('Your password has been reset as requested.'), + '$lbl3' => t('Your new password is'), + '$lbl4' => t('Save or copy your new password - and then'), + '$lbl5' => '' . t('click here to login') . '.', + '$lbl6' => t('Your password may be changed from the Settings page after successful login.'), + '$newpass' => $new_password, + '$baseurl' => z_root() + + )); + + info("Your password has been reset." . EOL); + + $email_tpl = get_intltext_template("passchanged_eml.tpl"); + $message = replace_macros($email_tpl, array( + '$sitename' => \App::$config['sitename'], + '$siteurl' => z_root(), + '$username' => sprintf( t('Site Member (%s)'), $email), + '$email' => $email, + '$new_password' => $new_password, + '$uid' => $newuid )); + + $subject = email_header_encode( sprintf( t('Your password has changed at %s'), get_config('system','sitename')), 'UTF-8'); + + $res = mail($email,$subject,$message, + 'From: ' . 'Administrator@' . $_SERVER['SERVER_NAME'] . "\n" + . 'Content-type: text/plain; charset=UTF-8' . "\n" + . 'Content-transfer-encoding: 8bit' ); + + return $o; + } + + } + else { + $tpl = get_markup_template('lostpass.tpl'); + + $o .= replace_macros($tpl,array( + '$title' => t('Forgot your Password?'), + '$desc' => t('Enter your email address and submit to have your password reset. Then check your email for further instructions.'), + '$name' => t('Email Address'), + '$submit' => t('Reset') + )); + + return $o; + } + + } + +} diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php new file mode 100644 index 000000000..63db4a317 --- /dev/null +++ b/Zotlabs/Module/Magic.php @@ -0,0 +1,173 @@ + false, 'url' => '', 'message' => ''); + logger('mod_magic: invoked', LOGGER_DEBUG); + + logger('mod_magic: args: ' . print_r($_REQUEST,true),LOGGER_DATA); + + $addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : ''); + $dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : ''); + $test = ((x($_REQUEST,'test')) ? intval($_REQUEST['test']) : 0); + $rev = ((x($_REQUEST,'rev')) ? intval($_REQUEST['rev']) : 0); + $delegate = ((x($_REQUEST,'delegate')) ? $_REQUEST['delegate'] : ''); + + $parsed = parse_url($dest); + if(! $parsed) { + if($test) { + $ret['message'] .= 'could not parse ' . $dest . EOL; + return($ret); + } + goaway($dest); + } + + $basepath = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : ''); + + $x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1", + dbesc($basepath) + ); + + if(! $x) { + + /* + * We have no records for, or prior communications with this hub. + * If an address was supplied, let's finger them to create a hub record. + * Otherwise we'll use the special address '[system]' which will return + * either a system channel or the first available normal channel. We don't + * really care about what channel is returned - we need the hub information + * from that response so that we can create signed auth packets destined + * for that hub. + * + */ + + $ret = zot_finger((($addr) ? $addr : '[system]@' . $parsed['host']),null); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) + import_xchan($j); + + // Now try again + + $x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1", + dbesc($basepath) + ); + } + } + + if(! $x) { + if($rev) + goaway($dest); + else { + logger('mod_magic: no channels found for requested hub.' . print_r($_REQUEST,true)); + if($test) { + $ret['message'] .= 'This site has no previous connections with ' . $basepath . EOL; + return $ret; + } + notice( t('Hub not found.') . EOL); + return; + } + } + + // This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating. + // By default, we'll proceed without asking. + + $arr = array( + 'channel_id' => local_channel(), + 'xchan' => $x[0], + 'destination' => $dest, + 'proceed' => true + ); + + call_hooks('magic_auth',$arr); + $dest = $arr['destination']; + if(! $arr['proceed']) { + if($test) { + $ret['message'] .= 'cancelled by plugin.' . EOL; + return $ret; + } + goaway($dest); + } + + if((get_observer_hash()) && ($x[0]['hubloc_url'] === z_root())) { + // We are already authenticated on this site and a registered observer. + // Just redirect. + if($test) { + $ret['success'] = true; + $ret['message'] .= 'Local site - you are already authenticated.' . EOL; + return $ret; + } + + $delegation_success = false; + if($delegate) { + $r = q("select * from channel left join hubloc on channel_hash = hubloc_hash where hubloc_addr = '%s' limit 1", + dbesc($delegate) + ); + + if($r && intval($r[0]['channel_id'])) { + $allowed = perm_is_allowed($r[0]['channel_id'],get_observer_hash(),'delegate'); + if($allowed) { + $_SESSION['delegate_channel'] = $r[0]['channel_id']; + $_SESSION['delegate'] = get_observer_hash(); + $_SESSION['account_id'] = intval($r[0]['channel_account_id']); + change_channel($r[0]['channel_id']); + + $delegation_success = true; + } + } + } + + + + // FIXME: check and honour local delegation + + + goaway($dest); + } + + if(local_channel()) { + $channel = \App::get_channel(); + + $token = random_string(); + $token_sig = base64url_encode(rsa_sign($token,$channel['channel_prvkey'])); + + $channel['token'] = $token; + $channel['token_sig'] = $token_sig; + + \Zotlabs\Zot\Verify::create('auth',$channel['channel_id'],$token,$x[0]['hubloc_url']); + + $target_url = $x[0]['hubloc_callback'] . '/?f=&auth=' . urlencode($channel['channel_address'] . '@' . \App::get_hostname()) + . '&sec=' . $token . '&dest=' . urlencode($dest) . '&version=' . ZOT_REVISION; + + if($delegate) + $target_url .= '&delegate=' . urlencode($delegate); + + logger('mod_magic: redirecting to: ' . $target_url, LOGGER_DEBUG); + + if($test) { + $ret['success'] = true; + $ret['url'] = $target_url; + $ret['message'] = 'token ' . $token . ' created for channel ' . $channel['channel_id'] . ' for url ' . $x[0]['hubloc_url'] . EOL; + return $ret; + } + + goaway($target_url); + + } + + if($test) { + $ret['message'] = 'Not authenticated or invalid arguments to mod_magic' . EOL; + return $ret; + } + + goaway($dest); + + } + +} diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php new file mode 100644 index 000000000..35cb3b9bf --- /dev/null +++ b/Zotlabs/Module/Mail.php @@ -0,0 +1,397 @@ + $v) { + if($v) { + $their_perms = $their_perms | intval($global_perms[$k][1]); + } + } + + if(! ($their_perms & PERMS_W_MAIL)) { + notice( t('Selected channel has private message restrictions. Send failed.')); + // reported issue: let's still save the message and continue. We'll just tell them + // that nothing useful is likely to happen. They might have spent hours on it. + // return; + + } + } + + // if(feature_enabled(local_channel(),'richtext')) { + // $body = fix_mce_lf($body); + // } + + require_once('include/text.php'); + linkify_tags($a, $body, local_channel()); + + if($preview) { + + + + + } + + if(! $recipient) { + notice('No recipient found.'); + \App::$argc = 2; + \App::$argv[1] = 'new'; + return; + } + + // We have a local_channel, let send_message use the session channel and save a lookup + + $ret = send_message(0, $recipient, $body, $subject, $replyto, $expires); + + if($ret['success']) { + xchan_mail_query($ret['mail']); + build_sync_packet(0,array('conv' => array($ret['conv']),'mail' => array(encode_mail($ret['mail'],true)))); + } + else { + notice($ret['message']); + } + + goaway(z_root() . '/mail/combined'); + + } + + function get() { + + $o = ''; + nav_set_selected('messages'); + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return login(); + } + + $channel = \App::get_channel(); + + head_set_icon($channel['xchan_photo_s']); + + $cipher = get_pconfig(local_channel(),'system','default_cipher'); + if(! $cipher) + $cipher = 'aes256'; + + $tpl = get_markup_template('mail_head.tpl'); + $header = replace_macros($tpl, array( + '$header' => t('Messages'), + )); + + if((argc() == 4) && (argv(2) === 'drop')) { + if(! intval(argv(3))) + return; + $cmd = argv(2); + $mailbox = argv(1); + $r = private_messages_drop(local_channel(), argv(3)); + if($r) { + //info( t('Message deleted.') . EOL ); + } + goaway(z_root() . '/mail/' . $mailbox); + } + + if((argc() == 4) && (argv(2) === 'recall')) { + if(! intval(argv(3))) + return; + $cmd = argv(2); + $mailbox = argv(1); + $r = q("update mail set mail_recalled = 1 where id = %d and channel_id = %d", + intval(argv(3)), + intval(local_channel()) + ); + $x = q("select * from mail where id = %d and channel_id = %d", + intval(argv(3)), + intval(local_channel()) + ); + if($x) { + build_sync_packet(local_channel(),array('mail' => encode_mail($x[0],true))); + } + + proc_run('php','include/notifier.php','mail',intval(argv(3))); + + if($r) { + info( t('Message recalled.') . EOL ); + } + goaway(z_root() . '/mail/' . $mailbox . '/' . argv(3)); + + } + + if((argc() == 4) && (argv(2) === 'dropconv')) { + if(! intval(argv(3))) + return; + $cmd = argv(2); + $mailbox = argv(1); + $r = private_messages_drop(local_channel(), argv(3), true); + if($r) + info( t('Conversation removed.') . EOL ); + goaway(z_root() . '/mail/' . $mailbox); + } + + if((argc() > 1) && (argv(1) === 'new')) { + + $plaintext = true; + + $tpl = get_markup_template('msg-header.tpl'); + + $header = replace_macros($tpl, array( + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$nickname' => $channel['channel_address'], + '$linkurl' => t('Please enter a link URL:'), + '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') + )); + + \App::$page['htmlhead'] .= $header; + + $prename = ''; + $preid = ''; + + if(x($_REQUEST,'hash')) { + + $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash + where abook_channel = %d and abook_xchan = '%s' limit 1", + intval(local_channel()), + dbesc($_REQUEST['hash']) + ); + + if(!$r) { + $r = q("select * from xchan where xchan_hash = '%s' and xchan_network = 'zot' limit 1", + dbesc($_REQUEST['hash']) + ); + } + + if($r) { + $prename = (($r[0]['abook_id']) ? $r[0]['xchan_name'] : $r[0]['xchan_addr']); + $preurl = $r[0]['xchan_url']; + $preid = (($r[0]['abook_id']) ? ($r[0]['xchan_hash']) : ''); + } + else { + notice( t('Requested channel is not in this network') . EOL ); + } + + } + + $tpl = get_markup_template('prv_message.tpl'); + $o .= replace_macros($tpl,array( + '$new' => true, + '$header' => t('Send Private Message'), + '$to' => t('To:'), + '$prefill' => $prename, + '$preid' => $preid, + '$subject' => t('Subject:'), + '$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''), + '$text' => ((x($_REQUEST,'body')) ? htmlspecialchars($_REQUEST['body'], ENT_COMPAT, 'UTF-8') : ''), + '$yourmessage' => t('Your message:'), + '$parent' => '', + '$attach' => t('Attach file'), + '$insert' => t('Insert web link'), + '$submit' => t('Send'), + '$defexpire' => '', + '$feature_expire' => ((feature_enabled(local_channel(),'content_expire')) ? true : false), + '$expires' => t('Set expiration date'), + '$feature_encrypt' => ((feature_enabled(local_channel(),'content_encrypt')) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + )); + + return $o; + } + + switch(argv(1)) { + case 'combined': + $mailbox = 'combined'; + break; + case 'inbox': + $mailbox = 'inbox'; + break; + case 'outbox': + $mailbox = 'outbox'; + break; + default: + $mailbox = 'combined'; + break; + } + + $last_message = private_messages_list(local_channel(), $mailbox, 0, 1); + + $mid = ((argc() > 2) && (intval(argv(2)))) ? argv(2) : $last_message[0]['id']; + + $plaintext = true; + + // if( local_channel() && feature_enabled(local_channel(),'richtext') ) + // $plaintext = false; + + + + if($mailbox == 'combined') { + $messages = private_messages_fetch_conversation(local_channel(), $mid, true); + } + else { + $messages = private_messages_fetch_message(local_channel(), $mid, true); + } + + if(! $messages) { + //info( t('Message not found.') . EOL); + return; + } + + if($messages[0]['to_xchan'] === $channel['channel_hash']) + \App::$poi = $messages[0]['from']; + else + \App::$poi = $messages[0]['to']; + + // require_once('include/Contact.php'); + + // \App::set_widget('mail_conversant',vcard_from_xchan(\App::$poi,$get_observer_hash,'mail')); + + + $tpl = get_markup_template('msg-header.tpl'); + + \App::$page['htmlhead'] .= replace_macros($tpl, array( + '$nickname' => $channel['channel_address'], + '$baseurl' => z_root(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$linkurl' => t('Please enter a link URL:'), + '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') + )); + + $mails = array(); + + $seen = 0; + $unknown = false; + + foreach($messages as $message) { + + $s = theme_attachments($message); + + $mails[] = array( + 'mailbox' => $mailbox, + 'id' => $message['id'], + 'mid' => $message['mid'], + 'from_name' => $message['from']['xchan_name'], + 'from_url' => chanlink_hash($message['from_xchan']), + 'from_photo' => $message['from']['xchan_photo_s'], + 'to_name' => $message['to']['xchan_name'], + 'to_url' => chanlink_hash($message['to_xchan']), + 'to_photo' => $message['to']['xchan_photo_s'], + 'subject' => $message['title'], + 'body' => smilies(bbcode($message['body'])), + 'attachments' => $s, + 'delete' => t('Delete message'), + 'dreport' => t('Delivery report'), + 'recall' => t('Recall message'), + 'can_recall' => (($channel['channel_hash'] == $message['from_xchan']) ? true : false), + 'is_recalled' => (intval($message['mail_recalled']) ? t('Message has been recalled.') : ''), + 'date' => datetime_convert('UTC',date_default_timezone_get(),$message['created'], 'c'), + ); + + $seen = $message['seen']; + + } + + $recp = (($message['from_xchan'] === $channel['channel_hash']) ? 'to' : 'from'); + + $tpl = get_markup_template('mail_display.tpl'); + $o = replace_macros($tpl, array( + '$mailbox' => $mailbox, + '$prvmsg_header' => $message['title'], + '$thread_id' => $mid, + '$thread_subject' => $message['title'], + '$thread_seen' => $seen, + '$delete' => t('Delete Conversation'), + '$canreply' => (($unknown) ? false : '1'), + '$unknown_text' => t("No secure communications available. You may be able to respond from the sender's profile page."), + '$mails' => $mails, + + // reply + '$header' => t('Send Reply'), + '$to' => t('To:'), + '$reply' => true, + '$subject' => t('Subject:'), + '$subjtxt' => $message['title'], + '$yourmessage' => sprintf(t('Your message for %s (%s):'), $message[$recp]['xchan_name'], $message[$recp]['xchan_addr']), + '$text' => '', + '$parent' => $message['parent_mid'], + '$recphash' => $message[$recp]['xchan_hash'], + '$attach' => t('Attach file'), + '$insert' => t('Insert web link'), + '$submit' => t('Submit'), + '$defexpire' => '', + '$feature_expire' => ((feature_enabled(local_channel(),'content_expire')) ? true : false), + '$expires' => t('Set expiration date'), + '$feature_encrypt' => ((feature_enabled(local_channel(),'content_encrypt')) ? true : false), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Manage.php b/Zotlabs/Module/Manage.php new file mode 100644 index 000000000..fee202263 --- /dev/null +++ b/Zotlabs/Module/Manage.php @@ -0,0 +1,181 @@ + 1) ? intval(argv(1)) : 0); + + if((argc() > 2) && (argv(2) === 'default')) { + $r = q("select channel_id from channel where channel_id = %d and channel_account_id = %d limit 1", + intval($change_channel), + intval(get_account_id()) + ); + if($r) { + q("update account set account_default_channel = %d where account_id = %d", + intval($change_channel), + intval(get_account_id()) + ); + } + goaway(z_root() . '/manage'); + } + + if($change_channel) { + $r = change_channel($change_channel); + + if((argc() > 2) && !(argv(2) === 'default')) { + goaway(z_root() . '/' . implode('/',array_slice(\App::$argv,2))); // Go to whatever is after /manage/, but with the new channel + } + else { + if($r && $r['channel_startpage']) + goaway(z_root() . '/' . $r['channel_startpage']); // If nothing extra is specified, go to the default page + } + goaway(z_root()); + } + + $channels = null; + + if(local_channel()) { + $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", + intval(get_account_id()) + ); + + $account = \App::get_account(); + + if($r && count($r)) { + $channels = $r; + for($x = 0; $x < count($channels); $x ++) { + $channels[$x]['link'] = 'manage/' . intval($channels[$x]['channel_id']); + $channels[$x]['default'] = (($channels[$x]['channel_id'] == $account['account_default_channel']) ? "1" : ''); + $channels[$x]['default_links'] = '1'; + + + $c = q("SELECT id, item_wall FROM item + WHERE item_unseen = 1 and uid = %d " . item_normal(), + intval($channels[$x]['channel_id']) + ); + + if($c) { + foreach ($c as $it) { + if(intval($it['item_wall'])) + $channels[$x]['home'] ++; + else + $channels[$x]['network'] ++; + } + } + + + $intr = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", + intval($channels[$x]['channel_id']) + ); + + if($intr) + $channels[$x]['intros'] = intval($intr[0]['total']); + + + $mails = q("SELECT count(id) as total from mail WHERE channel_id = %d AND mail_seen = 0 and from_xchan != '%s' ", + intval($channels[$x]['channel_id']), + dbesc($channels[$x]['channel_hash']) + ); + + if($mails) + $channels[$x]['mail'] = intval($mails[0]['total']); + + + $events = q("SELECT type, start, adjust FROM `event` + WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 + ORDER BY `start` ASC ", + intval($channels[$x]['channel_id']), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + 7 days')), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) + ); + + if($events) { + $channels[$x]['all_events'] = count($events); + + if($channels[$x]['all_events']) { + $str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d'); + foreach($events as $e) { + $bd = false; + if($e['type'] === 'birthday') { + $channels[$x]['birthdays'] ++; + $bd = true; + } + else { + $channels[$x]['events'] ++; + } + if(datetime_convert('UTC', ((intval($e['adjust'])) ? date_default_timezone_get() : 'UTC'), $e['start'], 'Y-m-d') === $str_now) { + $channels[$x]['all_events_today'] ++; + if($bd) + $channels[$x]['birthdays_today'] ++; + else + $channels[$x]['events_today'] ++; + } + } + } + } + } + } + + $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0", + intval(get_account_id()) + ); + $limit = account_service_class_fetch(get_account_id(),'total_identities'); + if($limit !== false) { + $channel_usage_message = sprintf( t("You have created %1$.0f of %2$.0f allowed channels."), $r[0]['total'], $limit); + } + else { + $channel_usage_message = ''; + } + } + + $create = array( 'new_channel', t('Create a new channel'), t('Create New')); + + $delegates = q("select * from abook left join xchan on abook_xchan = xchan_hash where + abook_channel = %d and (abook_their_perms & %d) > 0", + intval(local_channel()), + intval(PERMS_A_DELEGATE) + ); + + if($delegates) { + for($x = 0; $x < count($delegates); $x ++) { + $delegates[$x]['link'] = 'magic?f=&dest=' . urlencode($delegates[$x]['xchan_url']) + . '&delegate=' . urlencode($delegates[$x]['xchan_addr']); + $delegates[$x]['channel_name'] = $delegates[$x]['xchan_name']; + $delegates[$x]['delegate'] = 1; + } + } + else { + $delegates = null; + } + + $o = replace_macros(get_markup_template('channels.tpl'), array( + '$header' => t('Channel Manager'), + '$msg_selected' => t('Current Channel'), + '$selected' => local_channel(), + '$desc' => t('Switch to one of your channels by selecting it.'), + '$msg_default' => t('Default Channel'), + '$msg_make_default' => t('Make Default'), + '$create' => $create, + '$all_channels' => $channels, + '$mail_format' => t('%d new messages'), + '$intros_format' => t('%d new introductions'), + '$channel_usage_message' => $channel_usage_message, + '$delegated_desc' => t('Delegated Channel'), + '$delegates' => $delegates + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Match.php b/Zotlabs/Module/Match.php new file mode 100644 index 000000000..c422e4b3e --- /dev/null +++ b/Zotlabs/Module/Match.php @@ -0,0 +1,84 @@ +' . t('Profile Match') . ''; + + $r = q("SELECT `keywords` FROM `profile` WHERE `is_default` = 1 AND `uid` = %d LIMIT 1", + intval(local_channel()) + ); + if (! count($r)) + return; + + if (! $r[0]['keywords']) { + notice( t('No keywords to match. Please add keywords to your default profile.') . EOL); + return; + } + + $params = array(); + $tags = trim($r[0]['keywords']); + + if ($tags) { + $params['s'] = $tags; + if (\App::$pager['page'] != 1) + $params['p'] = \App::$pager['page']; + + // if(strlen(get_config('system','directory_submit_url'))) + // $x = post_url('http://dir.friendica.com/msearch', $params); + // else + // $x = post_url(z_root() . '/msearch', $params); + + $j = json_decode($x); + + if ($j->total) { + \App::set_pager_total($j->total); + \App::set_pager_itemspage($j->items_page); + } + + if (count($j->results)) { + $tpl = get_markup_template('match.tpl'); + foreach ($j->results as $jj) { + $connlnk = z_root() . '/follow/?url=' . $jj->url; + $o .= replace_macros($tpl,array( + '$url' => zid($jj->url), + '$name' => $jj->name, + '$photo' => $jj->photo, + '$inttxt' => ' ' . t('is interested in:'), + '$conntxt' => t('Connect'), + '$connlnk' => $connlnk, + '$tags' => $jj->tags + )); + } + } else { + info( t('No matches') . EOL); + } + } + + $o .= cleardiv(); + $o .= paginate($a); + + return $o; + } + +} diff --git a/Zotlabs/Module/Menu.php b/Zotlabs/Module/Menu.php new file mode 100644 index 000000000..9ada63911 --- /dev/null +++ b/Zotlabs/Module/Menu.php @@ -0,0 +1,173 @@ + 1) ? intval(argv(1)) : 0); + if($menu_id) { + $_REQUEST['menu_id'] = intval(argv(1)); + $r = menu_edit($_REQUEST); + if($r) { + menu_sync_packet($uid,get_observer_hash(),$menu_id); + //info( t('Menu updated.') . EOL); + goaway(z_root() . '/mitem/' . $menu_id . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + else + notice( t('Unable to update menu.'). EOL); + } + else { + $r = menu_create($_REQUEST); + if($r) { + menu_sync_packet($uid,get_observer_hash(),$r); + + //info( t('Menu created.') . EOL); + goaway(z_root() . '/mitem/' . $r . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + else + notice( t('Unable to create menu.'). EOL); + + } + } + + + + + function get() { + + $uid = local_channel(); + + if (\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + $uid = intval($sys['channel_id']); + } + + if(! $uid) { + notice( t('Permission denied.') . EOL); + return ''; + } + + if(argc() == 1) { + + + + // list menus + $x = menu_list($uid); + if($x) { + for($y = 0; $y < count($x); $y ++) { + $m = menu_fetch($x[$y]['menu_name'],$uid,get_observer_hash()); + if($m) + $x[$y]['element'] = '[element]' . base64url_encode(json_encode(menu_element($m))) . '[/element]'; + $x[$y]['bookmark'] = (($x[$y]['menu_flags'] & MENU_BOOKMARK) ? true : false); + } + } + + $create = replace_macros(get_markup_template('menuedit.tpl'), array( + '$menu_name' => array('menu_name', t('Menu Name'), '', t('Unique name (not visible on webpage) - required'), '*'), + '$menu_desc' => array('menu_desc', t('Menu Title'), '', t('Visible on webpage - leave empty for no title'), ''), + '$menu_bookmark' => array('menu_bookmark', t('Allow Bookmarks'), 0 , t('Menu may be used to store saved bookmarks'), array(t('No'), t('Yes'))), + '$submit' => t('Submit and proceed'), + '$sys' => \App::$is_sys, + '$display' => 'none' + )); + + $o = replace_macros(get_markup_template('menulist.tpl'),array( + '$title' => t('Menus'), + '$create' => $create, + '$menus' => $x, + '$nametitle' => t('Menu Name'), + '$desctitle' => t('Menu Title'), + '$edit' => t('Edit'), + '$drop' => t('Drop'), + '$created' => t('Created'), + '$edited' => t('Edited'), + '$new' => t('New'), + '$bmark' => t('Bookmarks allowed'), + '$hintnew' => t('Create'), + '$hintdrop' => t('Delete this menu'), + '$hintcontent' => t('Edit menu contents'), + '$hintedit' => t('Edit this menu'), + '$sys' => \App::$is_sys + )); + + return $o; + + } + + if(argc() > 1) { + if(intval(argv(1))) { + + if(argc() == 3 && argv(2) == 'drop') { + menu_sync_packet($uid,get_observer_hash(),intval(argv(1)),true); + $r = menu_delete_id(intval(argv(1)),$uid); + if(!$r) + notice( t('Menu could not be deleted.'). EOL); + + goaway(z_root() . '/menu' . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + + $m = menu_fetch_id(intval(argv(1)),$uid); + + if(! $m) { + notice( t('Menu not found.') . EOL); + return ''; + } + + $o = replace_macros(get_markup_template('menuedit.tpl'), array( + '$header' => t('Edit Menu'), + '$sys' => \App::$is_sys, + '$menu_id' => intval(argv(1)), + '$menu_edit_link' => 'mitem/' . intval(argv(1)) . ((\App::$is_sys) ? '?f=&sys=1' : ''), + '$hintedit' => t('Add or remove entries to this menu'), + '$editcontents' => t('Edit menu contents'), + '$menu_name' => array('menu_name', t('Menu name'), $m['menu_name'], t('Must be unique, only seen by you'), '*'), + '$menu_desc' => array('menu_desc', t('Menu title'), $m['menu_desc'], t('Menu title as seen by others'), ''), + '$menu_bookmark' => array('menu_bookmark', t('Allow bookmarks'), (($m['menu_flags'] & MENU_BOOKMARK) ? 1 : 0), t('Menu may be used to store saved bookmarks'), array(t('No'), t('Yes'))), + '$menu_system' => (($m['menu_flags'] & MENU_SYSTEM) ? 1 : 0), + '$submit' => t('Submit and proceed') + )); + + return $o; + + } + else { + notice( t('Not found.') . EOL); + return; + } + } + + } + +} diff --git a/Zotlabs/Module/Message.php b/Zotlabs/Module/Message.php new file mode 100644 index 000000000..58a138899 --- /dev/null +++ b/Zotlabs/Module/Message.php @@ -0,0 +1,110 @@ + $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'] : '' . $rr['title'] . ''), + 'delete' => t('Delete conversation'), + 'body' => smilies(bbcode($rr['body'])), + 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')), + 'seen' => $rr['seen'] + ); + } + + + $tpl = get_markup_template('mail_head.tpl'); + $o = replace_macros($tpl, array( + '$header' => $header, + '$messages' => $messages + )); + + + $o .= alt_pager($a,count($r)); + + return $o; + + return; + + } + */ + + return; + } + +} diff --git a/Zotlabs/Module/Mitem.php b/Zotlabs/Module/Mitem.php new file mode 100644 index 000000000..b64b50c8e --- /dev/null +++ b/Zotlabs/Module/Mitem.php @@ -0,0 +1,245 @@ + 2) ? intval(argv(2)) : 0); + if($mitem_id) { + $_REQUEST['mitem_id'] = $mitem_id; + $r = menu_edit_item($_REQUEST['menu_id'],$uid,$_REQUEST); + if($r) { + menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']); + //info( t('Menu element updated.') . EOL); + goaway(z_root() . '/mitem/' . $_REQUEST['menu_id'] . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + else + notice( t('Unable to update menu element.') . EOL); + + } + else { + $r = menu_add_item($_REQUEST['menu_id'],$uid,$_REQUEST); + if($r) { + menu_sync_packet($uid,get_observer_hash(),$_REQUEST['menu_id']); + //info( t('Menu element added.') . EOL); + if($_REQUEST['submit']) { + goaway(z_root() . '/menu' . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + if($_REQUEST['submit-more']) { + goaway(z_root() . '/mitem/' . $_REQUEST['menu_id'] . '?f=&display=block' . ((\App::$is_sys) ? '&sys=1' : '') ); + } + } + else + notice( t('Unable to add menu element.') . EOL); + + } + + } + + + function get() { + + $uid = local_channel(); + $channel = \App::get_channel(); + $observer = \App::get_observer(); + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + $uid = intval($sys['channel_id']); + $channel = $sys; + $ob_hash = $sys['xchan_hash']; + } + + if(! $uid) { + notice( t('Permission denied.') . EOL); + return ''; + } + + if(argc() < 2 || (! \App::$data['menu'])) { + notice( t('Not found.') . EOL); + return ''; + } + + $m = menu_fetch(\App::$data['menu']['menu_name'],$uid,$ob_hash); + \App::$data['menu_item'] = $m; + + $menu_list = menu_list($uid); + + foreach($menu_list as $menus) { + if($menus['menu_name'] != $m['menu']['menu_name']) + $menu_names[] = $menus['menu_name']; + } + + $acl = new \Zotlabs\Access\AccessList($channel); + + $lockstate = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'); + + if(argc() == 2) { + $r = q("select * from menu_item where mitem_menu_id = %d and mitem_channel_id = %d order by mitem_order asc, mitem_desc asc", + intval(\App::$data['menu']['menu_id']), + intval($uid) + ); + + if($_GET['display']) { + $display = $_GET['display']; + } + else { + $display = (($r) ? 'none' : 'block'); + } + + $create = replace_macros(get_markup_template('mitemedit.tpl'), array( + '$menu_id' => \App::$data['menu']['menu_id'], + '$permissions' => t('Menu Item Permissions'), + '$permdesc' => t("\x28click to open/close\x29"), + '$aclselect' => populate_acl($acl->get(),false), + '$mitem_desc' => array('mitem_desc', t('Link Name'), '', 'Visible name of the link','*'), + '$mitem_link' => array('mitem_link', t('Link or Submenu Target'), '', t('Enter URL of the link or select a menu name to create a submenu'), '*', 'list="menu-names"'), + '$usezid' => array('usezid', t('Use magic-auth if available'), true, '', array(t('No'), t('Yes'))), + '$newwin' => array('newwin', t('Open link in new window'), false,'', array(t('No'), t('Yes'))), + '$mitem_order' => array('mitem_order', t('Order in list'),'0',t('Higher numbers will sink to bottom of listing')), + '$submit' => t('Submit and finish'), + '$submit_more' => t('Submit and continue'), + '$display' => $display, + '$lockstate' => $lockstate, + '$menu_names' => $menu_names, + '$sys' => \App::$is_sys + )); + + $o .= replace_macros(get_markup_template('mitemlist.tpl'),array( + '$title' => t('Menu:'), + '$create' => $create, + '$nametitle' => t('Link Name'), + '$targettitle' => t('Link Target'), + '$menuname' => \App::$data['menu']['menu_name'], + '$menudesc' => \App::$data['menu']['menu_desc'], + '$edmenu' => t('Edit menu'), + '$menu_id' => \App::$data['menu']['menu_id'], + '$mlist' => $r, + '$edit' => t('Edit element'), + '$drop' => t('Drop element'), + '$new' => t('New element'), + '$hintmenu' => t('Edit this menu container'), + '$hintnew' => t('Add menu element'), + '$hintdrop' => t('Delete this menu item'), + '$hintedit' => t('Edit this menu item'), + )); + + return $o; + } + + + if(argc() > 2) { + + if(intval(argv(2))) { + + $m = q("select * from menu_item where mitem_id = %d and mitem_channel_id = %d limit 1", + intval(argv(2)), + intval($uid) + ); + + if(! $m) { + notice( t('Menu item not found.') . EOL); + goaway(z_root() . '/menu'. ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + + $mitem = $m[0]; + + $lockstate = (($mitem['allow_cid'] || $mitem['allow_gid'] || $mitem['deny_cid'] || $mitem['deny_gid']) ? 'lock' : 'unlock'); + + if(argc() == 4 && argv(3) == 'drop') { + menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']); + $r = menu_del_item($mitem['mitem_menu_id'], $uid, intval(argv(2))); + menu_sync_packet($uid,get_observer_hash(),$mitem['mitem_menu_id']); + if($r) + info( t('Menu item deleted.') . EOL); + else + notice( t('Menu item could not be deleted.'). EOL); + + goaway(z_root() . '/mitem/' . $mitem['mitem_menu_id'] . ((\App::$is_sys) ? '?f=&sys=1' : '')); + } + + // edit menu item + $o = replace_macros(get_markup_template('mitemedit.tpl'), array( + '$header' => t('Edit Menu Element'), + '$menu_id' => \App::$data['menu']['menu_id'], + '$permissions' => t('Menu Item Permissions'), + '$permdesc' => t("\x28click to open/close\x29"), + '$aclselect' => populate_acl($mitem,false), + '$mitem_id' => intval(argv(2)), + '$mitem_desc' => array('mitem_desc', t('Link text'), $mitem['mitem_desc'], '','*'), + '$mitem_link' => array('mitem_link', t('Link or Submenu Target'), $mitem['mitem_link'], 'Enter URL of the link or select a menu name to create a submenu', '*', 'list="menu-names"'), + '$usezid' => array('usezid', t('Use magic-auth if available'), (($mitem['mitem_flags'] & MENU_ITEM_ZID) ? 1 : 0), '', array(t('No'), t('Yes'))), + '$newwin' => array('newwin', t('Open link in new window'), (($mitem['mitem_flags'] & MENU_ITEM_NEWWIN) ? 1 : 0),'', array(t('No'), t('Yes'))), + '$mitem_order' => array('mitem_order', t('Order in list'),$mitem['mitem_order'],t('Higher numbers will sink to bottom of listing')), + '$submit' => t('Submit'), + '$lockstate' => $lockstate, + '$menu_names' => $menu_names + )); + + return $o; + } + } + } + +} diff --git a/Zotlabs/Module/Mood.php b/Zotlabs/Module/Mood.php new file mode 100644 index 000000000..b1007fd06 --- /dev/null +++ b/Zotlabs/Module/Mood.php @@ -0,0 +1,146 @@ + $v) + if($v !== 'NOTRANSLATION') + $shortlist[] = array($k,$v); + + + $tpl = get_markup_template('mood_content.tpl'); + + $o = replace_macros($tpl,array( + '$title' => t('Mood'), + '$desc' => t('Set your current mood and tell your friends'), + '$verbs' => $shortlist, + '$parent' => $parent, + '$submit' => t('Submit'), + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Msearch.php b/Zotlabs/Module/Msearch.php new file mode 100644 index 000000000..e96f78e16 --- /dev/null +++ b/Zotlabs/Module/Msearch.php @@ -0,0 +1,47 @@ + $rr['name'], + 'url' => z_root() . '/channel/' . $rr['nickname'], + 'photo' => z_root() . '/photo/avatar/' . $rr['uid'], + 'tags' => str_replace(array(',',' '),array(' ',' '),$rr['keywords']) + ); + } + + $output = array('total' => $total, 'items_page' => $perpage, 'page' => $page + 1, 'results' => $results); + + echo json_encode($output); + + killme(); + + } +} diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php new file mode 100644 index 000000000..77353da05 --- /dev/null +++ b/Zotlabs/Module/Network.php @@ -0,0 +1,531 @@ + \App::$query_string); + + call_hooks('network_content_init', $arr); + + $channel = \App::get_channel(); + $item_normal = item_normal(); + + $datequery = $datequery2 = ''; + + $group = 0; + + $nouveau = false; + + $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); + $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); + $nouveau = ((x($_GET,'new')) ? intval($_GET['new']) : 0); + $gid = ((x($_GET,'gid')) ? intval($_GET['gid']) : 0); + $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : ''); + $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : ''); + $verb = ((x($_REQUEST,'verb')) ? $_REQUEST['verb'] : ''); + + $search = (($_GET['search']) ? $_GET['search'] : ''); + if($search) { + if(strpos($search,'@') === 0) { + $r = q("select abook_id from abook left join xchan on abook_xchan = xchan_hash where xchan_name = '%s' and abook_channel = %d limit 1", + dbesc(substr($search,1)), + intval(local_channel()) + ); + if($r) { + $_GET['cid'] = $r[0]['abook_id']; + $search = $_GET['search'] = ''; + } + } + elseif(strpos($search,'#') === 0) { + $hashtags = substr($search,1); + $search = $_GET['search'] = ''; + } + } + + if($datequery) + $_GET['order'] = 'post'; + + + // filter by collection (e.g. group) + + if($gid) { + $r = q("SELECT * FROM groups WHERE id = %d AND uid = %d LIMIT 1", + intval($gid), + intval(local_channel()) + ); + if(! $r) { + if($update) + killme(); + notice( t('No such group') . EOL ); + goaway(z_root() . '/network'); + // NOTREACHED + } + + $group = $gid; + $group_hash = $r[0]['hash']; + $def_acl = array('allow_gid' => '<' . $r[0]['hash'] . '>'); + } + + $o = ''; + + + // if no tabs are selected, defaults to comments + + $cid = ((x($_GET,'cid')) ? intval($_GET['cid']) : 0); + $star = ((x($_GET,'star')) ? intval($_GET['star']) : 0); + $order = ((x($_GET,'order')) ? notags($_GET['order']) : 'comment'); + $liked = ((x($_GET,'liked')) ? intval($_GET['liked']) : 0); + $conv = ((x($_GET,'conv')) ? intval($_GET['conv']) : 0); + $spam = ((x($_GET,'spam')) ? intval($_GET['spam']) : 0); + $cmin = ((x($_GET,'cmin')) ? intval($_GET['cmin']) : 0); + $cmax = ((x($_GET,'cmax')) ? intval($_GET['cmax']) : 99); + $firehose = ((x($_GET,'fh')) ? intval($_GET['fh']) : 0); + $file = ((x($_GET,'file')) ? $_GET['file'] : ''); + + + $deftag = ''; + + if(x($_GET,'search') || x($_GET,'file')) + $nouveau = true; + if($cid) { + $r = q("SELECT abook_xchan FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", + intval($cid), + intval(local_channel()) + ); + if(! $r) { + if($update) { + killme(); + } + notice( t('No such channel') . EOL ); + goaway(z_root() . '/network'); + // NOTREACHED + } + if($_GET['pf'] === '1') + $deftag = '@' . t('forum') . '+' . intval($cid) . '+'; + else + $def_acl = array('allow_cid' => '<' . $r[0]['abook_xchan'] . '>'); + } + + if(! $update) { + $tabs = network_tabs(); + $o .= $tabs; + + // search terms header + if($search) { + $o .= replace_macros(get_markup_template("section_title.tpl"),array( + '$title' => t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') + )); + } + + nav_set_selected('network'); + + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + + $private_editing = ((($group || $cid) && (! intval($_GET['pf']))) ? true : false); + + $x = array( + 'is_owner' => true, + 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), + 'default_location' => $channel['channel_location'], + 'nickname' => $channel['channel_address'], + 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')), + 'bang' => (($private_editing) ? '!' : ''), + 'visitor' => true, + 'profile_uid' => local_channel(), + 'editor_autocomplete' => true, + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + if($deftag) + $x['pretext'] = $deftag; + + + $status_editor = status_editor($a,$x); + $o .= $status_editor; + + } + + + // We don't have to deal with ACL's on this page. You're looking at everything + // that belongs to you, hence you can see all of it. We will filter by group if + // desired. + + + $sql_options = (($star) + ? " and item_starred = 1 " + : ''); + + $sql_nets = ''; + + $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE item_thread_top = 1 $sql_options ) "; + + if($group) { + $contact_str = ''; + $contacts = group_get_members($group); + if($contacts) { + foreach($contacts as $c) { + if($contact_str) + $contact_str .= ','; + $contact_str .= "'" . $c['xchan'] . "'"; + } + } + else { + $contact_str = ' 0 '; + info( t('Privacy group is empty')); + } + + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) "; + + $x = group_rec_byhash(local_channel(), $group_hash); + + if($x) { + $title = replace_macros(get_markup_template("section_title.tpl"),array( + '$title' => t('Privacy group: ') . $x['name'] + )); + } + + $o = $tabs; + $o .= $title; + $o .= $status_editor; + + } + + elseif($cid) { + + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1", + intval($cid), + intval(local_channel()) + ); + if($r) { + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) "; + $title = replace_macros(get_markup_template("section_title.tpl"),array( + '$title' => '' . urlencode($r[0]['xchan_name']) . ' ' . $r[0]['xchan_name'] . '' + )); + $o = $tabs; + $o .= $title; + $o .= $status_editor; + } + else { + notice( t('Invalid connection.') . EOL); + goaway(z_root() . '/network'); + } + } + + if(x($category)) { + $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY)); + } + if(x($hashtags)) { + $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); + } + + if(! $update) { + // The special div is needed for liveUpdate to kick in for this page. + // We only launch liveUpdate if you aren't filtering in some incompatible + // way and also you aren't writing a comment (discovered in javascript). + + if($gid || $cid || $cmin || ($cmax != 99) || $star || $liked || $conv || $spam || $nouveau || $list) + $firehose = 0; + + $maxheight = get_pconfig(local_channel(),'system','network_divmore_height'); + if(! $maxheight) + $maxheight = 400; + + + $o .= '
    ' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'network', + '$uid' => ((local_channel()) ? local_channel() : '0'), + '$gid' => (($gid) ? $gid : '0'), + '$cid' => (($cid) ? $cid : '0'), + '$cmin' => (($cmin) ? $cmin : '0'), + '$cmax' => (($cmax) ? $cmax : '0'), + '$star' => (($star) ? $star : '0'), + '$liked' => (($liked) ? $liked : '0'), + '$conv' => (($conv) ? $conv : '0'), + '$spam' => (($spam) ? $spam : '0'), + '$fh' => (($firehose) ? $firehose : '0'), + '$nouveau' => (($nouveau) ? $nouveau : '0'), + '$wall' => '0', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$search' => (($search) ? $search : ''), + '$order' => $order, + '$file' => $file, + '$cats' => $category, + '$tags' => $hashtags, + '$dend' => $datequery, + '$mid' => '', + '$verb' => $verb, + '$dbegin' => $datequery2 + )); + } + + $sql_extra3 = ''; + + if($datequery) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); + } + if($datequery2) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); + } + + $sql_extra2 = (($nouveau) ? '' : " AND item.parent = item.id "); + $sql_extra3 = (($nouveau) ? '' : $sql_extra3); + + if(x($_GET,'search')) { + $search = escape_tags($_GET['search']); + if(strpos($search,'#') === 0) { + $sql_extra .= term_query('item',substr($search,1),TERM_HASHTAG,TERM_COMMUNITYTAG); + } + else { + $sql_extra .= sprintf(" AND item.body like '%s' ", + dbesc(protect_sprintf('%' . $search . '%')) + ); + } + } + + if($verb) { + $sql_extra .= sprintf(" AND item.verb like '%s' ", + dbesc(protect_sprintf('%' . $verb . '%')) + ); + } + + if(strlen($file)) { + $sql_extra .= term_query('item',$file,TERM_FILE); + } + + if($conv) { + $sql_extra .= sprintf(" AND parent IN (SELECT distinct(parent) from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ", + dbesc(protect_sprintf($channel['channel_hash'])) + ); + } + + if($update && ! $load) { + + // only setup pagination on initial page view + $pager_sql = ''; + + } + else { + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + } + + + if(($cmin != 0) || ($cmax != 99)) { + + // Not everybody who shows up in the network stream will be in your address book. + // By default those that aren't are assumed to have closeness = 99; but this isn't + // recorded anywhere. So if cmax is 99, we'll open the search up to anybody in + // the stream with a NULL address book entry. + + $sql_nets .= " AND "; + + if($cmax == 99) + $sql_nets .= " ( "; + + $sql_nets .= "( abook.abook_closeness >= " . intval($cmin) . " "; + $sql_nets .= " AND abook.abook_closeness <= " . intval($cmax) . " ) "; + + if($cmax == 99) + $sql_nets .= " OR abook.abook_closeness IS NULL ) "; + + + } + + $abook_uids = " and abook.abook_channel = " . local_channel() . " "; + + if($firehose && (! get_config('system','disable_discover_tab'))) { + require_once('include/identity.php'); + $sys = get_sys_channel(); + $uids = " and item.uid = " . intval($sys['channel_id']) . " "; + \App::$data['firehose'] = intval($sys['channel_id']); + } + else { + $uids = " and item.uid = " . local_channel() . " "; + } + + if(get_pconfig(local_channel(),'system','network_list_mode')) + $page_mode = 'list'; + else + $page_mode = 'client'; + + $simple_update = (($update) ? " and item_unseen = 1 " : ''); + + // This fixes a very subtle bug so I'd better explain it. You wake up in the morning or return after a day + // or three and look at your matrix page - after opening up your browser. The first page loads just as it + // should. All of a sudden a few seconds later, page 2 will get inserted at the beginning of the page + // (before the page 1 content). The update code is actually doing just what it's supposed + // to, it's fetching posts that have the ITEM_UNSEEN bit set. But the reason that page 2 content is being + // returned in an UPDATE is because you hadn't gotten that far yet - you're still on page 1 and everything + // that we loaded for page 1 is now marked as seen. But the stuff on page 2 hasn't been. So... it's being + // treated as "new fresh" content because it is unseen. We need to distinguish it somehow from content + // which "arrived as you were reading page 1". We're going to do this + // by storing in your session the current UTC time whenever you LOAD a network page, and only UPDATE items + // which are both ITEM_UNSEEN and have "changed" since that time. Cross fingers... + + if($update && $_SESSION['loadtime']) + $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; + if($load) + $simple_update = ''; + + if($nouveau && $load) { + // "New Item View" - show all items unthreaded in reverse created date order + + $items = q("SELECT item.*, item.id AS item_id, received FROM item + left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) + WHERE true $uids $item_normal + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $simple_update + $sql_extra $sql_nets + ORDER BY item.received DESC $pager_sql " + ); + + require_once('include/items.php'); + + xchan_query($items); + + $items = fetch_post_tags($items,true); + } + elseif($update) { + + // Normal conversation view + + if($order === 'post') + $ordering = "created"; + else + $ordering = "commented"; + + if($load) { + + // Fetch a page full of parent items for this page + + $r = q("SELECT distinct item.id AS item_id, $ordering FROM item + left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) + WHERE true $uids $item_normal + AND item.parent = item.id + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra3 $sql_extra $sql_nets + ORDER BY $ordering DESC $pager_sql " + ); + + } + else { + // this is an update + $r = q("SELECT item.parent AS item_id FROM item + left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) + WHERE true $uids $item_normal $simple_update + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra3 $sql_extra $sql_nets " + ); + $_SESSION['loadtime'] = datetime_convert(); + } + + // Then fetch all the children of the parents that are on this page + $parents_str = ''; + $update_unseen = ''; + + if($r) { + + $parents_str = ids_to_querystr($r,'item_id'); + + $items = q("SELECT item.*, item.id AS item_id FROM item + WHERE true $uids $item_normal + AND item.parent IN ( %s ) + $sql_extra ", + dbesc($parents_str) + ); + + xchan_query($items,true,(($firehose) ? local_channel() : 0)); + $items = fetch_post_tags($items,true); + $items = conv_sort($items,$ordering); + } + else { + $items = array(); + } + + if($page_mode === 'list') { + + /** + * in "list mode", only mark the parent item and any like activities as "seen". + * We won't distinguish between comment likes and post likes. The important thing + * is that the number of unseen comments will be accurate. The SQL to separate the + * comment likes could also get somewhat hairy. + */ + + if($parents_str) { + $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )"; + $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) "; + } + } + else { + if($parents_str) { + $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )"; + } + } + } + + if(($update_unseen) && (! $firehose)) + $r = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d $update_unseen ", + intval(local_channel()) + ); + + $mode = (($nouveau) ? 'network-new' : 'network'); + + $o .= conversation($a,$items,$mode,$update,$page_mode); + + if(($items) && (! $update)) + $o .= alt_pager($a,count($items)); + + return $o; + } + +} diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php new file mode 100644 index 000000000..b77b2660b --- /dev/null +++ b/Zotlabs/Module/New_channel.php @@ -0,0 +1,151 @@ + 1) ? argv(1) : ''); + + if($cmd === 'autofill.json') { + require_once('library/urlify/URLify.php'); + $result = array('error' => false, 'message' => ''); + $n = trim($_REQUEST['name']); + + $x = strtolower(URLify::transliterate($n)); + + $test = array(); + + // first name + if(strpos($x,' ')) + $test[] = legal_webbie(substr($x,0,strpos($x,' '))); + if($test[0]) { + // first name plus first initial of last + $test[] = ((strpos($x,' ')) ? $test[0] . legal_webbie(trim(substr($x,strpos($x,' '),2))) : ''); + // first name plus random number + $test[] = $test[0] . mt_rand(1000,9999); + } + // fullname + $test[] = legal_webbie($x); + // fullname plus random number + $test[] = legal_webbie($x) . mt_rand(1000,9999); + + json_return_and_die(check_webbie($test)); + } + + if($cmd === 'checkaddr.json') { + require_once('library/urlify/URLify.php'); + $result = array('error' => false, 'message' => ''); + $n = trim($_REQUEST['nick']); + + $x = strtolower(URLify::transliterate($n)); + + $test = array(); + + $n = legal_webbie($x); + if(strlen($n)) { + $test[] = $n; + $test[] = $n . mt_rand(1000,9999); + } + + for($y = 0; $y < 100; $y ++) + $test[] = 'id' . mt_rand(1000,9999); + + json_return_and_die(check_webbie($test)); + } + + + } + + function post() { + + $arr = $_POST; + + $acc = \App::get_account(); + $arr['account_id'] = get_account_id(); + + // prevent execution by delegated channels as well as those not logged in. + // get_account_id() returns the account_id from the session. But \App::$account + // may point to the original authenticated account. + + if((! $acc) || ($acc['account_id'] != $arr['account_id'])) { + notice( t('Permission denied.') . EOL ); + return; + } + + $result = create_identity($arr); + + if(! $result['success']) { + notice($result['message']); + return; + } + + $newuid = $result['channel']['channel_id']; + + change_channel($result['channel']['channel_id']); + + if(! strlen($next_page = get_config('system','workflow_channel_next'))) + $next_page = 'settings'; + + goaway(z_root() . '/' . $next_page); + + } + + function get() { + + $acc = \App::get_account(); + + if((! $acc) || $acc['account_id'] != get_account_id()) { + notice( t('Permission denied.') . EOL); + return; + } + + $default_role = ''; + $aid = get_account_id(); + if($aid) { + $r = q("select count(channel_id) as total from channel where channel_account_id = %d", + intval($aid) + ); + if($r && (! intval($r[0]['total']))) { + $default_role = get_config('system','default_permissions_role'); + } + + $limit = account_service_class_fetch(get_account_id(),'total_identities'); + + if($r && ($limit !== false)) { + $channel_usage_message = sprintf( t("You have created %1$.0f of %2$.0f allowed channels."), $r[0]['total'], $limit); + } + else { + $channel_usage_message = ''; + } + } + + $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"')); + $nickhub = '@' . \App::get_hostname(); + $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub)); + $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" ); + $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' ' . t('Read more about roles') . '',get_roles()); + + $o = replace_macros(get_markup_template('new_channel.tpl'), array( + '$title' => t('Create Channel'), + '$desc' => t('A channel is your identity on this network. It can represent a person, a blog, or a forum to name a few. Channels can make connections with other channels to share information with highly detailed permissions.'), + '$label_import' => t('or import an existing channel from another location.'), + '$name' => $name, + '$role' => $role, + '$default_role' => $default_role, + '$nickname' => $nickname, + '$submit' => t('Create'), + '$channel_usage_message' => $channel_usage_message + )); + + return $o; + + } + + +} diff --git a/Zotlabs/Module/Nojs.php b/Zotlabs/Module/Nojs.php new file mode 100644 index 000000000..5e48c5b5f --- /dev/null +++ b/Zotlabs/Module/Nojs.php @@ -0,0 +1,15 @@ + true); + if(array_key_exists('note_text',$_REQUEST)) { + $body = escape_tags($_REQUEST['note_text']); + + // I've had my notes vanish into thin air twice in four years. + // Provide a backup copy if there were contents previously + // and there are none being saved now. + + if(! $body) { + $old_text = get_pconfig(local_channel(),'notes','text'); + if($old_text) + set_pconfig(local_channel(),'notes','text.bak',$old_text); + } + set_pconfig(local_channel(),'notes','text',$body); + } + + // push updates to channel clones + + if((argc() > 1) && (argv(1) === 'sync')) { + require_once('include/zot.php'); + build_sync_packet(); + } + + logger('notes saved.', LOGGER_DEBUG); + json_return_and_die($ret); + + } + +} diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php new file mode 100644 index 000000000..d51d2861c --- /dev/null +++ b/Zotlabs/Module/Notifications.php @@ -0,0 +1,111 @@ + 1) ? \App::$argv[1] : 0); + + if($request_id === "all") + return; + + if($request_id) { + + $r = q("SELECT * FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($request_id), + intval(local_channel()) + ); + + if(count($r)) { + $intro_id = $r[0]['id']; + $contact_id = $r[0]['contact-id']; + } + else { + notice( t('Invalid request identifier.') . EOL); + return; + } + + // If it is a friend suggestion, the contact is not a new friend but an existing friend + // that should not be deleted. + + $fid = $r[0]['fid']; + + if($_POST['submit'] == t('Discard')) { + $r = q("DELETE FROM `intro` WHERE `id` = %d", + intval($intro_id) + ); + if(! $fid) { + + // The check for blocked and pending is in case the friendship was already approved + // and we just want to get rid of the now pointless notification + + $r = q("DELETE FROM `contact` WHERE `id` = %d AND `uid` = %d AND `self` = 0 AND `blocked` = 1 AND `pending` = 1", + intval($contact_id), + intval(local_channel()) + ); + } + goaway(z_root() . '/notifications/intros'); + } + if($_POST['submit'] == t('Ignore')) { + $r = q("UPDATE `intro` SET `ignore` = 1 WHERE `id` = %d", + intval($intro_id)); + goaway(z_root() . '/notifications/intros'); + } + } + } + + + + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + nav_set_selected('notifications'); + + $o = ''; + + $notif_tpl = get_markup_template('notifications.tpl'); + + $not_tpl = get_markup_template('notify.tpl'); + require_once('include/bbcode.php'); + + $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc", + intval(local_channel()) + ); + + if (count($r) > 0) { + $notifications_available =1; + foreach ($r as $it) { + $notif_content .= replace_macros($not_tpl,array( + '$item_link' => z_root().'/notify/view/'. $it['id'], + '$item_image' => $it['photo'], + '$item_text' => strip_tags(bbcode($it['msg'])), + '$item_when' => relative_date($it['date']) + )); + } + } else { + $notif_content .= t('No more system notifications.'); + } + + $o .= replace_macros($notif_tpl,array( + '$notif_header' => t('System Notifications'), + '$notif_link_mark_seen' => t('Mark all system notifications seen'), + '$notif_content' => $notif_content, + '$notifications_available' => $notifications_available, + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php new file mode 100644 index 000000000..227491145 --- /dev/null +++ b/Zotlabs/Module/Notify.php @@ -0,0 +1,69 @@ + 2 && argv(1) === 'view' && intval(argv(2))) { + $r = q("select * from notify where id = %d and uid = %d limit 1", + intval(argv(2)), + intval(local_channel()) + ); + if($r) { + q("update notify set seen = 1 where (( parent != '' and parent = '%s' and otype = '%s' ) or link = '%s' ) and uid = %d", + dbesc($r[0]['parent']), + dbesc($r[0]['otype']), + dbesc($r[0]['link']), + intval(local_channel()) + ); + goaway($r[0]['link']); + } + goaway(z_root()); + } + + + } + + + function get() { + if(! local_channel()) + return login(); + + $notif_tpl = get_markup_template('notifications.tpl'); + + $not_tpl = get_markup_template('notify.tpl'); + require_once('include/bbcode.php'); + + $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc", + intval(local_channel()) + ); + + if($r) { + foreach ($r as $it) { + $notif_content .= replace_macros($not_tpl,array( + '$item_link' => z_root().'/notify/view/'. $it['id'], + '$item_image' => $it['photo'], + '$item_text' => strip_tags(bbcode($it['msg'])), + '$item_when' => relative_date($it['date']) + )); + } + } + else { + $notif_content .= t('No more system notifications.'); + } + + $o .= replace_macros($notif_tpl,array( + '$notif_header' => t('System Notifications'), + '$tabs' => '', // $tabs, + '$notif_content' => $notif_content, + )); + + return $o; + + } +} diff --git a/Zotlabs/Module/Oembed.php b/Zotlabs/Module/Oembed.php new file mode 100644 index 000000000..b02182053 --- /dev/null +++ b/Zotlabs/Module/Oembed.php @@ -0,0 +1,36 @@ + 1) { + if (argv(1) == 'b2h'){ + $url = array( "", trim(hex2bin($_REQUEST['url']))); + echo oembed_replacecb($url); + killme(); + } + + elseif (argv(1) == 'h2b'){ + $text = trim(hex2bin($_REQUEST['text'])); + echo oembed_html2bbcode($text); + killme(); + } + + else { + echo ""; + $src = base64url_decode(argv(1)); + $j = oembed_fetch_url($src); + echo $j->html; + // logger('mod-oembed ' . $h, LOGGER_ALL); + echo ""; + } + } + killme(); + } + +} diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php new file mode 100644 index 000000000..f36a452e8 --- /dev/null +++ b/Zotlabs/Module/Oep.php @@ -0,0 +1,403 @@ + 1 && argv(1) === 'html') ? true : false); + if($_REQUEST['url']) { + $_REQUEST['url'] = strip_zids($_REQUEST['url']); + $url = $_REQUEST['url']; + } + + if(! $url) + http_status_exit(404, 'Not found'); + + $maxwidth = $_REQUEST['maxwidth']; + $maxheight = $_REQUEST['maxheight']; + $format = $_REQUEST['format']; + if($format && $format !== 'json') + http_status_exit(501, 'Not implemented'); + + if(fnmatch('*/photos/*/album/*',$url)) + $arr = $this->oep_album_reply($_REQUEST); + elseif(fnmatch('*/photos/*/image/*',$url)) + $arr = $this->oep_photo_reply($_REQUEST); + elseif(fnmatch('*/photos*',$url)) + $arr = $this->oep_phototop_reply($_REQUEST); + elseif(fnmatch('*/display/*',$url)) + $arr = $this->oep_display_reply($_REQUEST); + elseif(fnmatch('*/channel/*mid=*',$url)) + $arr = $this->oep_mid_reply($_REQUEST); + elseif(fnmatch('*/channel*',$url)) + $arr = $this->oep_profile_reply($_REQUEST); + elseif(fnmatch('*/profile/*',$url)) + $arr = $this->oep_profile_reply($_REQUEST); + + if($arr) { + if($html) { + if($arr['type'] === 'rich') { + header('Content-Type: text/html'); + echo $arr['html']; + } + } + else { + header('Content-Type: application/json+oembed'); + echo json_encode($arr); + } + killme(); + } + + http_status_exit(404,'Not found'); + + } + + function oep_display_reply($args) { + + $ret = array(); + $url = $args['url']; + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + if(preg_match('#//(.*?)/(.*?)/(.*?)/(.*?)mid\=(.*?)(&|$)#',$url,$matches)) { + $chn = $matches[3]; + $res = $matches[5]; + } + + if(! ($chn && $res)) + return; + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($chn) + ); + + if(! $c) + return; + + $sql_extra = item_permissions_sql($c[0]['channel_id']); + + $p = q("select * from item where mid = '%s' and uid = %d $sql_extra limit 1", + dbesc($res), + intval($c[0]['channel_id']) + ); + if(! $p) + return; + + xchan_query($p,true); + $p = fetch_post_tags($p,true); + + $o = "[share author='".urlencode($p[0]['author']['xchan_name']). + "' profile='".$p[0]['author']['xchan_url'] . + "' avatar='".$p[0]['author']['xchan_photo_s']. + "' link='".$p[0]['plink']. + "' posted='".$p[0]['created']. + "' message_id='".$p[0]['mid']."']"; + if($p[0]['title']) + $o .= '[b]'.$p[0]['title'].'[/b]'."\r\n"; + $o .= $p[0]['body']; + $o .= "[/share]"; + $o = bbcode($o); + + $ret['type'] = 'rich'; + + $w = (($maxwidth) ? $maxwidth : 640); + $h = (($maxheight) ? $maxheight : $w * 2 / 3); + + $ret['html'] = '
    ' . $o . '
    '; + + $ret['width'] = $w; + $ret['height'] = $h; + + return $ret; + + } + + function oep_mid_reply($args) { + + $ret = array(); + $url = $args['url']; + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + if(preg_match('#//(.*?)/(.*?)/(.*?)/(.*?)mid\=(.*?)(&|$)#',$url,$matches)) { + $chn = $matches[3]; + $res = $matches[5]; + } + + if(! ($chn && $res)) + return; + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($chn) + ); + + if(! $c) + return; + + $sql_extra = item_permissions_sql($c[0]['channel_id']); + + $p = q("select * from item where mid = '%s' and uid = %d $sql_extra limit 1", + dbesc($res), + intval($c[0]['channel_id']) + ); + if(! $p) + return; + + xchan_query($p,true); + $p = fetch_post_tags($p,true); + + $o = "[share author='".urlencode($p[0]['author']['xchan_name']). + "' profile='".$p[0]['author']['xchan_url'] . + "' avatar='".$p[0]['author']['xchan_photo_s']. + "' link='".$p[0]['plink']. + "' posted='".$p[0]['created']. + "' message_id='".$p[0]['mid']."']"; + if($p[0]['title']) + $o .= '[b]'.$p[0]['title'].'[/b]'."\r\n"; + $o .= $p[0]['body']; + $o .= "[/share]"; + $o = bbcode($o); + + $ret['type'] = 'rich'; + + $w = (($maxwidth) ? $maxwidth : 640); + $h = (($maxheight) ? $maxheight : $w * 2 / 3); + + $ret['html'] = '
    ' . $o . '
    '; + + $ret['width'] = $w; + $ret['height'] = $h; + + return $ret; + + } + + function oep_profile_reply($args) { + + + require_once('include/identity.php'); + require_once('include/Contact.php'); + $url = $args['url']; + + if(preg_match('#//(.*?)/(.*?)/(.*?)(/|\?|&|$)#',$url,$matches)) { + $chn = $matches[3]; + } + + if(! $chn) + return; + + $c = channelx_by_nick($chn); + + if(! $c) + return; + + + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + $width = 800; + $height = 375; + + if($maxwidth) { + $width = $maxwidth; + $height = (375 / 800) * $width; + } + if($maxheight) { + if($maxheight < $height) { + $width = (800 / 375) * $maxheight; + $height = $maxheight; + } + } + $ret = array(); + + $ret['type'] = 'rich'; + $ret['width'] = intval($width); + $ret['height'] = intval($height); + + $ret['html'] = get_zcard($c,get_observer_hash(),array('width' => $width, 'height' => $height)); + + return $ret; + + } + + function oep_album_reply($args) { + + $ret = array(); + $url = $args['url']; + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + if(preg_match('|//(.*?)/(.*?)/(.*?)/album/|',$url,$matches)) { + $chn = $matches[3]; + $res = hex2bin(basename($url)); + } + + if(! ($chn && $res)) + return; + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($chn) + ); + + if(! $c) + return; + + $sql_extra = permissions_sql($c[0]['channel_id']); + + $p = q("select resource_id from photo where album = '%s' and uid = %d and scale = 0 $sql_extra order by created desc limit 1", + dbesc($res), + intval($c[0]['channel_id']) + ); + if(! $p) + return; + + $res = $p[0]['resource_id']; + + $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + intval($c[0]['channel_id']), + dbesc($res) + ); + + if($r) { + foreach($r as $rr) { + $foundres = false; + if($maxheight && $rr['height'] > $maxheight) + continue; + if($maxwidth && $rr['width'] > $maxwidth) + continue; + $foundres = true; + break; + } + + if($foundres) { + $ret['type'] = 'link'; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_width'] = $rr['width']; + $ret['thumbnail_height'] = $rr['height']; + } + + + } + return $ret; + + } + + + function oep_phototop_reply($args) { + + $ret = array(); + $url = $args['url']; + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + if(preg_match('|//(.*?)/(.*?)/(.*?)$|',$url,$matches)) { + $chn = $matches[3]; + } + + if(! $chn) + return; + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($chn) + ); + + if(! $c) + return; + + $sql_extra = permissions_sql($c[0]['channel_id']); + + $p = q("select resource_id from photo where uid = %d and scale = 0 $sql_extra order by created desc limit 1", + intval($c[0]['channel_id']) + ); + if(! $p) + return; + + $res = $p[0]['resource_id']; + + $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + intval($c[0]['channel_id']), + dbesc($res) + ); + + if($r) { + foreach($r as $rr) { + $foundres = false; + if($maxheight && $rr['height'] > $maxheight) + continue; + if($maxwidth && $rr['width'] > $maxwidth) + continue; + $foundres = true; + break; + } + + if($foundres) { + $ret['type'] = 'link'; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_width'] = $rr['width']; + $ret['thumbnail_height'] = $rr['height']; + } + + + } + return $ret; + + } + + + function oep_photo_reply($args) { + + $ret = array(); + $url = $args['url']; + $maxwidth = intval($args['maxwidth']); + $maxheight = intval($args['maxheight']); + + if(preg_match('|//(.*?)/(.*?)/(.*?)/image/|',$url,$matches)) { + $chn = $matches[3]; + $res = basename($url); + } + + if(! ($chn && $res)) + return; + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($chn) + ); + + if(! $c) + return; + + $sql_extra = permissions_sql($c[0]['channel_id']); + + + $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + intval($c[0]['channel_id']), + dbesc($res) + ); + + if($r) { + foreach($r as $rr) { + $foundres = false; + if($maxheight && $rr['height'] > $maxheight) + continue; + if($maxwidth && $rr['width'] > $maxwidth) + continue; + $foundres = true; + break; + } + + if($foundres) { + $ret['type'] = 'link'; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_width'] = $rr['width']; + $ret['thumbnail_height'] = $rr['height']; + } + + + } + return $ret; + + } +} diff --git a/Zotlabs/Module/Oexchange.php b/Zotlabs/Module/Oexchange.php new file mode 100644 index 000000000..24fc14821 --- /dev/null +++ b/Zotlabs/Module/Oexchange.php @@ -0,0 +1,77 @@ + 1) && (argv(1) === 'xrd')) { + $tpl = get_markup_template('oexchange_xrd.tpl'); + + $o = replace_macros($tpl, array('$base' => z_root())); + echo $o; + killme(); + } + } + + function get() { + + if(! local_channel()) { + if(remote_channel()) { + $observer = \App::get_observer(); + if($observer && $observer['xchan_url']) { + $parsed = @parse_url($observer['xchan_url']); + if(! $parsed) { + notice( t('Unable to find your hub.') . EOL); + return; + } + $url = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : ''); + $url .= '/oexchange'; + $result = z_post_url($url,$_REQUEST); + json_return_and_die($result); + } + } + + return login(false); + } + + if((argc() > 1) && argv(1) === 'done') { + info( t('Post successful.') . EOL); + return; + } + + $url = (((x($_REQUEST,'url')) && strlen($_REQUEST['url'])) + ? urlencode(notags(trim($_REQUEST['url']))) : ''); + $title = (((x($_REQUEST,'title')) && strlen($_REQUEST['title'])) + ? '&title=' . urlencode(notags(trim($_REQUEST['title']))) : ''); + $description = (((x($_REQUEST,'description')) && strlen($_REQUEST['description'])) + ? '&description=' . urlencode(notags(trim($_REQUEST['description']))) : ''); + $tags = (((x($_REQUEST,'tags')) && strlen($_REQUEST['tags'])) + ? '&tags=' . urlencode(notags(trim($_REQUEST['tags']))) : ''); + + $ret = z_fetch_url(z_root() . '/urlinfo?f=&url=' . $url . $title . $description . $tags); + + if($ret['success']) + $s = $ret['body']; + + if(! strlen($s)) + return; + + $post = array(); + + $post['profile_uid'] = local_channel(); + $post['return'] = '/oexchange/done' ; + $post['body'] = $s; + $post['type'] = 'wall'; + + $_REQUEST = $post; + $mod = new Item(); + $mod->post(); + + } + + + +} diff --git a/Zotlabs/Module/Online.php b/Zotlabs/Module/Online.php new file mode 100644 index 000000000..39399db38 --- /dev/null +++ b/Zotlabs/Module/Online.php @@ -0,0 +1,17 @@ + false); + if(argc() != 2) + json_return_and_die($ret); + + $ret = get_online_status(argv(1)); + json_return_and_die($ret); + } + +} diff --git a/Zotlabs/Module/Openid.php b/Zotlabs/Module/Openid.php new file mode 100644 index 000000000..c24686e33 --- /dev/null +++ b/Zotlabs/Module/Openid.php @@ -0,0 +1,198 @@ +validate()) { + + logger('openid: validate'); + + $authid = normalise_openid($_REQUEST['openid_identity']); + + if(! strlen($authid)) { + logger( t('OpenID protocol error. No ID returned.') . EOL); + goaway(z_root()); + } + + $x = match_openid($authid); + if($x) { + + $r = q("select * from channel where channel_id = %d limit 1", + intval($x) + ); + if($r) { + $y = q("select * from account where account_id = %d limit 1", + intval($r[0]['channel_account_id']) + ); + if($y) { + foreach($y as $record) { + if(($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)) { + logger('mod_openid: openid success for ' . $x[0]['channel_name']); + $_SESSION['uid'] = $r[0]['channel_id']; + $_SESSION['account_id'] = $r[0]['channel_account_id']; + $_SESSION['authenticated'] = true; + authenticate_success($record,true,true,true,true); + goaway(z_root()); + } + } + } + } + } + + // Successful OpenID login - but we can't match it to an existing account. + // See if they've got an xchan + + $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", + dbesc($authid) + ); + + if($r) { + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $r[0]['xchan_hash']; + $_SESSION['my_url'] = $r[0]['xchan_url']; + $_SESSION['my_address'] = $r[0]['xchan_addr']; + $arr = array('xchan' => $r[0], 'session' => $_SESSION); + call_hooks('magic_auth_openid_success',$arr); + \App::set_observer($r[0]); + require_once('include/security.php'); + \App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); + info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name'])); + logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); + if($_SESSION['return_url']) + goaway($_SESSION['return_url']); + goaway(z_root()); + } + + // no xchan... + // create one. + // We should probably probe the openid url and figure out if they have any kind of social presence we might be able to + // scrape some identifying info from. + + $name = $authid; + $url = trim($_REQUEST['openid_identity'],'/'); + if(strpos($url,'http') === false) + $url = 'https://' . $url; + $pphoto = z_root() . '/' . get_default_profile_photo(); + $parsed = @parse_url($url); + if($parsed) { + $host = $parsed['host']; + } + + $attr = $openid->getAttributes(); + + if(is_array($attr) && count($attr)) { + foreach($attr as $k => $v) { + if($k === 'namePerson/friendly') + $nick = notags(trim($v)); + if($k === 'namePerson/first') + $first = notags(trim($v)); + if($k === 'namePerson') + $name = notags(trim($v)); + if($k === 'contact/email') + $addr = notags(trim($v)); + if($k === 'media/image/aspect11') + $photosq = trim($v); + if($k === 'media/image/default') + $photo_other = trim($v); + } + } + if(! $nick) { + if($first) + $nick = $first; + else + $nick = $name; + } + + require_once('library/urlify/URLify.php'); + $x = strtolower(URLify::transliterate($nick)); + if($nick & $host) + $addr = $nick . '@' . $host; + $network = 'unknown'; + + if($photosq) + $pphoto = $photosq; + elseif($photo_other) + $pphoto = $photo_other; + + $mimetype = guess_image_type($pphoto); + + $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype, + xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, + xchan_name_date, xchan_hidden) + values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ", + dbesc($url), + dbesc(''), + dbesc(''), + dbesc(''), + dbesc($mimetype), + dbesc($pphoto), + dbesc($addr), + dbesc($url), + dbesc(''), + dbesc(''), + dbesc(''), + dbesc($name), + dbesc($network), + dbesc(datetime_convert()), + dbesc(datetime_convert()) + ); + if($x) { + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($url) + ); + if($r) { + + $photos = import_xchan_photo($pphoto,$url); + if($photos) { + $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', + xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", + dbesc(datetime_convert()), + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($url) + ); + } + + set_xconfig($url,'system','openid',$authid); + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $r[0]['xchan_hash']; + $_SESSION['my_url'] = $r[0]['xchan_url']; + $_SESSION['my_address'] = $r[0]['xchan_addr']; + $arr = array('xchan' => $r[0], 'session' => $_SESSION); + call_hooks('magic_auth_openid_success',$arr); + \App::set_observer($r[0]); + info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name'])); + logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); + if($_SESSION['return_url']) + goaway($_SESSION['return_url']); + goaway(z_root()); + } + } + + } + } + notice( t('Login failed.') . EOL); + goaway(z_root()); + // NOTREACHED + } + +} diff --git a/Zotlabs/Module/Opensearch.php b/Zotlabs/Module/Opensearch.php new file mode 100644 index 000000000..8e76038c9 --- /dev/null +++ b/Zotlabs/Module/Opensearch.php @@ -0,0 +1,24 @@ + z_root(), + '$nodename' => \App::get_hostname(), + )); + + echo $o; + + killme(); + + } + +} diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php new file mode 100644 index 000000000..64b940b0f --- /dev/null +++ b/Zotlabs/Module/Page.php @@ -0,0 +1,150 @@ +disallowed_pconfig())) { + notice( t('This setting requires special processing and editing has been blocked.') . EOL); + return; + } + + if(strpos($k,'password') !== false) { + $v = z_obscure($v); + } + + set_pconfig(local_channel(),$cat,$k,$v); + build_sync_packet(); + + goaway(z_root() . '/pconfig/' . $cat . '/' . $k); + + } + + + function get() { + + if(! local_channel()) { + return login(); + } + + $content = '

    ' . t('Configuration Editor') . '

    '; + $content .= '
    ' . t('Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature.') . '
    ' . EOL . EOL; + + + + if(argc() == 3) { + $content .= 'pconfig[' . local_channel() . ']' . EOL; + $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . ']' . EOL . EOL; + $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . escape_tags(argv(2)) . '] = ' . get_pconfig(local_channel(),escape_tags(argv(1)),escape_tags(argv(2))) . EOL; + + if(in_array(argv(2),disallowed_pconfig())) { + notice( t('This setting requires special processing and editing has been blocked.') . EOL); + return $content; + } + else + $content .= $this->pconfig_form(escape_tags(argv(1)),escape_tags(argv(2))); + } + + + if(argc() == 2) { + $content .= 'pconfig[' . local_channel() . ']' . EOL; + load_pconfig(local_channel(),escape_tags(argv(1))); + foreach(\App::$config[local_channel()][escape_tags(argv(1))] as $k => $x) { + $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . $k . '] = ' . escape_tags($x) . EOL; + } + } + + if(argc() == 1) { + + $r = q("select * from pconfig where uid = " . local_channel()); + if($r) { + foreach($r as $rr) { + $content .= 'pconfig[' . local_channel() . '][' . escape_tags($rr['cat']) . '][' . escape_tags($rr['k']) . '] = ' . escape_tags($rr['v']) . EOL; + } + } + } + return $content; + + } + + + function pconfig_form($cat,$k) { + + $o = '
    '; + $o .= ''; + + $v = get_pconfig(local_channel(),$cat,$k); + if(strpos($k,'password') !== false) + $v = z_unobscure($v); + + $o .= ''; + $o .= ''; + + if(strpos($v,"\n")) + $o .= ''; + else + $o .= ''; + + $o .= EOL . EOL; + $o .= ''; + $o .= '
    '; + + return $o; + + } + + + + function disallowed_pconfig() { + return array( + 'permissions_role' + ); + } + +} diff --git a/Zotlabs/Module/Pdledit.php b/Zotlabs/Module/Pdledit.php new file mode 100644 index 000000000..accfb6fa1 --- /dev/null +++ b/Zotlabs/Module/Pdledit.php @@ -0,0 +1,72 @@ + 1) + $module = 'mod_' . argv(1) . '.pdl'; + else { + $o .= '
    '; + $o .= '

    ' . t('Edit System Page Description') . '

    '; + $files = glob('mod/*'); + if($files) { + foreach($files as $f) { + $name = basename($f,'.php'); + $x = theme_include('mod_' . $name . '.pdl'); + if($x) { + $o .= '' . $name . '
    '; + } + } + } + + $o .= '
    '; + + // list module pdl files + return $o; + } + + $t = get_pconfig(local_channel(),'system',$module); + if(! $t) + $t = file_get_contents(theme_include($module)); + if(! $t) { + notice( t('Layout not found.') . EOL); + return ''; + } + + $o = replace_macros(get_markup_template('pdledit.tpl'),array( + '$header' => t('Edit System Page Description'), + '$mname' => t('Module Name:'), + '$help' => t('Layout Help'), + '$module' => argv(1), + '$content' => htmlspecialchars($t,ENT_COMPAT,'UTF-8'), + '$submit' => t('Submit') + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php new file mode 100644 index 000000000..408688886 --- /dev/null +++ b/Zotlabs/Module/Photo.php @@ -0,0 +1,250 @@ + 1)) + { + $resolution = 1; + } + } + + // If using resolution 1, make sure it exists before proceeding: + if ($resolution == 1) + { + $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1", + dbesc($photo), + intval($resolution) + ); + if (!($r)) + $resolution = 2; + } + + $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1", + dbesc($photo), + intval($resolution) + ); + if($r) { + + $allowed = (($r[0]['uid']) ? perm_is_allowed($r[0]['uid'],$observer_xchan,'view_storage') : true); + + $sql_extra = permissions_sql($r[0]['uid']); + + // Now we'll see if we can access the photo + + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND scale = %d $sql_extra LIMIT 1", + dbesc($photo), + intval($resolution) + ); + + if($r && $allowed) { + $data = dbunescbin($r[0]['data']); + $mimetype = $r[0]['type']; + if(intval($r[0]['os_storage'])) + $data = file_get_contents($data); + } + else { + + // Does the picture exist? It may be a remote person with no credentials, + // but who should otherwise be able to view it. Show a default image to let + // them know permissions was denied. It may be possible to view the image + // through an authenticated profile visit. + // There won't be many completely unauthorised people seeing this because + // they won't have the photo link, so there's a reasonable chance that the person + // might be able to obtain permission to view it. + + $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `scale` = %d LIMIT 1", + dbesc($photo), + intval($resolution) + ); + + if($r) { + logger('mod_photo: forbidden. ' . \App::$query_string); + $observer = \App::get_observer(); + logger('mod_photo: observer = ' . (($observer) ? $observer['xchan_addr'] : '(not authenticated)')); + $data = file_get_contents('images/nosign.png'); + $mimetype = 'image/png'; + $prvcachecontrol = true; + } + } + } + } + + if(! isset($data)) { + if(isset($resolution)) { + switch($resolution) { + + case 4: + $data = file_get_contents(get_default_profile_photo()); + $mimetype = 'image/png'; + break; + case 5: + $data = file_get_contents(get_default_profile_photo(80)); + $mimetype = 'image/png'; + break; + case 6: + $data = file_get_contents(get_default_profile_photo(48)); + $mimetype = 'image/png'; + break; + default: + killme(); + // NOTREACHED + break; + } + } + } + + if(isset($res) && intval($res) && $res < 500) { + $ph = photo_factory($data, $mimetype); + if($ph->is_valid()) { + $ph->scaleImageSquare($res); + $data = $ph->imageString(); + $mimetype = $ph->getType(); + } + } + + // Writing in cachefile + if (isset($cachefile) && $cachefile != '') + file_put_contents($cachefile, $data); + + if(function_exists('header_remove')) { + header_remove('Pragma'); + header_remove('pragma'); + } + + header("Content-type: " . $mimetype); + + if($prvcachecontrol) { + + // it is a private photo that they have no permission to view. + // tell the browser not to cache it, in case they authenticate + // and subsequently have permission to see it + + header("Cache-Control: no-store, no-cache, must-revalidate"); + + } + else { + // The photo cache default is 1 day to provide a privacy trade-off, + // as somebody reducing photo permissions on a photo that is already + // "in the wild" won't be able to stop the photo from being viewed + // for this amount amount of time once it is in the browser cache. + // The privacy expectations of your site members and their perception + // of privacy where it affects the entire project may be affected. + // This has performance considerations but we highly recommend you + // leave it alone. + + $cache = get_config('system','photo_cache_time'); + if(! $cache) + $cache = (3600 * 24); // 1 day + + header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache) . " GMT"); + header("Cache-Control: max-age=" . $cache); + + } + echo $data; + killme(); + // NOTREACHED + } + +} diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php new file mode 100644 index 000000000..00a577847 --- /dev/null +++ b/Zotlabs/Module/Photos.php @@ -0,0 +1,1384 @@ + 1) { + $nick = argv(1); + + profile_load($a,$nick); + + $channelx = channelx_by_nick($nick); + + if(! $channelx) + return; + + \App::$data['channel'] = $channelx; + + $observer = \App::get_observer(); + \App::$data['observer'] = $observer; + + $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); + + head_set_icon(\App::$data['channel']['xchan_photo_s']); + + \App::$page['htmlhead'] .= "" ; + + } + + return; + } + + + + function post() { + + 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); + + $ph = photo_factory(''); + + $phototypes = $ph->supportedTypes(); + + $can_post = false; + + $page_owner_uid = \App::$data['channel']['channel_id']; + + if(perm_is_allowed($page_owner_uid,get_observer_hash(),'write_storage')) + $can_post = true; + + if(! $can_post) { + notice( t('Permission denied.') . EOL ); + if(is_ajax()) + killme(); + return; + } + + $s = abook_self($page_owner_uid); + + if(! $s) { + notice( t('Page owner information could not be retrieved.') . EOL); + logger('mod_photos: post: unable to locate contact record for page owner. uid=' . $page_owner_uid); + if(is_ajax()) + killme(); + return; + } + + $owner_record = $s[0]; + + $acl = new \Zotlabs\Access\AccessList(\App::$data['channel']); + + 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)) { + notice( t('Album not found.') . EOL); + goaway(z_root() . '/' . $_SESSION['photo_return']); + } + + + /* + * RENAME photo album + */ + + $newalbum = notags(trim($_REQUEST['albumname'])); + if($newalbum != $album) { + + // @fixme - syncronise with DAV or disallow completely + + goaway(z_root() . '/' . $_SESSION['photo_return']); + + // $x = photos_album_rename($page_owner_uid,$album,$newalbum); + // if($x) { + // $newurl = str_replace(bin2hex($album),bin2hex($newalbum),$_SESSION['photo_return']); + // goaway(z_root() . '/' . $newurl); + // } + } + + /* + * DELETE photo album and all its photos + */ + + if($_REQUEST['dropalbum'] == t('Delete Album')) { + + + // This is dangerous because we combined file storage and photos into one interface + // This function will remove all photos from any directory with the same name since + // we have not passed the path value. + + // The correct solution would be to use a full pathname from your storage root for 'album' + // We also need to prevent/block removing the storage root folder. + + $folder_hash = ''; + + $r = q("select * from attach where is_dir = 1 and uid = %d and filename = '%s'", + intval($page_owner_uid), + dbesc($album) + ); + if(! $r) { + 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']; + } + + + + $res = array(); + + // get the list of photos we are about to delete + + if(remote_channel() && (! local_channel())) { + $str = photos_album_get_db_idstr($page_owner_uid,$album,remote_channel()); + } + elseif(local_channel()) { + $str = photos_album_get_db_idstr(local_channel(),$album); + } + else { + $str = null; + } + if(! $str) { + goaway(z_root() . '/' . $_SESSION['photo_return']); + } + + $r = q("select id from item where resource_id in ( $str ) and resource_type = 'photo' and uid = %d " . item_normal(), + intval($page_owner_uid) + ); + if($r) { + foreach($r as $i) { + attach_delete($page_owner_uid, $i['resource_id'], 1 ); + } + } + + // remove the associated photos in case they weren't attached to an item + + q("delete from photo where resource_id in ( $str ) and uid = %d", + intval($page_owner_uid) + ); + + // @FIXME do the same for the linked attach + + if($folder_hash) { + attach_delete($page_owner_uid,$folder_hash, 1); + + $sync = attach_export_data(\App::$data['channel'],$folder_hash, true); + + if($sync) + build_sync_packet($page_owner_uid,array('file' => array($sync))); + } + + } + + goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']); + } + + if((argc() > 2) && (x($_REQUEST,'delete')) && ($_REQUEST['delete'] === t('Delete Photo'))) { + + // same as above but remove single photo + + $ob_hash = get_observer_hash(); + if(! $ob_hash) + goaway(z_root() . '/' . $_SESSION['photo_return']); + + $r = q("SELECT `id`, `resource_id` FROM `photo` WHERE ( xchan = '%s' or `uid` = %d ) AND `resource_id` = '%s' LIMIT 1", + dbesc($ob_hash), + intval(local_channel()), + dbesc(\App::$argv[2]) + ); + + if($r) { + attach_delete($page_owner_uid, $r[0]['resource_id'], 1 ); + $sync = attach_export_data(\App::$data['channel'],$r[0]['resource_id'], true); + + if($sync) + build_sync_packet($page_owner_uid,array('file' => array($sync))); + } + + goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $_SESSION['album_return']); + } + + + if((\App::$argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false)) || (x($_POST,'albname') !== false)) { + + + $desc = ((x($_POST,'desc')) ? notags(trim($_POST['desc'])) : ''); + $rawtags = ((x($_POST,'newtag')) ? notags(trim($_POST['newtag'])) : ''); + $item_id = ((x($_POST,'item_id')) ? intval($_POST['item_id']) : 0); + $albname = ((x($_POST,'albname')) ? notags(trim($_POST['albname'])) : ''); + $is_nsfw = ((x($_POST,'adult')) ? intval($_POST['adult']) : 0); + + $acl->set_from_array($_POST); + $perm = $acl->get(); + + $resource_id = argv(2); + + if(! strlen($albname)) + $albname = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y'); + + + if((x($_POST,'rotate') !== false) && + ( (intval($_POST['rotate']) == 1) || (intval($_POST['rotate']) == 2) )) { + logger('rotate'); + + $r = q("select * from photo where `resource_id` = '%s' and uid = %d and scale = 0 limit 1", + dbesc($resource_id), + intval($page_owner_uid) + ); + if(count($r)) { + $d = (($r[0]['os_storage']) ? @file_get_contents($r[0]['data']) : dbunescbin($r[0]['data'])); + $ph = photo_factory($d, $r[0]['type']); + if($ph->is_valid()) { + $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 ); + $ph->rotate($rotate_deg); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + if(intval($r[0]['os_storage'])) { + @file_put_contents($r[0]['data'],$ph->imageString()); + $data = $r[0]['data']; + $fsize = @filesize($r[0]['data']); + q("update attach set filesize = %d where hash = '%s' and uid = %d limit 1", + intval($fsize), + dbesc($resource_id), + intval($page_owner_uid) + ); + } + else { + $data = $ph->imageString(); + $fsize = strlen($data); + } + + $x = q("update photo set data = '%s', `size` = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 0", + dbescbin($data), + intval($fsize), + intval($height), + intval($width), + dbesc($resource_id), + intval($page_owner_uid) + ); + + if($width > 1024 || $height > 1024) + $ph->scaleImage(1024); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 1", + dbescbin($ph->imageString()), + intval($height), + intval($width), + dbesc($resource_id), + intval($page_owner_uid) + ); + + + if($width > 640 || $height > 640) + $ph->scaleImage(640); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 2", + dbescbin($ph->imageString()), + intval($height), + intval($width), + dbesc($resource_id), + intval($page_owner_uid) + ); + + + if($width > 320 || $height > 320) + $ph->scaleImage(320); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 3", + dbescbin($ph->imageString()), + intval($height), + intval($width), + dbesc($resource_id), + intval($page_owner_uid) + ); + } + } + } + + $p = q("SELECT type, is_nsfw, description, resource_id, scale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY scale DESC", + dbesc($resource_id), + intval($page_owner_uid) + ); + if($p) { + $ext = $phototypes[$p[0]['type']]; + + $r = q("UPDATE `photo` SET `description` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d", + dbesc($desc), + dbesc($perm['allow_cid']), + dbesc($perm['allow_gid']), + dbesc($perm['deny_cid']), + dbesc($perm['deny_gid']), + dbesc($resource_id), + intval($page_owner_uid) + ); + } + + $item_private = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? true : false); + + $old_is_nsfw = $p[0]['is_nsfw']; + if($old_is_nsfw != $is_nsfw) { + $r = q("update photo set is_nsfw = %d where resource_id = '%s' and uid = %d", + intval($is_nsfw), + dbesc($resource_id), + intval($page_owner_uid) + ); + } + + /* Don't make the item visible if the only change was the album name */ + + $visibility = 0; + if($p[0]['description'] !== $desc || strlen($rawtags)) + $visibility = 1; + + if(! $item_id) { + $item_id = photos_create_item(\App::$data['channel'],get_observer_hash(),$p[0],$visibility); + + } + + if($item_id) { + $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($item_id), + intval($page_owner_uid) + ); + + if($r) { + $old_tag = $r[0]['tag']; + $old_inform = $r[0]['inform']; + } + } + + + // make sure the linked item has the same permissions as the photo regardless of any other changes + $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d + where id = %d", + dbesc($perm['allow_cid']), + dbesc($perm['allow_gid']), + dbesc($perm['deny_cid']), + dbesc($perm['deny_gid']), + intval($acl->is_private()), + intval($item_id) + ); + + // make sure the attach has the same permissions as the photo regardless of any other changes + $x = q("update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where hash = '%s' and uid = %d and is_photo = 1", + dbesc($perm['allow_cid']), + dbesc($perm['allow_gid']), + dbesc($perm['deny_cid']), + dbesc($perm['deny_gid']), + dbesc($resource_id), + intval($page_owner_uid) + ); + + + + if(strlen($rawtags)) { + + $str_tags = ''; + $inform = ''; + + // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a mention + + $x = substr($rawtags,0,1); + if($x !== '@' && $x !== '#') + $rawtags = '@' . $rawtags; + + require_once('include/text.php'); + $profile_uid = \App::$profile['profile_uid']; + + $results = linkify_tags($a, $rawtags, (local_channel()) ? local_channel() : $profile_uid); + + $success = $results['success']; + $post_tags = array(); + + foreach($results as $result) { + $success = $result['success']; + if($success['replaced']) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } + } + + $r = q("select * from item where id = %d and uid = %d limit 1", + intval($item_id), + intval($page_owner_uid) + ); + + if($r) { + $r = fetch_post_tags($r,true); + $datarray = $r[0]; + if($post_tags) { + if((! array_key_exists('term',$datarray)) || (! is_array($datarray['term']))) + $datarray['term'] = $post_tags; + else + $datarray['term'] = array_merge($datarray['term'],$post_tags); + } + item_store_update($datarray,$execflag); + } + + } + + goaway(z_root() . '/' . $_SESSION['photo_return']); + return; // NOTREACHED + + $sync = attach_export_data(\App::$data['channel'],$resource_id); + + if($sync) + build_sync_packet($page_owner_uid,array('file' => array($sync))); + + } + + + /** + * default post action - upload a photo + */ + + $channel = \App::$data['channel']; + $observer = \App::$data['observer']; + + $_REQUEST['source'] = 'photos'; + require_once('include/attach.php'); + + if(! local_channel()) { + $_REQUEST['contact_allow'] = expand_acl($channel['channel_allow_cid']); + $_REQUEST['group_allow'] = expand_acl($channel['channel_allow_gid']); + $_REQUEST['contact_deny'] = expand_acl($channel['channel_deny_cid']); + $_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']); + } + + $r = attach_store($channel,get_observer_hash(), '', $_REQUEST); + + if(! $r['success']) { + notice($r['message'] . EOL); + } + + 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'))); + + } + + + + function get() { + + // URLs: + // photos/name + // photos/name/album/xxxxx (xxxxx is album name) + // photos/name/image/xxxxx + + + if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + notice( t('Public access denied.') . EOL); + return; + } + + $unsafe = ((array_key_exists('unsafe',$_REQUEST) && $_REQUEST['unsafe']) ? 1 : 0); + + require_once('include/bbcode.php'); + require_once('include/security.php'); + require_once('include/conversation.php'); + + if(! x(\App::$data,'channel')) { + notice( t('No photos selected') . EOL ); + return; + } + + $ph = photo_factory(''); + $phototypes = $ph->supportedTypes(); + + $_SESSION['photo_return'] = \App::$cmd; + + // + // Parse arguments + // + + $can_comment = perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'post_comments'); + + if(argc() > 3) { + $datatype = argv(2); + $datum = argv(3); + } else { + if(argc() > 2) { + $datatype = argv(2); + $datum = ''; + } + else + $datatype = 'summary'; + } + + if(argc() > 4) + $cmd = argv(4); + else + $cmd = 'view'; + + // + // Setup permissions structures + // + + $can_post = false; + $visitor = 0; + + + $owner_uid = \App::$data['channel']['channel_id']; + $owner_aid = \App::$data['channel']['channel_account_id']; + + $observer = \App::get_observer(); + + $can_post = perm_is_allowed($owner_uid,$observer['xchan_hash'],'write_storage'); + $can_view = perm_is_allowed($owner_uid,$observer['xchan_hash'],'view_storage'); + + if(! $can_view) { + notice( t('Access to this item is restricted.') . EOL); + return; + } + + $sql_extra = permissions_sql($owner_uid); + + $o = ""; + + $o .= "\r\n"; + + // tabs + + $_is_owner = (local_channel() && (local_channel() == $owner_uid)); + $o .= profile_tabs($a,$_is_owner, \App::$data['channel']['channel_address']); + + /** + * Display upload form + */ + + if( $can_post) { + + $uploader = ''; + + $ret = array('post_url' => z_root() . '/photos/' . \App::$data['channel']['channel_address'], + 'addon_text' => $uploader, + 'default_upload' => true); + + call_hooks('photo_upload_form',$ret); + + /* Show space usage */ + + $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", + intval(\App::$data['channel']['channel_account_id']) + ); + + + $limit = service_class_fetch(\App::$data['channel']['channel_id'],'photo_upload_limit'); + if($limit !== false) { + $usage_message = sprintf( t("%1$.2f MB of %2$.2f MB photo storage used."), $r[0]['total'] / 1024000, $limit / 1024000 ); + } + else { + $usage_message = sprintf( t('%1$.2f MB photo storage used.'), $r[0]['total'] / 1024000 ); + } + + if($_is_owner) { + $channel = \App::get_channel(); + + $acl = new \Zotlabs\Access\AccessList($channel); + $channel_acl = $acl->get(); + + $lockstate = (($acl->is_private()) ? 'lock' : 'unlock'); + } + + $aclselect = (($_is_owner) ? populate_acl($channel_acl,false) : ''); + + // this is wrong but is to work around an issue with js_upload wherein it chokes if these variables + // don't exist. They really should be set to a parseable representation of the channel's default permissions + // which can be processed by getSelected() + + if(! $aclselect) { + $aclselect = ''; + } + + $selname = (($datum) ? hex2bin($datum) : ''); + + $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer'])); + + if(! $selname) { + $def_album = get_pconfig(\App::$data['channel']['channel_id'],'system','photo_path'); + if($def_album) { + $selname = filepath_macro($def_album); + $albums['album'][] = array('text' => $selname); + } + } + + $tpl = get_markup_template('photos_upload.tpl'); + $upload_form = replace_macros($tpl,array( + '$pagename' => t('Upload Photos'), + '$sessid' => session_id(), + '$usage' => $usage_message, + '$nickname' => \App::$data['channel']['channel_address'], + '$newalbum_label' => t('Enter an album name'), + '$newalbum_placeholder' => t('or select an existing album (doubleclick)'), + '$visible' => array('visible', t('Create a status post for this upload'), 0,'', array(t('No'), t('Yes')), 'onclick="showHideBodyTextarea();"'), + '$caption' => array('description', t('Caption (optional):')), + '$body' => array('body', t('Description (optional):'),'', 'Description will only appear in the status post'), + '$albums' => $albums['albums'], + '$selname' => $selname, + '$permissions' => t('Permissions'), + '$aclselect' => $aclselect, + '$lockstate' => $lockstate, + '$uploader' => $ret['addon_text'], + '$default' => (($ret['default_upload']) ? true : false), + '$uploadurl' => $ret['post_url'], + '$submit' => t('Submit') + + )); + + } + + // + // dispatch request + // + + /* + * Display a single photo album + */ + + 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 = ''; + } + } + + $album = (($datum) ? hex2bin($datum) : ''); + + + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + + + $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' + AND `scale` <= 4 and photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", + intval($owner_uid), + dbesc($album), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + intval($unsafe) + ); + if(count($r)) { + \App::set_pager_total(count($r)); + \App::set_pager_itemspage(60); + } else { + goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']); + } + + if($_GET['order'] === 'posted') + $order = 'ASC'; + else + $order = 'DESC'; + + + $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.scale, p.description, p.created FROM photo p INNER JOIN + (SELECT resource_id, max(scale) scale FROM photo WHERE uid = %d AND album = '%s' AND scale <= 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.scale = ph.scale) + ORDER BY created $order LIMIT %d OFFSET %d", + intval($owner_uid), + dbesc($album), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + intval($unsafe), + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + //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'])); + + // @fixme - syncronise actions with DAV + + // $edit_tpl = get_markup_template('album_edit.tpl'); + // $album_edit = replace_macros($edit_tpl,array( + // '$nametext' => t('Enter a new album name'), + // '$name_placeholder' => t('or select an existing one (doubleclick)'), + // '$nickname' => \App::$data['channel']['channel_address'], + // '$album' => $album_e, + // '$albums' => $albums['albums'], + // '$hexalbum' => bin2hex($album), + // '$submit' => t('Submit'), + // '$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)); + else + $order = array(t('Show Oldest First'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($album) . '?f=&order=posted'); + + $photos = array(); + if(count($r)) { + $twist = 'rotright'; + foreach($r as $rr) { + + if($twist == 'rotright') + $twist = 'rotleft'; + else + $twist = 'rotright'; + + $ext = $phototypes[$rr['type']]; + + $imgalt_e = $rr['filename']; + $desc_e = $rr['description']; + + $imagelink = (z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id'] + . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '')); + + $photos[] = array( + 'id' => $rr['id'], + 'twist' => ' ' . $twist . rand(2,4), + 'link' => $imagelink, + 'title' => t('View Photo'), + 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext, + 'alt' => $imgalt_e, + 'desc'=> $desc_e, + 'ext' => $ext, + 'hash'=> $rr['resource_id'], + 'unknown' => t('Unknown') + ); + } + } + + if($_REQUEST['aj']) { + if($photos) { + $o = replace_macros(get_markup_template('photosajax.tpl'),array( + '$photos' => $photos, + '$album_id' => bin2hex($album) + )); + } + else { + $o = '
    '; + } + echo $o; + killme(); + } + else { + $o .= ""; + $tpl = get_markup_template('photo_album.tpl'); + $o .= replace_macros($tpl, array( + '$photos' => $photos, + '$album' => $album, + '$album_id' => bin2hex($album), + '$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)), + '$order' => $order, + '$upload_form' => $upload_form, + '$usage' => $usage_message + )); + + } + + if((! $photos) && ($_REQUEST['aj'])) { + $o .= '
    '; + echo $o; + killme(); + } + + // $o .= paginate($a); + + return $o; + + } + + /** + * Display one photo + */ + + if($datatype === 'image') { + + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + + // fetch image, item containing image, then comments + + $ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,`description`,album,filename,`type`,height,width,`size`,scale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' + $sql_extra ORDER BY `scale` ASC ", + intval($owner_uid), + dbesc($datum) + ); + + if(! $ph) { + + /* Check again - this time without specifying permissions */ + + $ph = q("SELECT id FROM photo WHERE uid = %d AND resource_id = '%s' LIMIT 1", + intval($owner_uid), + dbesc($datum) + ); + if($ph) + notice( t('Permission denied. Access to this item may be restricted.') . EOL); + else + notice( t('Photo not available') . EOL ); + return; + } + + + + $prevlink = ''; + $nextlink = ''; + + if($_GET['order'] === 'posted') + $order = 'ASC'; + else + $order = 'DESC'; + + + $prvnxt = q("SELECT `resource_id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0 + $sql_extra ORDER BY `created` $order ", + dbesc($ph[0]['album']), + intval($owner_uid) + ); + + if(count($prvnxt)) { + for($z = 0; $z < count($prvnxt); $z++) { + if($prvnxt[$z]['resource_id'] == $ph[0]['resource_id']) { + $prv = $z - 1; + $nxt = $z + 1; + if($prv < 0) + $prv = count($prvnxt) - 1; + if($nxt >= count($prvnxt)) + $nxt = 0; + break; + } + } + + $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' : ''); + } + + + if(count($ph) == 1) + $hires = $lores = $ph[0]; + if(count($ph) > 1) { + if($ph[1]['scale'] == 2) { + // original is 640 or less, we can display it directly + $hires = $lores = $ph[0]; + } + else { + $hires = $ph[0]; + $lores = $ph[1]; + } + } + + $album_link = z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($ph[0]['album']); + $tools = Null; + $lock = Null; + + if($can_post && ($ph[0]['uid'] == $owner_uid)) { + $tools = array( + 'profile'=>array(z_root() . '/profile_photo/use/'.$ph[0]['resource_id'], t('Use as profile photo')), + 'cover'=>array(z_root() . '/cover_photo/use/'.$ph[0]['resource_id'], t('Use as cover photo')), + ); + } + + // lockstate + $lockstate = ( ( (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) + || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ) + ? array('lock', t('Private Photo')) + : array('unlock', Null)); + + \App::$page['htmlhead'] .= ''; + + if($prevlink) + $prevlink = array($prevlink, t('Previous')); + + $photo = array( + 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], + 'title'=> t('View Full Size'), + 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?f=&_u=' . datetime_convert('','','','ymdhis') + ); + + if($nextlink) + $nextlink = array($nextlink, t('Next')); + + + // 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", + dbesc($datum) + ); + + $map = null; + + if($linked_items) { + + xchan_query($linked_items); + $linked_items = fetch_post_tags($linked_items,true); + + $link_item = $linked_items[0]; + $item_normal = item_normal(); + + $r = q("select * from item where parent_mid = '%s' + $item_normal and uid = %d $sql_extra ", + dbesc($link_item['mid']), + intval($link_item['uid']) + + ); + + if($r) { + xchan_query($r); + $r = fetch_post_tags($r,true); + $r = conv_sort($r,'commented'); + } + + $tags = array(); + if($link_item['term']) { + $cnt = 0; + foreach($link_item['term'] as $t) { + $tags[$cnt] = array(0 => format_term_for_display($t)); + if($can_post && ($ph[0]['uid'] == $owner_uid)) { + $tags[$cnt][1] = 'tagrm/drop/' . $link_item['id'] . '/' . bin2hex($t['term']); //?f=&item=' . $link_item['id']; + $tags[$cnt][2] = t('Remove'); + } + $cnt ++; + } + } + + if((local_channel()) && (local_channel() == $link_item['uid'])) { + q("UPDATE `item` SET item_unseen = 0 WHERE parent = %d and uid = %d and item_unseen = 1", + intval($link_item['parent']), + intval(local_channel()) + ); + } + + if($link_item['coord']) { + $map = generate_map($link_item['coord']); + } + } + + // logger('mod_photo: link_item' . print_r($link_item,true)); + + // FIXME - remove this when we move to conversation module + + $r = $r[0]['children']; + + $edit = null; + if($can_post) { + $album_e = $ph[0]['album']; + $caption_e = $ph[0]['description']; + $aclselect_e = (($_is_owner) ? populate_acl($ph[0]) : ''); + $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer'])); + + $_SESSION['album_return'] = bin2hex($ph[0]['album']); + + $edit = array( + 'edit' => t('Edit photo'), + 'id' => $link_item['id'], + 'rotatecw' => t('Rotate CW (right)'), + 'rotateccw' => t('Rotate CCW (left)'), + 'albums' => $albums['albums'], + 'album' => $album_e, + '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, + '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)) { + + $cmnt_tpl = get_markup_template('comment_item.tpl'); + $tpl = get_markup_template('photo_item.tpl'); + $return_url = \App::$cmd; + + $like_tpl = get_markup_template('like_noshare.tpl'); + + $likebuttons = ''; + + if($can_post || $can_comment) { + $likebuttons = array( + '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') + ); + } + + $comments = ''; + if(! count($r)) { + if($can_post || $can_comment) { + $commentbox = replace_macros($cmnt_tpl,array( + '$return_path' => '', + '$mode' => 'photos', + '$jsreload' => $return_url, + '$type' => 'wall-comment', + '$id' => $link_item['id'], + '$parent' => $link_item['id'], + '$profile_uid' => $owner_uid, + '$mylink' => $observer['xchan_url'], + '$mytitle' => t('This is you'), + '$myphoto' => $observer['xchan_photo_s'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$preview' => t('Preview'), + '$ww' => '', + '$feature_encrypt' => false + )); + } + } + + $alike = array(); + $dlike = array(); + + $like = ''; + $dislike = ''; + + $conv_responses = array( + 'like' => array('title' => t('Likes','title')),'dislike' => array('title' => t('Dislikes','title')), + 'agree' => array('title' => t('Agree','title')),'disagree' => array('title' => t('Disagree','title')), 'abstain' => array('title' => t('Abstain','title')), + 'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title')) + ); + + + + + if($r) { + + foreach($r as $item) { + builtin_activity_puller($item, $conv_responses); + } + + + $like_count = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid']] : ''); + $like_list = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid'] . '-l'] : ''); + if (count($like_list) > MAX_LIKERS) { + $like_list_part = array_slice($like_list, 0, MAX_LIKERS); + array_push($like_list_part, '' . t('View all') . ''); + } else { + $like_list_part = ''; + } + $like_button_label = tt('Like','Likes',$like_count,'noun'); + + //if (feature_enabled($conv->get_profile_owner(),'dislike')) { + $dislike_count = ((x($dlike,$link_item['mid'])) ? $dlike[$link_item['mid']] : ''); + $dislike_list = ((x($dlike,$link_item['mid'])) ? $dlike[$link_item['mid'] . '-l'] : ''); + $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); + if (count($dislike_list) > MAX_LIKERS) { + $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); + array_push($dislike_list_part, '' . t('View all') . ''); + } else { + $dislike_list_part = ''; + } + //} + + + $like = ((isset($alike[$link_item['mid']])) ? format_like($alike[$link_item['mid']],$alike[$link_item['mid'] . '-l'],'like',$link_item['mid']) : ''); + $dislike = ((isset($dlike[$link_item['mid']])) ? format_like($dlike[$link_item['mid']],$dlike[$link_item['mid'] . '-l'],'dislike',$link_item['mid']) : ''); + + // display comments + + foreach($r as $item) { + $comment = ''; + $template = $tpl; + $sparkle = ''; + + if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) && ($item['id'] != $item['parent'])) + continue; + + $redirect_url = z_root() . '/redir/' . $item['cid'] ; + + + $profile_url = zid($item['author']['xchan_url']); + $sparkle = ''; + + + $profile_name = $item['author']['xchan_name']; + $profile_avatar = $item['author']['xchan_photo_m']; + + $profile_link = $profile_url; + + $drop = ''; + + if($observer['xchan_hash'] === $item['author_xchan'] || $observer['xchan_hash'] === $item['owner_xchan']) + $drop = replace_macros(get_markup_template('photo_drop.tpl'), array('$id' => $item['id'], '$delete' => t('Delete'))); + + + $name_e = $profile_name; + $title_e = $item['title']; + unobscure($item); + $body_e = prepare_text($item['body'],$item['mimetype']); + + $comments .= replace_macros($template,array( + '$id' => $item['id'], + '$mode' => 'photos', + '$profile_url' => $profile_link, + '$name' => $name_e, + '$thumb' => $profile_avatar, + '$sparkle' => $sparkle, + '$title' => $title_e, + '$body' => $body_e, + '$ago' => relative_date($item['created']), + '$indent' => (($item['parent'] != $item['id']) ? ' comment' : ''), + '$drop' => $drop, + '$comment' => $comment + )); + + } + + if($can_post || $can_comment) { + $commentbox = replace_macros($cmnt_tpl,array( + '$return_path' => '', + '$jsreload' => $return_url, + '$type' => 'wall-comment', + '$id' => $link_item['id'], + '$parent' => $link_item['id'], + '$profile_uid' => $owner_uid, + '$mylink' => $observer['xchan_url'], + '$mytitle' => t('This is you'), + '$myphoto' => $observer['xchan_photo_s'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$ww' => '' + )); + } + + } + $paginate = paginate($a); + } + + $album_e = array($album_link,$ph[0]['album']); + $like_e = $like; + $dislike_e = $dislike; + + + $response_verbs = array('like'); + if(feature_enabled($owner_uid,'dislike')) + $response_verbs[] = 'dislike'; + + + $responses = get_responses($conv_responses,$response_verbs,'',$link_item); + + $photo_tpl = get_markup_template('photo_view.tpl'); + $o .= replace_macros($photo_tpl, array( + '$id' => $ph[0]['id'], + '$album' => $album_e, + '$tools' => $tools, + '$lock' => $lockstate[1], + '$photo' => $photo, + '$prevlink' => $prevlink, + '$nextlink' => $nextlink, + '$desc' => $ph[0]['description'], + '$filename' => $ph[0]['filename'], + '$unknown' => t('Unknown'), + '$tag_hdr' => t('In This Photo:'), + '$tags' => $tags, + 'responses' => $responses, + '$edit' => $edit, + '$map' => $map, + '$map_text' => t('Map'), + '$likebuttons' => $likebuttons, + '$like' => $like_e, + '$dislike' => $dislike_e, + '$like_count' => $like_count, + '$like_list' => $like_list, + '$like_list_part' => $like_list_part, + '$like_button_label' => $like_button_label, + '$like_modal_title' => t('Likes','noun'), + '$dislike_modal_title' => t('Dislikes','noun'), + '$dislike_count' => $dislike_count, //((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''), + '$dislike_list' => $dislike_list, //((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''), + '$dislike_list_part' => $dislike_list_part, //((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''), + '$dislike_button_label' => $dislike_button_label, //((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''), + '$modal_dismiss' => t('Close'), + '$comments' => $comments, + '$commentbox' => $commentbox, + '$paginate' => $paginate, + )); + + \App::$data['photo_html'] = $o; + + return $o; + } + + // Default - show recent photos with upload link (if applicable) + //$o = ''; + + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + + + $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' + and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", + intval(\App::$data['channel']['channel_id']), + dbesc('Contact Photos'), + dbesc( t('Contact Photos')), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + intval($unsafe) + ); + if(count($r)) { + \App::set_pager_total(count($r)); + \App::set_pager_itemspage(60); + } + + $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.album, p.scale, p.created FROM photo p INNER JOIN + (SELECT resource_id, max(scale) scale FROM photo + WHERE uid=%d AND album != '%s' AND album != '%s' + 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.scale = ph.scale) ORDER by p.created DESC LIMIT %d OFFSET %d", + intval(\App::$data['channel']['channel_id']), + dbesc('Contact Photos'), + dbesc( t('Contact Photos')), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + intval($unsafe), + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + + + $photos = array(); + if(count($r)) { + $twist = 'rotright'; + foreach($r as $rr) { + if($twist == 'rotright') + $twist = 'rotleft'; + else + $twist = 'rotright'; + $ext = $phototypes[$rr['type']]; + + 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']; + } + + $photos[] = array( + 'id' => $rr['id'], + 'twist' => ' ' . $twist . rand(2,4), + 'link' => z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id'], + 'title' => t('View Photo'), + 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . ((($rr['scale']) == 6) ? 4 : $rr['scale']) . '.' . $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'), + ), + + ); + } + } + + if($_REQUEST['aj']) { + if($photos) { + $o = replace_macros(get_markup_template('photosajax.tpl'),array( + '$photos' => $photos, + '$album_id' => bin2hex(t('Recent Photos')) + )); + } + else { + $o = '
    '; + } + echo $o; + killme(); + } + else { + $o .= ""; + $tpl = get_markup_template('photos_recent.tpl'); + $o .= replace_macros($tpl, array( + '$title' => t('Recent Photos'), + '$album_id' => bin2hex(t('Recent Photos')), + '$can_post' => $can_post, + '$upload' => array(t('Upload'), z_root().'/photos/'.\App::$data['channel']['channel_address'].'/upload'), + '$photos' => $photos, + '$upload_form' => $upload_form, + '$usage' => $usage_message + )); + + } + + if((! $photos) && ($_REQUEST['aj'])) { + $o .= '
    '; + echo $o; + killme(); + } + + // paginate($a); + return $o; + } + + +} diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php new file mode 100644 index 000000000..bea4a08b7 --- /dev/null +++ b/Zotlabs/Module/Ping.php @@ -0,0 +1,497 @@ + $m); + } + unset($_SESSION['sysmsg']); + } + if(x($_SESSION, 'sysmsg_info')){ + foreach ($_SESSION['sysmsg_info'] as $m){ + $result['info'][] = array('message' => $m); + } + unset($_SESSION['sysmsg_info']); + } + if(! ($vnotify & VNOTIFY_INFO)) + $result['info'] = array(); + if(! ($vnotify & VNOTIFY_ALERT)) + $result['notice'] = array(); + + + if(\App::$install) { + echo json_encode($result); + killme(); + } + + /** + * Update chat presence indication (if applicable) + */ + + if(get_observer_hash() && (! $result['invalid'])) { + $r = q("select cp_id, cp_room from chatpresence where cp_xchan = '%s' and cp_client = '%s' and cp_room = 0 limit 1", + dbesc(get_observer_hash()), + dbesc($_SERVER['REMOTE_ADDR']) + ); + $basic_presence = false; + if($r) { + $basic_presence = true; + q("update chatpresence set cp_last = '%s' where cp_id = %d", + dbesc(datetime_convert()), + intval($r[0]['cp_id']) + ); + } + if(! $basic_presence) { + q("insert into chatpresence ( cp_xchan, cp_last, cp_status, cp_client) + values( '%s', '%s', '%s', '%s' ) ", + dbesc(get_observer_hash()), + dbesc(datetime_convert()), + dbesc('online'), + dbesc($_SERVER['REMOTE_ADDR']) + ); + } + } + + /** + * Chatpresence continued... if somebody hasn't pinged recently, they've most likely left the page + * and shouldn't count as online anymore. We allow an expection for bots. + */ + + q("delete from chatpresence where cp_last < %s - INTERVAL %s and cp_client != 'auto' ", + db_utcnow(), db_quoteinterval('3 MINUTE') + ); + + if((! local_channel()) || ($result['invalid'])) { + echo json_encode($result); + killme(); + } + + /** + * Everything following is only permitted under the context of a locally authenticated site member. + */ + + + /** + * Handle "mark all xyz notifications read" requests. + */ + + // mark all items read + if(x($_REQUEST, 'markRead') && local_channel()) { + switch($_REQUEST['markRead']) { + case 'network': + $r = q("update item set item_unseen = 0 where item_unseen = 1 and uid = %d", + intval(local_channel()) + ); + break; + case 'home': + $r = q("update item set item_unseen = 0 where item_unseen = 1 and item_wall = 1 and uid = %d", + intval(local_channel()) + ); + break; + case 'messages': + $r = q("update mail set mail_seen = 1 where mail_seen = 0 and channel_id = %d ", + intval(local_channel()) + ); + break; + case 'all_events': + $r = q("update event set `ignore` = 1 where `ignore` = 0 and uid = %d AND start < '%s' AND start > '%s' ", + intval(local_channel()), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) + ); + break; + case 'notify': + $r = q("update notify set seen = 1 where uid = %d", + intval(local_channel()) + ); + break; + default: + break; + } + } + + if(x($_REQUEST, 'markItemRead') && local_channel()) { + $r = q("update item set item_unseen = 0 where parent = %d and uid = %d", + intval($_REQUEST['markItemRead']), + intval(local_channel()) + ); + } + + + + /** + * URL ping/something will return detail for "something", e.g. a json list with which to populate a notification + * dropdown menu. + */ + + if(argc() > 1 && argv(1) === 'notify') { + $t = q("select count(*) as total from notify where uid = %d and seen = 0", + intval(local_channel()) + ); + if($t && intval($t[0]['total']) > 49) { + $z = q("select * from notify where uid = %d + and seen = 0 order by date desc limit 50", + intval(local_channel()) + ); + } + else { + $z1 = q("select * from notify where uid = %d + and seen = 0 order by date desc limit 50", + intval(local_channel()) + ); + $z2 = q("select * from notify where uid = %d + and seen = 1 order by date desc limit %d", + intval(local_channel()), + intval(50 - intval($t[0]['total'])) + ); + $z = array_merge($z1,$z2); + } + + if(count($z)) { + foreach($z as $zz) { + $notifs[] = array( + 'notify_link' => z_root() . '/notify/view/' . $zz['id'], + 'name' => $zz['name'], + 'url' => $zz['url'], + 'photo' => $zz['photo'], + 'when' => relative_date($zz['date']), + 'hclass' => (($zz['seen']) ? 'notify-seen' : 'notify-unseen'), + 'message' => strip_tags(bbcode($zz['msg'])) + ); + } + } + + echo json_encode(array('notify' => $notifs)); + killme(); + } + + if(argc() > 1 && argv(1) === 'messages') { + $channel = \App::get_channel(); + $t = q("select mail.*, xchan.* from mail left join xchan on xchan_hash = from_xchan + where channel_id = %d and mail_seen = 0 and mail_deleted = 0 + and from_xchan != '%s' order by created desc limit 50", + intval(local_channel()), + dbesc($channel['channel_hash']) + ); + + if($t) { + foreach($t as $zz) { + $notifs[] = array( + 'notify_link' => z_root() . '/mail/' . $zz['id'], + 'name' => $zz['xchan_name'], + 'url' => $zz['xchan_url'], + 'photo' => $zz['xchan_photo_s'], + 'when' => relative_date($zz['created']), + 'hclass' => (intval($zz['mail_seen']) ? 'notify-seen' : 'notify-unseen'), + 'message' => t('sent you a private message'), + ); + } + } + + echo json_encode(array('notify' => $notifs)); + killme(); + } + + if(argc() > 1 && (argv(1) === 'network' || argv(1) === 'home')) { + $result = array(); + + $r = q("SELECT * FROM item + WHERE item_unseen = 1 and uid = %d $item_normal + and author_xchan != '%s' ORDER BY created DESC limit 300", + intval(local_channel()), + dbesc($ob_hash) + ); + + if($r) { + xchan_query($r); + foreach($r as $item) { + if((argv(1) === 'home') && (! intval($item['item_wall']))) + continue; + $result[] = format_notification($item); + } + } + // logger('ping (network||home): ' . print_r($result, true), LOGGER_DATA); + echo json_encode(array('notify' => $result)); + killme(); + } + + if(argc() > 1 && (argv(1) === 'intros')) { + $result = array(); + + $r = q("SELECT * FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ORDER BY abook_created DESC LIMIT 50", + intval(local_channel()) + ); + + if($r) { + foreach($r as $rr) { + $result[] = array( + 'notify_link' => z_root() . '/connections/ifpending', + 'name' => $rr['xchan_name'], + 'url' => $rr['xchan_url'], + 'photo' => $rr['xchan_photo_s'], + 'when' => relative_date($rr['abook_created']), + 'hclass' => ('notify-unseen'), + 'message' => t('added your channel') + ); + } + } + logger('ping (intros): ' . print_r($result, true), LOGGER_DATA); + echo json_encode(array('notify' => $result)); + killme(); + } + + if(argc() > 1 && (argv(1) === 'all_events')) { + $bd_format = t('g A l F d') ; // 8 AM Friday January 18 + + $result = array(); + + $r = q("SELECT * FROM event left join xchan on event_xchan = xchan_hash + WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 + and type in ( 'event', 'birthday' ) + ORDER BY `start` DESC LIMIT 1000", + intval(local_channel()), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) + ); + + if($r) { + foreach($r as $rr) { + if($rr['adjust']) + $md = datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'Y/m'); + else + $md = datetime_convert('UTC', 'UTC', $rr['start'], 'Y/m'); + + $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start']); + $today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false); + + $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); + + $result[] = array( + 'notify_link' => z_root() . '/events', // FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'], + 'name' => $rr['xchan_name'], + 'url' => $rr['xchan_url'], + 'photo' => $rr['xchan_photo_s'], + 'when' => $when, + 'hclass' => ('notify-unseen'), + 'message' => t('posted an event') + ); + } + } + logger('ping (all_events): ' . print_r($result, true), LOGGER_DATA); + echo json_encode(array('notify' => $result)); + killme(); + } + + + + /** + * Normal ping - just the counts, no detail + */ + + if($vnotify & VNOTIFY_SYSTEM) { + $t = q("select count(*) as total from notify where uid = %d and seen = 0", + intval(local_channel()) + ); + if($t) + $result['notify'] = intval($t[0]['total']); + } + + $t1 = dba_timer(); + + if($vnotify & (VNOTIFY_NETWORK|VNOTIFY_CHANNEL)) { + $r = q("SELECT id, item_wall FROM item + WHERE item_unseen = 1 and uid = %d + $item_normal + and author_xchan != '%s'", + intval(local_channel()), + dbesc($ob_hash) + ); + + if($r) { + $arr = array('items' => $r); + call_hooks('network_ping', $arr); + + foreach ($r as $it) { + if(intval($it['item_wall'])) + $result['home'] ++; + else + $result['network'] ++; + } + } + } + if(! ($vnotify & VNOTIFY_NETWORK)) + $result['network'] = 0; + if(! ($vnotify & VNOTIFY_CHANNEL)) + $result['home'] = 0; + + + $t2 = dba_timer(); + + if($vnotify & VNOTIFY_INTRO) { + $intr = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ", + intval(local_channel()) + ); + + $t3 = dba_timer(); + + if($intr) + $result['intros'] = intval($intr[0]['total']); + } + + $t4 = dba_timer(); + $channel = \App::get_channel(); + + if($vnotify & VNOTIFY_MAIL) { + $mails = q("SELECT count(id) as total from mail + WHERE channel_id = %d AND mail_seen = 0 and from_xchan != '%s' ", + intval(local_channel()), + dbesc($channel['channel_hash']) + ); + if($mails) + $result['mail'] = intval($mails[0]['total']); + } + + if($vnotify & VNOTIFY_REGISTER) { + if (\App::$config['system']['register_policy'] == REGISTER_APPROVE && is_site_admin()) { + $regs = q("SELECT count(account_id) as total from account where (account_flags & %d) > 0", + intval(ACCOUNT_PENDING) + ); + if($regs) + $result['register'] = intval($regs[0]['total']); + } + } + + $t5 = dba_timer(); + + if($vnotify & (VNOTIFY_EVENT|VNOTIFY_EVENTTODAY|VNOTIFY_BIRTHDAY)) { + $events = q("SELECT type, start, adjust FROM `event` + WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 + and type in ( 'event', 'birthday' ) + ORDER BY `start` ASC ", + intval(local_channel()), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), + dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) + ); + + if($events) { + $result['all_events'] = count($events); + + if($result['all_events']) { + $str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d'); + foreach($events as $x) { + $bd = false; + if($x['type'] === 'birthday') { + $result['birthdays'] ++; + $bd = true; + } + else { + $result['events'] ++; + } + if(datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['start'], 'Y-m-d') === $str_now) { + $result['all_events_today'] ++; + if($bd) + $result['birthdays_today'] ++; + else + $result['events_today'] ++; + } + } + } + } + } + if(! ($vnotify & VNOTIFY_EVENT)) + $result['all_events'] = $result['events'] = 0; + if(! ($vnotify & VNOTIFY_EVENTTODAY)) + $result['all_events_today'] = $result['events_today'] = 0; + if(! ($vnotify & VNOTIFY_BIRTHDAY)) + $result['birthdays'] = 0; + + + $x = json_encode($result); + + $t6 = dba_timer(); + + // logger('ping timer: ' . sprintf('%01.4f %01.4f %01.4f %01.4f %01.4f %01.4f',$t6 - $t5, $t5 - $t4, $t4 - $t3, $t3 - $t2, $t2 - $t1, $t1 - $t0)); + + echo $x; + killme(); + } + +} diff --git a/Zotlabs/Module/Poco.php b/Zotlabs/Module/Poco.php new file mode 100644 index 000000000..85c9348c0 --- /dev/null +++ b/Zotlabs/Module/Poco.php @@ -0,0 +1,13 @@ +' : $channel['channel_allow_cid']); + $allow_gid = (($item_private) ? '' : $channel['channel_allow_gid']); + $deny_cid = (($item_private) ? '' : $channel['channel_deny_cid']); + $deny_gid = (($item_private) ? '' : $channel['channel_deny_gid']); + } + + + $arr = array(); + + $arr['item_wall'] = 1; + $arr['owner_xchan'] = (($parent_item) ? $parent_item['owner_xchan'] : $channel['channel_hash']); + $arr['parent_mid'] = (($parent_mid) ? $parent_mid : $mid); + $arr['title'] = ''; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['verb'] = $activity; + $arr['item_private'] = $item_private; + $arr['obj_type'] = ACTIVITY_OBJ_PERSON; + $arr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t($verbs[$verb][0]) . ' ' . '[zrl=' . $target['xchan_url'] . ']' . $target['xchan_name'] . '[/zrl]'; + + $obj = array( + 'type' => ACTIVITY_OBJ_PERSON, + 'title' => $target['xchan_name'], + 'id' => $target['xchan_hash'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $target['xchan_url']), + array('rel' => 'photo', 'type' => $target['xchan_photo_mimetype'], 'href' => $target['xchan_photo_l']) + ), + ); + + $arr['object'] = json_encode($obj); + + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; + $arr['item_unseen'] = 1; + if(! $parent_item) + $item['item_thread_top'] = 1; + + + post_activity_item($arr); + + return; + } + + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + $name = ''; + $id = ''; + + if(intval($_REQUEST['c'])) { + $r = q("select abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash + where abook_id = %d and abook_channel = %d limit 1", + intval($_REQUEST['c']), + intval(local_channel()) + ); + if($r) { + $name = $r[0]['xchan_name']; + $id = $r[0]['abook_id']; + } + } + + $parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : '0'); + + $verbs = get_poke_verbs(); + + $shortlist = array(); + foreach($verbs as $k => $v) + if($v[1] !== 'NOTRANSLATION') + $shortlist[] = array($k,$v[1]); + + + $poke_basic = get_config('system','poke_basic'); + if($poke_basic) { + $title = t('Poke'); + $desc = t('Poke somebody'); + } + else { + $title = t('Poke/Prod'); + $desc = t('Poke, prod or do other things to somebody'); + } + + $o = replace_macros(get_markup_template('poke_content.tpl'),array( + '$title' => $title, + '$poke_basic' => $poke_basic, + '$desc' => $desc, + '$clabel' => t('Recipient'), + '$choice' => t('Choose what you wish to do to recipient'), + '$verbs' => $shortlist, + '$parent' => $parent, + '$prv_desc' => t('Make this post private'), + '$private' => array('private', t('Make this post private'), false, ''), + '$submit' => t('Submit'), + '$name' => $name, + '$id' => $id + )); + + return $o; + + } +} diff --git a/Zotlabs/Module/Post.php b/Zotlabs/Module/Post.php new file mode 100644 index 000000000..af231ab50 --- /dev/null +++ b/Zotlabs/Module/Post.php @@ -0,0 +1,36 @@ + $r[0]['xlink_rating'],'rating_text' => $r[0]['xlink_rating_text'])); + killme(); + } + + function post() { + + if(! local_channel()) + return; + + $channel = \App::get_channel(); + + $target = trim($_REQUEST['target']); + if(! $target) + return; + + if($target === $channel['channel_hash']) + return; + + $rating = intval($_POST['rating']); + if($rating < (-10)) + $rating = (-10); + if($rating > 10) + $rating = 10; + + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); + + $signed = $target . '.' . $rating . '.' . $rating_text; + + $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); + + + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc($target) + ); + if($z) { + $record = $z[0]['xlink_id']; + $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s' + where xlink_id = %d", + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()), + intval($record) + ); + } + else { + $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", + dbesc($channel['channel_hash']), + dbesc($target), + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()) + ); + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc($orig_record[0]['abook_xchan']) + ); + if($z) + $record = $z[0]['xlink_id']; + } + if($record) { + proc_run('php','include/ratenotif.php','rating',$record); + } + + json_return_and_die(array('result' => true));; + } + + + + + + + + + + + + +} diff --git a/Zotlabs/Module/Pretheme.php b/Zotlabs/Module/Pretheme.php new file mode 100644 index 000000000..120fd5359 --- /dev/null +++ b/Zotlabs/Module/Pretheme.php @@ -0,0 +1,28 @@ + get_theme_screenshot($theme), 'desc' => $desc, 'version' => $version, 'credits' => $credits)); + } + killme(); + } + +} diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php new file mode 100644 index 000000000..79abe9819 --- /dev/null +++ b/Zotlabs/Module/Probe.php @@ -0,0 +1,47 @@ +Probe Diagnostic'; + + $o .= '
    '; + $o .= 'Lookup address: '; + $o .= '
    '; + + $o .= '

    '; + + if(x($_GET,'addr')) { + $channel = \App::get_channel(); + $addr = trim($_GET['addr']); + $do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false); + $res = zot_finger($addr,$channel,false); + $o .= '
    ';
    +			if($res['success'])
    +				$j = json_decode($res['body'],true);
    +			else {
    +				$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
    +				$o .= "https connection failed. Trying again with auto failover to http.\r\n\r\n";
    +				$res = zot_finger($addr,$channel,true);
    +				if($res['success'])
    +					$j = json_decode($res['body'],true);
    +				else
    +					$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
    +	
    +			}
    +			if($do_import && $j)
    +				$x = import_xchan($j);
    +			if($j && $j['permissions'] && $j['permissions']['iv'])
    +				$j['permissions'] = json_decode(crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']),true);
    +			$o .= str_replace("\n",'
    ',print_r($j,true)); + $o .= '
    '; + } + return $o; + } + +} diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php new file mode 100644 index 000000000..04a64fe76 --- /dev/null +++ b/Zotlabs/Module/Profile.php @@ -0,0 +1,90 @@ + 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $profile = ''; + $channel = \App::get_channel(); + + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", + intval($profile), + intval(local_channel()) + ); + if(! $r) + $profile = ''; + $profile = $r[0]['profile_guid']; + } + + \App::$page['htmlhead'] .= '' . "\r\n" ; + + if(! $profile) { + $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", + dbesc(argv(1)) + ); + if($x) { + \App::$profile = $x[0]; + } + } + + profile_load($a,$which,$profile); + + + } + + function get() { + + if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { + return login(); + } + + $groups = array(); + + $tab = 'profile'; + $o = ''; + + if(! (perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(), 'view_profile'))) { + notice( t('Permission denied.') . EOL); + return; + } + + + $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false); + + if(\App::$profile['hidewall'] && (! $is_owner) && (! remote_channel())) { + notice( t('Permission denied.') . EOL); + return; + } + + $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']); + + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + + $o .= advanced_profile($a); + call_hooks('profile_advanced',$o); + return $o; + + } + +} diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php new file mode 100644 index 000000000..8f879503c --- /dev/null +++ b/Zotlabs/Module/Profile_photo.php @@ -0,0 +1,436 @@ +is_valid()) { + + $im->cropImage(300,$srcX,$srcY,$srcW,$srcH); + + $aid = get_account_id(); + + $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], + 'filename' => $base_image['filename'], 'album' => t('Profile Photos')); + + $p['scale'] = 4; + $p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL); + + $r1 = $im->save($p); + + $im->scaleImage(80); + $p['scale'] = 5; + + $r2 = $im->save($p); + + $im->scaleImage(48); + $p['scale'] = 6; + + $r3 = $im->save($p); + + if($r1 === false || $r2 === false || $r3 === false) { + // if one failed, delete them all so we can start over. + notice( t('Image resize failed.') . EOL ); + $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 4 ", + dbesc($base_image['resource_id']), + local_channel() + ); + return; + } + + $channel = \App::get_channel(); + + // If setting for the default profile, unset the profile photo flag from any other photos I own + + if($is_default_profile) { + $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d + AND resource_id != '%s' AND `uid` = %d", + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + dbesc($base_image['resource_id']), + intval(local_channel()) + ); + + send_profile_photo_activity($channel,$base_image,$profile); + + } + else { + $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d", + dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-4'), + dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-5'), + intval($_REQUEST['profile']), + intval(local_channel()) + ); + } + + profiles_build_sync(local_channel()); + + // We'll set the updated profile-photo timestamp even if it isn't the default profile, + // so that browsers will do a cache update unconditionally + + + $r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s' + where xchan_hash = '%s'", + dbesc($im->getType()), + dbesc(datetime_convert()), + dbesc($channel['xchan_hash']) + ); + + info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); + + // Update directory in background + proc_run('php',"include/directory.php",$channel['channel_id']); + + // Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures' + + profile_photo_set_profile_perms($_REQUEST['profile']); + + + + } + else + notice( t('Unable to process image') . EOL); + } + + goaway(z_root() . '/profiles'); + return; // NOTREACHED + } + + + + $hash = photo_new_resource(); + $smallest = 0; + + require_once('include/attach.php'); + + $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash)); + + logger('attach_store: ' . print_r($res,true)); + + if($res && intval($res['data']['is_photo'])) { + $i = q("select * from photo where resource_id = '%s' and uid = %d order by scale", + dbesc($hash), + intval(local_channel()) + ); + + if(! $i) { + notice( t('Image upload failed.') . EOL ); + return; + } + $os_storage = false; + + foreach($i as $ii) { + if(intval($ii['scale']) < 2) { + $smallest = intval($ii['scale']); + $os_storage = intval($ii['os_storage']); + $imagedata = $ii['data']; + $filetype = $ii['type']; + } + } + } + + $imagedata = (($os_storage) ? @file_get_contents($imagedata) : $imagedata); + $ph = photo_factory($imagedata, $filetype); + + if(! $ph->is_valid()) { + notice( t('Unable to process image.') . EOL ); + return; + } + + return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest); + + } + + + /* @brief Generate content of profile-photo view + * + * @param $a Current application + * @return void + * + */ + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL ); + return; + } + + $channel = \App::get_channel(); + + $newuser = false; + + if(argc() == 2 && argv(1) === 'new') + $newuser = true; + + if(argv(1) === 'use') { + if (argc() < 3) { + notice( t('Permission denied.') . EOL ); + return; + }; + + // check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); + + $resource_id = argv(2); + + + $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC", + intval(local_channel()), + dbesc($resource_id) + ); + if(! $r) { + notice( t('Photo not available.') . EOL ); + return; + } + $havescale = false; + foreach($r as $rr) { + if($rr['scale'] == 5) + $havescale = true; + } + + // set an already loaded photo as profile photo + + if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) { + // unset any existing profile photos + $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + intval(local_channel())); + + $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", + intval(PHOTO_PROFILE), + intval(local_channel()), + dbesc($resource_id) + ); + + $r = q("UPDATE xchan set xchan_photo_date = '%s' + where xchan_hash = '%s'", + dbesc(datetime_convert()), + dbesc($channel['xchan_hash']) + ); + + profile_photo_set_profile_perms(); //Reset default photo permissions to public + proc_run('php','include/directory.php',local_channel()); + goaway(z_root() . '/profiles'); + } + + $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + intval($r[0]['id']), + intval(local_channel()) + + ); + if(! $r) { + notice( t('Photo not available.') . EOL ); + return; + } + + if(intval($r[0]['os_storage'])) + $data = @file_get_contents($r[0]['data']); + else + $data = dbunescbin($r[0]['data']); + + $ph = photo_factory($data, $r[0]['type']); + $smallest = 0; + if($ph->is_valid()) { + // go ahead as if we have just uploaded a new photo to crop + $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale", + dbesc($r[0]['resource_id']), + intval(local_channel()) + ); + + if($i) { + $hash = $i[0]['resource_id']; + foreach($i as $ii) { + if(intval($ii['scale']) < 2) { + $smallest = intval($ii['scale']); + } + } + } + } + + profile_photo_crop_ui_head($a, $ph, $hash, $smallest); + } + + $profiles = q("select id, profile_name as name, is_default from profile where uid = %d", + intval(local_channel()) + ); + + if(! x(\App::$data,'imagecrop')) { + + $tpl = get_markup_template('profile_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 Profile Photo'), + '$submit' => t('Upload'), + '$profiles' => $profiles, + '$single' => ((count($profiles) == 1) ? true : false), + '$profile0' => $profiles[0], + '$form_security_token' => get_form_security_token("profile_photo"), + // FIXME - yuk + '$select' => sprintf('%s %s', t('or'), ($newuser) ? '' . t('skip this step') . '' : '' . t('select a photo from your photo albums') . '') + )); + + call_hooks('profile_photo_content_end', $o); + + return $o; + } + else { + $filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution']; + $resolution = \App::$data['imagecrop_resolution']; + $tpl = get_markup_template("cropbody.tpl"); + $o .= replace_macros($tpl,array( + '$filename' => $filename, + '$profile' => intval($_REQUEST['profile']), + '$resource' => \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'], + '$image_url' => z_root() . '/photo/' . $filename, + '$title' => t('Crop Image'), + '$desc' => t('Please adjust the image cropping for optimum viewing.'), + '$form_security_token' => get_form_security_token("profile_photo"), + '$done' => t('Done Editing') + )); + return $o; + } + + return; // NOTREACHED + } + + /* @brief Generate the UI for photo-cropping + * + * @param $a Current application + * @param $ph Photo-Factory + * @return void + * + */ + + + + function profile_photo_crop_ui_head(&$a, $ph, $hash, $smallest){ + + $max_length = get_config('system','max_image_length'); + if(! $max_length) + $max_length = MAX_IMAGE_LENGTH; + if($max_length > 0) + $ph->scaleImage($max_length); + + $width = $ph->getWidth(); + $height = $ph->getHeight(); + + if($width < 500 || $height < 500) { + $ph->scaleImageUp(400); + $width = $ph->getWidth(); + $height = $ph->getHeight(); + } + + + \App::$data['imagecrop'] = $hash; + \App::$data['imagecrop_resolution'] = $smallest; + \App::$page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array()); + return; + } + + +} diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php new file mode 100644 index 000000000..30ec337f8 --- /dev/null +++ b/Zotlabs/Module/Profiles.php @@ -0,0 +1,795 @@ + 2) && (argv(1) === "drop") && intval(argv(2))) { + $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d AND `is_default` = 0 LIMIT 1", + intval(argv(2)), + intval(local_channel()) + ); + if(! count($r)) { + notice( t('Profile not found.') . EOL); + goaway(z_root() . '/profiles'); + return; // NOTREACHED + } + $profile_guid = $r['profile_guid']; + + check_form_security_token_redirectOnErr('/profiles', 'profile_drop', 't'); + + // move every contact using this profile as their default to the user default + + $r = q("UPDATE abook SET abook_profile = (SELECT profile_guid AS FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1) WHERE abook_profile = '%s' AND abook_channel = %d ", + intval(local_channel()), + dbesc($profile_guid), + intval(local_channel()) + ); + $r = q("DELETE FROM `profile` WHERE `id` = %d AND `uid` = %d", + intval(argv(2)), + intval(local_channel()) + ); + if($r) + info( t('Profile deleted.') . EOL); + + // @fixme this is a much more complicated sync - add any changed abook entries and + // also add deleted flag to profile structure + // profiles_build_sync is just here as a placeholder - it doesn't work at all here + + // profiles_build_sync(local_channel()); + + goaway(z_root() . '/profiles'); + return; // NOTREACHED + } + + + + + + if((argc() > 1) && (argv(1) === 'new')) { + + // check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't'); + + $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d", + intval(local_channel())); + $num_profiles = count($r0); + + $name = t('Profile-') . ($num_profiles + 1); + + $r1 = q("SELECT `name`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1", + intval(local_channel())); + + $r2 = q("INSERT INTO `profile` (`aid`, `uid` , `profile_guid`, `profile_name` , `name`, `photo`, `thumb`) + VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s' )", + intval(get_account_id()), + intval(local_channel()), + dbesc(random_string()), + dbesc($name), + dbesc($r1[0]['name']), + dbesc($r1[0]['photo']), + dbesc($r1[0]['thumb']) + ); + + $r3 = q("SELECT `id` FROM `profile` WHERE `uid` = %d AND `profile_name` = '%s' LIMIT 1", + intval(local_channel()), + dbesc($name) + ); + + info( t('New profile created.') . EOL); + if(count($r3) == 1) + goaway(z_root() . '/profiles/' . $r3[0]['id']); + + goaway(z_root() . '/profiles'); + } + + if((argc() > 2) && (argv(1) === 'clone')) { + + check_form_security_token_redirectOnErr('/profiles', 'profile_clone', 't'); + + $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d", + intval(local_channel())); + $num_profiles = count($r0); + + $name = t('Profile-') . ($num_profiles + 1); + $r1 = q("SELECT * FROM `profile` WHERE `uid` = %d AND `id` = %d LIMIT 1", + intval(local_channel()), + intval(\App::$argv[2]) + ); + if(! count($r1)) { + notice( t('Profile unavailable to clone.') . EOL); + \App::$error = 404; + return; + } + unset($r1[0]['id']); + $r1[0]['is_default'] = 0; + $r1[0]['publish'] = 0; + $r1[0]['profile_name'] = dbesc($name); + $r1[0]['profile_guid'] = dbesc(random_string()); + + dbesc_array($r1[0]); + + $r2 = dbq("INSERT INTO `profile` (`" + . implode("`, `", array_keys($r1[0])) + . "`) VALUES ('" + . implode("', '", array_values($r1[0])) + . "')" ); + + $r3 = q("SELECT `id` FROM `profile` WHERE `uid` = %d AND `profile_name` = '%s' LIMIT 1", + intval(local_channel()), + dbesc($name) + ); + info( t('New profile created.') . EOL); + + profiles_build_sync(local_channel()); + + if(($r3) && (count($r3) == 1)) + goaway(z_root() . '/profiles/' . $r3[0]['id']); + + goaway(z_root() . '/profiles'); + + return; // NOTREACHED + } + + if((argc() > 2) && (argv(1) === 'export')) { + + $r1 = q("SELECT * FROM `profile` WHERE `uid` = %d AND `id` = %d LIMIT 1", + intval(local_channel()), + intval(argv(2)) + ); + if(! $r1) { + notice( t('Profile unavailable to export.') . EOL); + \App::$error = 404; + return; + } + header('content-type: application/octet_stream'); + header('content-disposition: attachment; filename="' . $r1[0]['profile_name'] . '.json"' ); + + unset($r1[0]['id']); + unset($r1[0]['aid']); + unset($r1[0]['uid']); + unset($r1[0]['is_default']); + unset($r1[0]['publish']); + unset($r1[0]['profile_name']); + unset($r1[0]['profile_guid']); + echo json_encode($r1[0]); + killme(); + } + + + + + // Run profile_load() here to make sure the theme is set before + // we start loading content + if(((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(),'multi_profiles')) { + if(feature_enabled(local_channel(),'multi_profiles')) + $id = \App::$argv[1]; + else { + $x = q("select id from profile where uid = %d and is_default = 1", + intval(local_channel()) + ); + if($x) + $id = $x[0]['id']; + } + $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($id), + intval(local_channel()) + ); + if(! count($r)) { + notice( t('Profile not found.') . EOL); + \App::$error = 404; + return; + } + + $chan = \App::get_channel(); + + profile_load($a,$chan['channel_address'],$r[0]['id']); + } + } + + function post() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + require_once('include/activities.php'); + + $namechanged = false; + + + // import from json export file. + // Only import fields that are allowed on this hub + + if(x($_FILES,'userfile')) { + $src = $_FILES['userfile']['tmp_name']; + $filesize = intval($_FILES['userfile']['size']); + if($filesize) { + $j = @json_decode(@file_get_contents($src),true); + @unlink($src); + if($j) { + $fields = get_profile_fields_advanced(); + if($fields) { + foreach($j as $jj => $v) { + foreach($fields as $f => $n) { + if($jj == $f) { + $_POST[$f] = $v; + break; + } + } + } + } + } + } + } + + call_hooks('profile_post', $_POST); + + + if((argc() > 1) && (argv(1) !== "new") && intval(argv(1))) { + $orig = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval(\App::$argv[1]), + intval(local_channel()) + ); + if(! count($orig)) { + notice( t('Profile not found.') . EOL); + return; + } + + check_form_security_token_redirectOnErr('/profiles', 'profile_edit'); + + $is_default = (($orig[0]['is_default']) ? 1 : 0); + + $profile_name = notags(trim($_POST['profile_name'])); + if(! strlen($profile_name)) { + notice( t('Profile Name is required.') . EOL); + return; + } + + $dob = $_POST['dob'] ? escape_tags(trim($_POST['dob'])) : '0000-00-00'; // FIXME: Needs to be validated? + + $y = substr($dob,0,4); + if((! ctype_digit($y)) || ($y < 1900)) + $ignore_year = true; + else + $ignore_year = false; + + if($dob != '0000-00-00') { + if(strpos($dob,'0000-') === 0) { + $ignore_year = true; + $dob = substr($dob,5); + } + $dob = datetime_convert('UTC','UTC',(($ignore_year) ? '1900-' . $dob : $dob),(($ignore_year) ? 'm-d' : 'Y-m-d')); + if($ignore_year) + $dob = '0000-' . $dob; + } + + $name = escape_tags(trim($_POST['name'])); + + if($orig[0]['name'] != $name) { + $namechanged = true; + + $v = validate_channelname($name); + if($v) { + notice($v); + $namechanged = false; + $name = $orig[0]['name']; + } + } + + $pdesc = escape_tags(trim($_POST['pdesc'])); + $gender = escape_tags(trim($_POST['gender'])); + $address = escape_tags(trim($_POST['address'])); + $locality = escape_tags(trim($_POST['locality'])); + $region = escape_tags(trim($_POST['region'])); + $postal_code = escape_tags(trim($_POST['postal_code'])); + $country_name = escape_tags(trim($_POST['country_name'])); + $keywords = escape_tags(trim($_POST['keywords'])); + $marital = escape_tags(trim($_POST['marital'])); + $howlong = escape_tags(trim($_POST['howlong'])); + $sexual = escape_tags(trim($_POST['sexual'])); + $homepage = escape_tags(trim($_POST['homepage'])); + $hometown = escape_tags(trim($_POST['hometown'])); + $politic = escape_tags(trim($_POST['politic'])); + $religion = escape_tags(trim($_POST['religion'])); + + $likes = fix_mce_lf(escape_tags(trim($_POST['likes']))); + $dislikes = fix_mce_lf(escape_tags(trim($_POST['dislikes']))); + + $about = fix_mce_lf(escape_tags(trim($_POST['about']))); + $interest = fix_mce_lf(escape_tags(trim($_POST['interest']))); + $contact = fix_mce_lf(escape_tags(trim($_POST['contact']))); + $channels = fix_mce_lf(escape_tags(trim($_POST['channels']))); + $music = fix_mce_lf(escape_tags(trim($_POST['music']))); + $book = fix_mce_lf(escape_tags(trim($_POST['book']))); + $tv = fix_mce_lf(escape_tags(trim($_POST['tv']))); + $film = fix_mce_lf(escape_tags(trim($_POST['film']))); + $romance = fix_mce_lf(escape_tags(trim($_POST['romance']))); + $work = fix_mce_lf(escape_tags(trim($_POST['work']))); + $education = fix_mce_lf(escape_tags(trim($_POST['education']))); + + $hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0); + + require_once('include/text.php'); + linkify_tags($a, $likes, local_channel()); + linkify_tags($a, $dislikes, local_channel()); + linkify_tags($a, $about, local_channel()); + linkify_tags($a, $interest, local_channel()); + linkify_tags($a, $interest, local_channel()); + linkify_tags($a, $contact, local_channel()); + linkify_tags($a, $channels, local_channel()); + linkify_tags($a, $music, local_channel()); + linkify_tags($a, $book, local_channel()); + linkify_tags($a, $tv, local_channel()); + linkify_tags($a, $film, local_channel()); + linkify_tags($a, $romance, local_channel()); + linkify_tags($a, $work, local_channel()); + linkify_tags($a, $education, local_channel()); + + + $with = ((x($_POST,'with')) ? escape_tags(trim($_POST['with'])) : ''); + + if(! strlen($howlong)) + $howlong = NULL_DATE; + else + $howlong = datetime_convert(date_default_timezone_get(),'UTC',$howlong); + + // linkify the relationship target if applicable + + $withchanged = false; + + if(strlen($with)) { + if($with != strip_tags($orig[0]['with'])) { + $withchanged = true; + $prf = ''; + $lookup = $with; + if(strpos($lookup,'@') === 0) + $lookup = substr($lookup,1); + $lookup = str_replace('_',' ', $lookup); + $newname = $lookup; + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + dbesc($newname), + intval(local_channel()) + ); + if(! $r) { + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_addr = '%s' AND abook_channel = %d LIMIT 1", + dbesc($lookup . '@%'), + intval(local_channel()) + ); + } + if($r) { + $prf = $r[0]['xchan_url']; + $newname = $r[0]['xchan_name']; + } + + + if($prf) { + $with = str_replace($lookup,'' . $newname . '', $with); + if(strpos($with,'@') === 0) + $with = substr($with,1); + } + } + else + $with = $orig[0]['with']; + } + + $profile_fields_basic = get_profile_fields_basic(); + $profile_fields_advanced = get_profile_fields_advanced(); + $advanced = ((feature_enabled(local_channel(),'advanced_profiles')) ? true : false); + if($advanced) + $fields = $profile_fields_advanced; + else + $fields = $profile_fields_basic; + + $z = q("select * from profdef where true"); + if($z) { + foreach($z as $zz) { + if(array_key_exists($zz['field_name'],$fields)) { + $w = q("select * from profext where channel_id = %d and hash = '%s' and k = '%s' limit 1", + intval(local_channel()), + dbesc($orig[0]['profile_guid']), + dbesc($zz['field_name']) + ); + if($w) { + q("update profext set v = '%s' where id = %d", + dbesc(escape_tags(trim($_POST[$zz['field_name']]))), + intval($w[0]['id']) + ); + } + else { + q("insert into profext ( channel_id, hash, k, v ) values ( %d, '%s', '%s', '%s') ", + intval(local_channel()), + dbesc($orig[0]['profile_guid']), + dbesc($zz['field_name']), + dbesc(escape_tags(trim($_POST[$zz['field_name']]))) + ); + } + } + } + } + + $changes = array(); + $value = ''; + if($is_default) { + if($marital != $orig[0]['marital']) { + $changes[] = '[color=#ff0000]♥[/color] ' . t('Marital Status'); + $value = $marital; + } + if($withchanged) { + $changes[] = '[color=#ff0000]♥[/color] ' . t('Romantic Partner'); + $value = strip_tags($with); + } + if($likes != $orig[0]['likes']) { + $changes[] = t('Likes'); + $value = $likes; + } + if($dislikes != $orig[0]['dislikes']) { + $changes[] = t('Dislikes'); + $value = $dislikes; + } + if($work != $orig[0]['work']) { + $changes[] = t('Work/Employment'); + } + if($religion != $orig[0]['religion']) { + $changes[] = t('Religion'); + $value = $religion; + } + if($politic != $orig[0]['politic']) { + $changes[] = t('Political Views'); + $value = $politic; + } + if($gender != $orig[0]['gender']) { + $changes[] = t('Gender'); + $value = $gender; + } + if($sexual != $orig[0]['sexual']) { + $changes[] = t('Sexual Preference'); + $value = $sexual; + } + if($homepage != $orig[0]['homepage']) { + $changes[] = t('Homepage'); + $value = $homepage; + } + if($interest != $orig[0]['interest']) { + $changes[] = t('Interests'); + $value = $interest; + } + if($address != $orig[0]['address']) { + $changes[] = t('Address'); + // New address not sent in notifications, potential privacy issues + // in case this leaks to unintended recipients. Yes, it's in the public + // profile but that doesn't mean we have to broadcast it to everybody. + } + if($locality != $orig[0]['locality'] || $region != $orig[0]['region'] + || $country_name != $orig[0]['country_name']) { + $changes[] = t('Location'); + $comma1 = ((($locality) && ($region || $country_name)) ? ', ' : ' '); + $comma2 = (($region && $country_name) ? ', ' : ''); + $value = $locality . $comma1 . $region . $comma2 . $country_name; + } + + profile_activity($changes,$value); + + } + + $r = q("UPDATE `profile` + SET `profile_name` = '%s', + `name` = '%s', + `pdesc` = '%s', + `gender` = '%s', + `dob` = '%s', + `address` = '%s', + `locality` = '%s', + `region` = '%s', + `postal_code` = '%s', + `country_name` = '%s', + `marital` = '%s', + `with` = '%s', + `howlong` = '%s', + `sexual` = '%s', + `homepage` = '%s', + `hometown` = '%s', + `politic` = '%s', + `religion` = '%s', + `keywords` = '%s', + `likes` = '%s', + `dislikes` = '%s', + `about` = '%s', + `interest` = '%s', + `contact` = '%s', + `channels` = '%s', + `music` = '%s', + `book` = '%s', + `tv` = '%s', + `film` = '%s', + `romance` = '%s', + `work` = '%s', + `education` = '%s', + `hide_friends` = %d + WHERE `id` = %d AND `uid` = %d", + dbesc($profile_name), + dbesc($name), + dbesc($pdesc), + dbesc($gender), + dbesc($dob), + dbesc($address), + dbesc($locality), + dbesc($region), + dbesc($postal_code), + dbesc($country_name), + dbesc($marital), + dbesc($with), + dbesc($howlong), + dbesc($sexual), + dbesc($homepage), + dbesc($hometown), + dbesc($politic), + dbesc($religion), + dbesc($keywords), + dbesc($likes), + dbesc($dislikes), + dbesc($about), + dbesc($interest), + dbesc($contact), + dbesc($channels), + dbesc($music), + dbesc($book), + dbesc($tv), + dbesc($film), + dbesc($romance), + dbesc($work), + dbesc($education), + intval($hide_friends), + intval(argv(1)), + intval(local_channel()) + ); + + if($r) + info( t('Profile updated.') . EOL); + + $r = q("select * from profile where id = %d and uid = %d limit 1", + intval(argv(1)), + intval(local_channel()) + ); + if($r) { + require_once('include/zot.php'); + build_sync_packet(local_channel(),array('profile' => $r)); + } + + $channel = \App::get_channel(); + + if($namechanged && $is_default) { + $r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'", + dbesc($name), + dbesc(datetime_convert()), + dbesc($channel['xchan_hash']) + ); + $r = q("UPDATE channel SET channel_name = '%s' WHERE channel_hash = '%s'", + dbesc($name), + dbesc($channel['xchan_hash']) + ); + } + + if($is_default) { + // reload the info for the sidebar widget - why does this not work? + profile_load($a,$channel['channel_address']); + proc_run('php','include/directory.php',local_channel()); + } + } + } + + + function get() { + + $o = ''; + + $channel = \App::get_channel(); + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + require_once('include/identity.php'); + + $profile_fields_basic = get_profile_fields_basic(); + $profile_fields_advanced = get_profile_fields_advanced(); + + if(((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(),'multi_profiles')) { + if(feature_enabled(local_channel(),'multi_profiles')) + $id = \App::$argv[1]; + else { + $x = q("select id from profile where uid = %d and is_default = 1", + intval(local_channel()) + ); + if($x) + $id = $x[0]['id']; + } + $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($id), + intval(local_channel()) + ); + if(! count($r)) { + notice( t('Profile not found.') . EOL); + return; + } + + require_once('include/profile_selectors.php'); + + + $editselect = 'none'; + // if(feature_enabled(local_channel(),'richtext')) + // $editselect = 'textareas'; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template('profed_head.tpl'), array( + '$baseurl' => z_root(), + '$editselect' => $editselect, + )); + + $advanced = ((feature_enabled(local_channel(),'advanced_profiles')) ? true : false); + if($advanced) + $fields = $profile_fields_advanced; + else + $fields = $profile_fields_basic; + + $hide_friends = array( + 'hide_friends', + t('Hide your connections list from viewers of this profile'), + $r[0]['hide_friends'], + '', + array(t('No'),t('Yes')) + ); + + $q = q("select * from profdef where true"); + if($q) { + $extra_fields = array(); + + foreach($q as $qq) { + $mine = q("select v from profext where k = '%s' and hash = '%s' and channel_id = %d limit 1", + dbesc($qq['field_name']), + dbesc($r[0]['profile_guid']), + intval(local_channel()) + ); + + if(array_key_exists($qq['field_name'],$fields)) { + $extra_fields[] = array($qq['field_name'],$qq['field_desc'],(($mine) ? $mine[0]['v'] : ''), $qq['field_help']); + } + } + } + + //logger('extra_fields: ' . print_r($extra_fields,true)); + + $f = get_config('system','birthday_input_format'); + if(! $f) + $f = 'ymd'; + + $is_default = (($r[0]['is_default']) ? 1 : 0); + + $tpl = get_markup_template("profile_edit.tpl"); + $o .= replace_macros($tpl,array( + + '$form_security_token' => get_form_security_token("profile_edit"), + '$profile_clone_link' => ((feature_enabled(local_channel(),'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' + . get_form_security_token("profile_clone") : ''), + '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' + . get_form_security_token("profile_drop"), + + '$fields' => $fields, + '$guid' => $r[0]['profile_guid'], + '$banner' => t('Edit Profile Details'), + '$submit' => t('Submit'), + '$viewprof' => t('View this profile'), + '$editvis' => t('Edit visibility'), + '$coverpic' => t('Change cover photo'), + '$profpic' => t('Change profile photo'), + '$cr_prof' => t('Create a new profile using these settings'), + '$cl_prof' => t('Clone this profile'), + '$del_prof' => t('Delete this profile'), + '$addthing' => t('Add profile things'), + '$personal' => t('Personal'), + '$location' => t('Location'), + '$relation' => t('Relation'), + '$miscellaneous'=> t('Miscellaneous'), + '$exportable' => feature_enabled(local_channel(),'profile_export'), + '$lbl_import' => t('Import profile from file'), + '$lbl_export' => t('Export profile to file'), + '$lbl_gender' => t('Your gender'), + '$lbl_marital' => t('Marital status'), + '$lbl_sexual' => t('Sexual preference'), + '$baseurl' => z_root(), + '$profile_id' => $r[0]['id'], + '$profile_name' => array('profile_name', t('Profile name'), $r[0]['profile_name'], t('Required'), '*'), + '$is_default' => $is_default, + '$default' => t('This is your default profile.') . EOL . translate_scope(map_scope($channel['channel_r_profile'])), + '$advanced' => $advanced, + '$name' => array('name', t('Your full name'), $r[0]['name'], t('Required'), '*'), + '$pdesc' => array('pdesc', t('Title/Description'), $r[0]['pdesc']), + '$dob' => dob($r[0]['dob']), + '$hide_friends' => $hide_friends, + '$address' => array('address', t('Street address'), $r[0]['address']), + '$locality' => array('locality', t('Locality/City'), $r[0]['locality']), + '$region' => array('region', t('Region/State'), $r[0]['region']), + '$postal_code' => array('postal_code', t('Postal/Zip code'), $r[0]['postal_code']), + '$country_name' => array('country_name', t('Country'), $r[0]['country_name']), + '$gender' => gender_selector($r[0]['gender']), + '$gender_min' => gender_selector_min($r[0]['gender']), + '$marital' => marital_selector($r[0]['marital']), + '$marital_min' => marital_selector_min($r[0]['marital']), + '$with' => array('with', t("Who (if applicable)"), $r[0]['with'], t('Examples: cathy123, Cathy Williams, cathy@example.com')), + '$howlong' => array('howlong', t('Since (date)'), ($r[0]['howlong'] === NULL_DATE ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong']))), + '$sexual' => sexpref_selector($r[0]['sexual']), + '$sexual_min' => sexpref_selector_min($r[0]['sexual']), + '$about' => array('about', t('Tell us about yourself'), $r[0]['about']), + '$homepage' => array('homepage', t('Homepage URL'), $r[0]['homepage']), + '$hometown' => array('hometown', t('Hometown'), $r[0]['hometown']), + '$politic' => array('politic', t('Political views'), $r[0]['politic']), + '$religion' => array('religion', t('Religious views'), $r[0]['religion']), + '$keywords' => array('keywords', t('Keywords used in directory listings'), $r[0]['keywords'], t('Example: fishing photography software')), + '$likes' => array('likes', t('Likes'), $r[0]['likes']), + '$dislikes' => array('dislikes', t('Dislikes'), $r[0]['dislikes']), + '$music' => array('music', t('Musical interests'), $r[0]['music']), + '$book' => array('book', t('Books, literature'), $r[0]['book']), + '$tv' => array('tv', t('Television'), $r[0]['tv']), + '$film' => array('film', t('Film/Dance/Culture/Entertainment'), $r[0]['film']), + '$interest' => array('interest', t('Hobbies/Interests'), $r[0]['interest']), + '$romance' => array('romance',t('Love/Romance'), $r[0]['romance']), + '$work' => array('work', t('Work/Employment'), $r[0]['work']), + '$education' => array('education', t('School/Education'), $r[0]['education']), + '$contact' => array('contact', t('Contact information and social networks'), $r[0]['contact']), + '$channels' => array('channels', t('My other channels'), $r[0]['channels']), + '$extra_fields' => $extra_fields, + )); + + $arr = array('profile' => $r[0], 'entry' => $o); + call_hooks('profile_edit', $arr); + + return $o; + } + else { + + $r = q("SELECT * FROM `profile` WHERE `uid` = %d", + local_channel()); + if(count($r)) { + + $tpl = get_markup_template('profile_entry.tpl'); + foreach($r as $rr) { + $profiles .= replace_macros($tpl, array( + '$photo' => $rr['thumb'], + '$id' => $rr['id'], + '$alt' => t('Profile Image'), + '$profile_name' => $rr['profile_name'], + '$visible' => (($rr['is_default']) + ? '' . translate_scope(map_scope($channel['channel_r_profile'])) . '' + : '' . t('Edit visibility') . '') + )); + } + + $tpl_header = get_markup_template('profile_listing_header.tpl'); + $o .= replace_macros($tpl_header,array( + '$header' => t('Edit Profiles'), + '$cr_new' => t('Create New'), + '$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new"), + '$profiles' => $profiles + )); + + + + + } + return $o; + } + + } + +} diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php new file mode 100644 index 000000000..94267aaac --- /dev/null +++ b/Zotlabs/Module/Profperm.php @@ -0,0 +1,172 @@ + 2) && intval(argv(1)) && intval(argv(2))) { + $r = q("SELECT abook_id FROM abook WHERE abook_id = %d and abook_channel = %d limit 1", + intval(argv(2)), + intval(local_channel()) + ); + if($r) + $change = intval(argv(2)); + } + + + if((argc() > 1) && (intval(argv(1)))) { + $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d AND `is_default` = 0 LIMIT 1", + intval(argv(1)), + intval(local_channel()) + ); + if(! $r) { + notice( t('Invalid profile identifier.') . EOL ); + return; + } + + $profile = $r[0]; + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", + intval(local_channel()), + dbesc($profile['profile_guid']) + ); + + $ingroup = array(); + if($r) + foreach($r as $member) + $ingroup[] = $member['abook_id']; + + $members = $r; + + if($change) { + if(in_array($change,$ingroup)) { + q("UPDATE abook SET abook_profile = '' WHERE abook_id = %d AND abook_channel = %d", + intval($change), + intval(local_channel()) + ); + } + else { + q("UPDATE abook SET abook_profile = '%s' WHERE abook_id = %d AND abook_channel = %d", + dbesc($profile['profile_guid']), + intval($change), + intval(local_channel()) + ); + + } + + + //Time to update the permissions on the profile-pictures as well + + profile_photo_set_profile_perms($profile['id']); + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", + intval(local_channel()), + dbesc($profile['profile_guid']) + ); + + $members = $r; + + $ingroup = array(); + if(count($r)) + foreach($r as $member) + $ingroup[] = $member['abook_id']; + } + + $o .= '

    ' . t('Profile Visibility Editor') . '

    '; + + $o .= '

    ' . t('Profile') . ' \'' . $profile['profile_name'] . '\'

    '; + + $o .= '
    ' . t('Click on a contact to add or remove.') . '
    '; + + } + + $o .= '
    '; + if($change) + $o = ''; + + $o .= '
    '; + $o .= '

    ' . t('Visible To') . '

    '; + $o .= '
    '; + $o .= '
    '; + + $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); + + foreach($members as $member) { + if($member['xchan_url']) { + $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['abook_id'] . '); return false;'; + $o .= micropro($member,true,'mpprof', $textmode); + } + } + $o .= '
    '; + $o .= '
    '; + + $o .= '
    '; + $o .= '

    ' . t("All Connections") . '

    '; + $o .= '
    '; + $o .= '
    '; + + $r = abook_connections(local_channel()); + + if($r) { + $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); + foreach($r as $member) { + if(! in_array($member['abook_id'],$ingroup)) { + $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['abook_id'] . '); return false;'; + $o .= micropro($member,true,'mpprof',$textmode); + } + } + } + + $o .= '
    '; + + if($change) { + echo $o; + killme(); + } + $o .= '
    '; + return $o; + + } + + +} diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php new file mode 100644 index 000000000..559c8f2f1 --- /dev/null +++ b/Zotlabs/Module/Pubsites.php @@ -0,0 +1,59 @@ +'; + + $o .= '

    ' . t('Public Hubs') . '

    '; + + $o .= '
    ' . + t('The listed hubs allow public registration for the $Projectname network. All hubs in the network are interlinked so membership on any of them conveys membership in the network as a whole. Some hubs may require subscription or provide tiered service plans. The hub itself may provide additional details.') . '
    ' . EOL; + + $ret = z_fetch_url($url); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) { + $o .= ''; + if($j['sites']) { + foreach($j['sites'] as $jj) { + if($jj['project'] !== \Zotlabs\Project\System::get_platform_name()) + continue; + $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); + $rate_links = ((local_channel()) ? '' : ''); + $location = ''; + if(!empty($jj['location'])) { + $location = '

    ' . $jj['location'] . '

    '; + } + else { + $location = '
     '; + } + $urltext = str_replace(array('https://'), '', $jj['url']); + $o .= '' . $rate_links . ''; + } + } + + $o .= '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Ratings') . '
    ' . t('Rate') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '
    '; + + $o .= '
    '; + + } + } + return $o; + } + +} diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php new file mode 100644 index 000000000..d6cfe6e92 --- /dev/null +++ b/Zotlabs/Module/Pubstream.php @@ -0,0 +1,168 @@ +' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'public', + '$uid' => ((local_channel()) ? local_channel() : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '0', + '$cmax' => '99', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$fh' => '1', + '$nouveau' => '0', + '$wall' => '0', + '$list' => '0', + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$search' => '', + '$order' => 'comment', + '$file' => '', + '$cats' => '', + '$tags' => '', + '$dend' => '', + '$mid' => '', + '$verb' => '', + '$dbegin' => '' + )); + } + + if($update && ! $load) { + // only setup pagination on initial page view + $pager_sql = ''; + } + else { + \App::set_pager_itemspage(20); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + } + + require_once('include/identity.php'); + require_once('include/security.php'); + + if(get_config('system','site_firehose')) { + $uids = " and item.uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) and item_private = 0 and item_wall = 1 "; + } + else { + $sys = get_sys_channel(); + $uids = " and item.uid = " . intval($sys['channel_id']) . " "; + $sql_extra = item_permissions_sql($sys['channel_id']); + \App::$data['firehose'] = intval($sys['channel_id']); + } + + if(get_config('system','public_list_mode')) + $page_mode = 'list'; + else + $page_mode = 'client'; + + + $simple_update = (($update) ? " and item.item_unseen = 1 " : ''); + + if($update && $_SESSION['loadtime']) + $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; + if($load) + $simple_update = ''; + + //logger('update: ' . $update . ' load: ' . $load); + + if($update) { + + $ordering = "commented"; + + if($load) { + + // Fetch a page full of parent items for this page + + $r = q("SELECT distinct item.id AS item_id, $ordering FROM item + left join abook on item.author_xchan = abook.abook_xchan + WHERE true $uids $item_normal + AND item.parent = item.id + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra3 $sql_extra $sql_nets + ORDER BY $ordering DESC $pager_sql " + ); + + + } + elseif($update) { + + $r = q("SELECT distinct item.id AS item_id, $ordering FROM item + left join abook on item.author_xchan = abook.abook_xchan + WHERE true $uids $item_normal + AND item.parent = item.id $simple_update + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra3 $sql_extra $sql_nets" + ); + $_SESSION['loadtime'] = datetime_convert(); + } + // Then fetch all the children of the parents that are on this page + $parents_str = ''; + $update_unseen = ''; + + if($r) { + + $parents_str = ids_to_querystr($r,'item_id'); + + $items = q("SELECT item.*, item.id AS item_id FROM item + WHERE true $uids $item_normal + AND item.parent IN ( %s ) + $sql_extra ", + dbesc($parents_str) + ); + + xchan_query($items,true,(-1)); + $items = fetch_post_tags($items,true); + $items = conv_sort($items,$ordering); + } + else { + $items = array(); + } + + } + + // fake it + $mode = ('network'); + + $o .= conversation($a,$items,$mode,$update,$page_mode); + + if(($items) && (! $update)) + $o .= alt_pager($a,count($items)); + + return $o; + + } +} diff --git a/Zotlabs/Module/Pushcall.php b/Zotlabs/Module/Pushcall.php new file mode 100644 index 000000000..c0b95159d --- /dev/null +++ b/Zotlabs/Module/Pushcall.php @@ -0,0 +1,19 @@ + 10) + $rating = 10; + + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); + + $signed = \App::$data['target'] . '.' . $rating . '.' . $rating_text; + + $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); + + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc(\App::$data['target']) + ); + + if($z) { + $record = $z[0]['xlink_id']; + $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s' + where xlink_id = %d", + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()), + intval($record) + ); + } + else { + $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", + dbesc($channel['channel_hash']), + dbesc(\App::$data['target']), + intval($rating), + dbesc($rating_text), + dbesc($sig), + dbesc(datetime_convert()) + ); + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", + dbesc($channel['channel_hash']), + dbesc(\App::$data['target']) + ); + if($z) + $record = $z[0]['xlink_id']; + } + + if($record) { + proc_run('php','include/ratenotif.php','rating',$record); + } + + } + + + + function get() { + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + // if(! \App::$data['target']) { + // notice( t('No recipients.') . EOL); + // return; + // } + + $poco_rating = get_config('system','poco_rating_enable'); + if((! $poco_rating) && ($poco_rating !== false)) { + notice('Ratings are disabled on this site.'); + return; + } + + $channel = \App::get_channel(); + + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", + dbesc($channel['channel_hash']), + dbesc(\App::$data['target']) + ); + if($r) { + \App::$data['xlink'] = $r[0]; + $rating_val = $r[0]['xlink_rating']; + $rating_text = $r[0]['xlink_rating_text']; + } + else { + $rating_val = 0; + $rating_text = ''; + } + + // if unset default to enabled + if($poco_rating === false) + $poco_rating = true; + + if($poco_rating) { + $rating = replace_macros(get_markup_template('rating_slider.tpl'),array( + '$min' => -10, + '$val' => $rating_val + )); + } + else { + $rating = false; + } + + $o = replace_macros(get_markup_template('rating_form.tpl'),array( + '$header' => t('Rating'), + '$website' => t('Website:'), + '$site' => ((\App::$data['site']) ? '' . \App::$data['site']['site_url'] . '' : ''), + 'target' => \App::$data['target'], + '$tgt_name' => ((\App::$poi && \App::$poi['xchan_name']) ? \App::$poi['xchan_name'] : sprintf( t('Remote Channel [%s] (not yet known on this site)'), substr(\App::$data['target'],0,16))), + '$lbl_rating' => t('Rating (this information is public)'), + '$lbl_rating_txt' => t('Optionally explain your rating (this information is public)'), + '$rating_txt' => $rating_text, + '$rating' => $rating, + '$rating_val' => $rating_val, + '$slide' => $slide, + '$submit' => t('Submit') + )); + + return $o; + + } +} diff --git a/Zotlabs/Module/Ratings.php b/Zotlabs/Module/Ratings.php new file mode 100644 index 000000000..802bbfec2 --- /dev/null +++ b/Zotlabs/Module/Ratings.php @@ -0,0 +1,115 @@ + 1) + $hash = argv(1); + + if(! $hash) { + notice('Must supply a channel identififier.'); + return; + } + + $results = false; + + $x = z_fetch_url($url . '/ratingsearch/' . urlencode($hash)); + + + if($x['success']) + $results = json_decode($x['body'],true); + + + if((! $results) || (! $results['success'])) { + + notice('No results.'); + return; + } + + if(array_key_exists('xchan_hash',$results['target'])) + \App::$poi = $results['target']; + + $friends = array(); + $others = array(); + + if($results['ratings']) { + foreach($results['ratings'] as $n) { + if(is_array(\App::$contacts) && array_key_exists($n['xchan_hash'],\App::$contacts)) + $friends[] = $n; + else + $others[] = $n; + } + } + + \App::$data = array('target' => $results['target'], 'results' => array_merge($friends,$others)); + + if(! \App::$data['results']) { + notice( t('No ratings') . EOL); + } + + return; + } + + + + + + function get() { + + if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + notice( t('Public access denied.') . EOL); + return; + } + + $poco_rating = get_config('system','poco_rating_enable'); + // if unset default to enabled + if($poco_rating === false) + $poco_rating = true; + + if(! $poco_rating) + return; + + $site_target = ((array_key_exists('target',\App::$data) && array_key_exists('site_url',\App::$data['target'])) ? + '' . \App::$data['target']['site_url'] . '' : ''); + + + $o = replace_macros(get_markup_template('prep.tpl'),array( + '$header' => t('Ratings'), + '$rating_lbl' => t('Rating: ' ), + '$website' => t('Website: '), + '$site' => $site_target, + '$rating_text_lbl' => t('Description: '), + '$raters' => \App::$data['results'] + )); + + return $o; + } + + +} diff --git a/Zotlabs/Module/Ratingsearch.php b/Zotlabs/Module/Ratingsearch.php new file mode 100644 index 000000000..5f463b378 --- /dev/null +++ b/Zotlabs/Module/Ratingsearch.php @@ -0,0 +1,76 @@ + false); + + $dirmode = intval(get_config('system','directory_mode')); + + if($dirmode == DIRECTORY_MODE_NORMAL) { + $ret['message'] = 'This site is not a directory server.'; + json_return_and_die($ret); + } + + if(argc() > 1) + $hash = argv(1); + + if(! $hash) { + $ret['message'] = 'No channel identifier'; + json_return_and_die($ret); + } + + if(strpos($hash,'@')) { + $r = q("select * from hubloc where hubloc_addr = '%s' limit 1", + dbesc($hash) + ); + if($r) + $hash = $r[0]['hubloc_hash']; + } + + $p = q("select * from xchan where xchan_hash like '%s'", + dbesc($hash . '%') + ); + + if($p) + $target = $p[0]['xchan_hash']; + else { + $p = q("select * from site where site_url like '%s' and site_type = %d ", + dbesc('%' . $hash), + intval(SITE_TYPE_ZOT) + ); + if($p) { + $target = strtolower($hash); + } + else { + $ret['message'] = 'Rating target not found'; + json_return_and_die($ret); + } + } + + if($p) + $ret['target'] = $p[0]; + + $ret['success'] = true; + + $r = q("select * from xlink left join xchan on xlink_xchan = xchan_hash + where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 order by xchan_name asc", + dbesc($target) + ); + + if($r) { + $ret['ratings'] = $r; + } + else + $ret['ratings'] = array(); + + json_return_and_die($ret); + + } + + +} diff --git a/Zotlabs/Module/Rbmark.php b/Zotlabs/Module/Rbmark.php new file mode 100644 index 000000000..226cef69e --- /dev/null +++ b/Zotlabs/Module/Rbmark.php @@ -0,0 +1,121 @@ + escape_tags($_REQUEST['url']),'term' => escape_tags($_REQUEST['title'])); + bookmark_add($channel,$channel,$t,((x($_REQUEST,'private')) ? intval($_REQUEST['private']) : 0), + array('menu_id' => ((x($_REQUEST,'menu_id')) ? intval($_REQUEST['menu_id']) : 0), + 'menu_name' => ((x($_REQUEST,'menu_name')) ? escape_tags($_REQUEST['menu_name']) : ''), + 'ischat' => ((x($_REQUEST['ischat'])) ? intval($_REQUEST['ischat']) : 0) + )); + + goaway(z_root() . '/bookmarks'); + + } + + + function get() { + + $o = ''; + + if(! local_channel()) { + + // The login procedure is going to bugger our $_REQUEST variables + // so save them in the session. + + if(array_key_exists('url',$_REQUEST)) { + $_SESSION['bookmark'] = $_REQUEST; + } + return login(); + } + + // If we have saved rbmark session variables, but nothing in the current $_REQUEST, recover the saved variables + + if((! array_key_exists('url',$_REQUEST)) && (array_key_exists('bookmark',$_SESSION))) { + $_REQUEST = $_SESSION['bookmark']; + unset($_SESSION['bookmark']); + } + + if($_REQUEST['remote_return']) { + $_SESSION['remote_return'] = $_REQUEST['remote_return']; + } + if(argc() > 1 && argv(1) === 'return') { + if($_SESSION['remote_return']) + goaway($_SESSION['remote_return']); + goaway(z_root() . '/bookmarks'); + } + + $channel = \App::get_channel(); + + + $m = menu_list($channel['channel_id'],'',MENU_BOOKMARK); + + $menus = array(); + if($m) { + $menus = array(0 => ''); + foreach($m as $n) { + $menus[$n['menu_id']] = $n['menu_name']; + } + } + $menu_select = array('menu_id',t('Select a bookmark folder'),false,'',$menus); + + + $o .= replace_macros(get_markup_template('rbmark.tpl'), array( + + '$header' => t('Save Bookmark'), + '$url' => array('url',t('URL of bookmark'),escape_tags($_REQUEST['url'])), + '$title' => array('title',t('Description'),escape_tags($_REQUEST['title'])), + '$ischat' => ((x($_REQUEST,'ischat')) ? intval($_REQUEST['ischat']) : 0), + '$private' => ((x($_REQUEST,'private')) ? intval($_REQUEST['private']) : 0), + '$submit' => t('Save'), + '$menu_name' => array('menu_name',t('Or enter new bookmark folder name'),'',''), + '$menus' => $menu_select + + )); + + + + + + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Regdir.php b/Zotlabs/Module/Regdir.php new file mode 100644 index 000000000..65f8daf67 --- /dev/null +++ b/Zotlabs/Module/Regdir.php @@ -0,0 +1,109 @@ + false); + + $url = $_REQUEST['url']; + $access_token = $_REQUEST['t']; + $valid = 0; + + // we probably don't need the realm as we will find out in the probe. + // What we may want to die is throw an error if you're trying to register in a different realm + // so this configuration issue can be discovered. + + $realm = $_REQUEST['realm']; + if(! $realm) + $realm = DIRECTORY_REALM; + + if($realm === DIRECTORY_REALM) { + $valid = 1; + } else { + $token = get_config('system','realm_token'); + if($token && $access_token != $token) { + $result['message'] = 'This realm requires an access token'; + return; + } + $valid = 1; + } + + $dirmode = intval(get_config('system','directory_mode')); + + if ($dirmode == DIRECTORY_MODE_NORMAL) { + $ret['message'] = t('This site is not a directory server'); + json_return_and_die($ret); + } + + $m = null; + if ($url) { + $m = parse_url($url); + + if ((! $m) || ((! @dns_get_record($m['host'], DNS_A + DNS_CNAME + DNS_PTR)) && (! filter_var($m['host'], FILTER_VALIDATE_IP) ))) { + + $result['message'] = 'unparseable url'; + json_return_and_die($result); + } + + $f = zot_finger('[system]@' . $m['host']); + if($f['success']) { + $j = json_decode($f['body'],true); + if($j['success'] && $j['guid']) { + $x = import_xchan($j); + if($x['success']) { + $result['success'] = true; + } + } + } + + if(! $result['success']) + $valid = 0; + + q("update site set site_valid = %d where site_url = '%s' limit 1", + intval($valid), + strtolower($url) + ); + + json_return_and_die($result); + } else { + + // We can put this in the sql without the condition after 31 august 2015 assuming + // most directory servers will have updated by then + // This just makes sure it happens if I forget + + $sql_extra = ((datetime_convert() > datetime_convert('UTC','UTC','2015-08-31')) ? ' and site_valid = 1 ' : '' ); + if ($dirmode == DIRECTORY_MODE_STANDALONE) { + $r = array(array('site_url' => z_root())); + } else { + $r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d $sql_extra ", + dbesc(get_directory_realm()), + intval(SITE_TYPE_ZOT) + ); + } + if ($r) { + $result['success'] = true; + $result['directories'] = array(); + foreach ($r as $rr) + $result['directories'][] = $rr['site_url']; + + json_return_and_die($result); + } + } + json_return_and_die($result); + } +} diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php new file mode 100644 index 000000000..ca3f33238 --- /dev/null +++ b/Zotlabs/Module/Register.php @@ -0,0 +1,270 @@ + 1) ? argv(1) : ''); + + // Provide a stored request for somebody desiring a connection + // when they first need to register someplace. Once they've + // created a channel, we'll try to revive the connection request + // and process it. + + if($_REQUEST['connect']) + $_SESSION['connect'] = $_REQUEST['connect']; + + switch($cmd) { + case 'invite_check.json': + $result = check_account_invite($_REQUEST['invite_code']); + break; + case 'email_check.json': + $result = check_account_email($_REQUEST['email']); + break; + case 'password_check.json': + $result = check_account_password($_REQUEST['password']); + break; + default: + break; + } + if($result) { + json_return_and_die($result); + } + } + + + function post() { + + $max_dailies = intval(get_config('system','max_daily_registrations')); + if($max_dailies) { + $r = q("select count(account_id) as total from account where account_created > %s - INTERVAL %s", + db_utcnow(), db_quoteinterval('1 day') + ); + if($r && $r[0]['total'] >= $max_dailies) { + notice( t('Maximum daily site registrations exceeded. Please try again tomorrow.') . EOL); + return; + } + } + + if(! x($_POST,'tos')) { + notice( t('Please indicate acceptance of the Terms of Service. Registration failed.') . EOL); + return; + } + + $policy = get_config('system','register_policy'); + + $email_verify = get_config('system','verify_email'); + + + switch($policy) { + + case REGISTER_OPEN: + $flags = ACCOUNT_OK; + break; + + case REGISTER_APPROVE: + $flags = ACCOUNT_BLOCKED | ACCOUNT_PENDING; + break; + + default: + case REGISTER_CLOSED: + if(! is_site_admin()) { + notice( t('Permission denied.') . EOL ); + return; + } + $flags = ACCOUNT_BLOCKED; + break; + } + + if($email_verify && $policy == REGISTER_OPEN) + $flags = $flags | ACCOUNT_UNVERIFIED; + + + if((! $_POST['password']) || ($_POST['password'] !== $_POST['password2'])) { + notice( t('Passwords do not match.') . EOL); + return; + } + + $arr = $_POST; + $arr['account_flags'] = $flags; + + $result = create_account($arr); + + if(! $result['success']) { + notice($result['message']); + return; + } + require_once('include/security.php'); + + + if($_REQUEST['name']) + set_aconfig($result['account']['account_id'],'register','channel_name',$_REQUEST['name']); + if($_REQUEST['nickname']) + set_aconfig($result['account']['account_id'],'register','channel_address',$_REQUEST['nickname']); + if($_REQUEST['permissions_role']) + set_aconfig($result['account']['account_id'],'register','permissions_role',$_REQUEST['permissions_role']); + + + $using_invites = intval(get_config('system','invitation_only')); + $num_invites = intval(get_config('system','number_invites')); + $invite_code = ((x($_POST,'invite_code')) ? notags(trim($_POST['invite_code'])) : ''); + + if($using_invites && $invite_code) { + q("delete * from register where hash = '%s'", dbesc($invite_code)); + // @FIXME - this also needs to be considered when using 'invites_remaining' in mod/invite.php + set_aconfig($result['account']['account_id'],'system','invites_remaining',$num_invites); + } + + if($policy == REGISTER_OPEN ) { + if($email_verify) { + $res = verify_email_address($result); + } + else { + $res = send_register_success_email($result['email'],$result['password']); + } + if($res) { + info( t('Registration successful. Please check your email for validation instructions.') . EOL ) ; + } + } + elseif($policy == REGISTER_APPROVE) { + $res = send_reg_approval_email($result); + if($res) { + info( t('Your registration is pending approval by the site owner.') . EOL ) ; + } + else { + notice( t('Your registration can not be processed.') . EOL); + } + goaway(z_root()); + } + + if($email_verify) { + goaway(z_root()); + } + + authenticate_success($result['account'],true,false,true); + + $new_channel = false; + $next_page = 'new_channel'; + + if(get_config('system','auto_channel_create') || UNO) { + $new_channel = auto_channel_create($result['account']['account_id']); + if($new_channel['success']) { + $channel_id = $new_channel['channel']['channel_id']; + change_channel($channel_id); + $next_page = '~'; + } + else + $new_channel = false; + } + + $x = get_config('system','workflow_register_next'); + if($x) { + $next_page = $x; + $_SESSION['workflow'] = true; + } + + goaway(z_root() . '/' . $next_page); + + } + + + + function get() { + + $registration_is = ''; + $other_sites = ''; + + if(get_config('system','register_policy') == REGISTER_CLOSED) { + if(get_config('system','directory_mode') == DIRECTORY_MODE_STANDALONE) { + notice( t('Registration on this hub is disabled.') . EOL); + return; + } + + $mod = new Pubsites(); + return $mod->get(); + } + + if(get_config('system','register_policy') == REGISTER_APPROVE) { + $registration_is = t('Registration on this hub is by approval only.'); + $other_sites = t('Register at another affiliated hub.'); + } + + $max_dailies = intval(get_config('system','max_daily_registrations')); + if($max_dailies) { + $r = q("select count(account_id) as total from account where account_created > %s - INTERVAL %s", + db_utcnow(), db_quoteinterval('1 day') + ); + if($r && $r[0]['total'] >= $max_dailies) { + logger('max daily registrations exceeded.'); + notice( t('This site has exceeded the number of allowed daily account registrations. Please try again tomorrow.') . EOL); + return; + } + } + + // Configurable terms of service link + + $tosurl = get_config('system','tos_url'); + if(! $tosurl) + $tosurl = z_root() . '/help/TermsOfService'; + + $toslink = '' . t('Terms of Service') . ''; + + // Configurable whether to restrict age or not - default is based on international legal requirements + // This can be relaxed if you are on a restricted server that does not share with public servers + + if(get_config('system','no_age_restriction')) + $label_tos = sprintf( t('I accept the %s for this website'), $toslink); + else + $label_tos = sprintf( t('I am over 13 years of age and accept the %s for this website'), $toslink); + + $enable_tos = 1 - intval(get_config('system','no_termsofservice')); + + $email = array('email', t('Your email address'), ((x($_REQUEST,'email')) ? strip_tags(trim($_REQUEST['email'])) : "")); + $password = array('password', t('Choose a password'), ((x($_REQUEST,'password')) ? trim($_REQUEST['password']) : "")); + $password2 = array('password2', t('Please re-enter your password'), ((x($_REQUEST,'password2')) ? trim($_REQUEST['password2']) : "")); + $invite_code = array('invite_code', t('Please enter your invitation code'), ((x($_REQUEST,'invite_code')) ? strip_tags(trim($_REQUEST['invite_code'])) : "")); + $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"')); + $nickhub = '@' . str_replace(array('http://','https://','/'), '', get_config('system','baseurl')); + $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub)); + $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : ""); + $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' ' . t('Read more about roles') . '',get_roles()); + $tos = array('tos', $label_tos, '', '', array(t('no'),t('yes'))); + + $auto_create = ((UNO) || (get_config('system','auto_channel_create')) ? true : false); + $default_role = ((UNO) ? 'social' : get_config('system','default_permissions_role')); + + require_once('include/bbcode.php'); + + $o = replace_macros(get_markup_template('register.tpl'), array( + + '$title' => t('Registration'), + '$reg_is' => $registration_is, + '$registertext' => bbcode(get_config('system','register_text')), + '$other_sites' => $other_sites, + '$invitations' => get_config('system','invitation_only'), + '$invite_desc' => t('Membership on this site is by invitation only.'), + '$invite_code' => $invite_code, + '$auto_create' => $auto_create, + '$name' => $name, + '$role' => $role, + '$default_role' => $default_role, + '$nickname' => $nickname, + '$enable_tos' => $enable_tos, + '$tos' => $tos, + '$email' => $email, + '$pass1' => $password, + '$pass2' => $password2, + '$submit' => ((UNO || $auto_create || $registration_is) ? t('Register') : t('Proceed to create your first channel')) + )); + + return $o; + + } + + +} diff --git a/Zotlabs/Module/Regmod.php b/Zotlabs/Module/Regmod.php new file mode 100644 index 000000000..c7e5c44aa --- /dev/null +++ b/Zotlabs/Module/Regmod.php @@ -0,0 +1,40 @@ +
    ' . login((\App::$config['system']['register_policy'] == REGISTER_CLOSED) ? 0 : 1); + return $o; + } + + if(! is_site_admin()) { + notice( t('Permission denied.') . EOL); + return ''; + } + + if(argc() != 3) + killme(); + + $cmd = argv(1); + $hash = argv(2); + + if($cmd === 'deny') { + if (! account_deny($hash)) killme(); + } + + if($cmd === 'allow') { + if (! account_allow($hash)) killme(); + } + } + +} diff --git a/Zotlabs/Module/Regver.php b/Zotlabs/Module/Regver.php new file mode 100644 index 000000000..82b162f56 --- /dev/null +++ b/Zotlabs/Module/Regver.php @@ -0,0 +1,28 @@ + d1) { + notice( t('Account removals are not allowed within 48 hours of changing the account password.') . EOL); + return; + } + } + + require_once('include/Contact.php'); + + $global_remove = intval($_POST['global']); + + account_remove($account_id,true); + + } + + + + function get() { + + if(! local_channel()) + goaway(z_root()); + + $hash = random_string(); + + $_SESSION['remove_account_verify'] = $hash; + $tpl = get_markup_template('removeaccount.tpl'); + $o .= replace_macros($tpl, array( + '$basedir' => z_root(), + '$hash' => $hash, + '$title' => t('Remove This Account'), + '$desc' => array(t('WARNING: '), t('This account and all its channels will be completely removed from the network. '), t('This action is permanent and can not be undone!')), + '$passwd' => t('Please enter your password for verification:'), + '$global' => array('global', t('Remove this account, all its channels and all its channel clones from the network'), false, t('By default only the instances of the channels located on this hub will be removed from the network')), + '$submit' => t('Remove Account') + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Removeme.php b/Zotlabs/Module/Removeme.php new file mode 100644 index 000000000..9b634672a --- /dev/null +++ b/Zotlabs/Module/Removeme.php @@ -0,0 +1,72 @@ + d1) { + notice( t('Channel removals are not allowed within 48 hours of changing the account password.') . EOL); + return; + } + } + + require_once('include/Contact.php'); + + $global_remove = intval($_POST['global']); + + channel_remove(local_channel(),1 - $global_remove,true); + + } + + + + function get() { + + if(! local_channel()) + goaway(z_root()); + + $hash = random_string(); + + $_SESSION['remove_account_verify'] = $hash; + + $tpl = get_markup_template('removeme.tpl'); + $o .= replace_macros($tpl, array( + '$basedir' => z_root(), + '$hash' => $hash, + '$title' => t('Remove This Channel'), + '$desc' => array(t('WARNING: '), t('This channel will be completely removed from the network. '), t('This action is permanent and can not be undone!')), + '$passwd' => t('Please enter your password for verification:'), + '$global' => array('global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), array(t('No'),t('Yes'))), + '$submit' => t('Remove Channel') + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Rmagic.php b/Zotlabs/Module/Rmagic.php new file mode 100644 index 000000000..bcdbf6c90 --- /dev/null +++ b/Zotlabs/Module/Rmagic.php @@ -0,0 +1,95 @@ + $address); + call_hooks('reverse_magic_auth', $arr); + + try { + require_once('library/openid/openid.php'); + $openid = new LightOpenID(z_root()); + $openid->identity = $address; + $openid->returnUrl = z_root() . '/openid'; + $openid->required = array('namePerson/friendly', 'namePerson'); + $openid->optional = array('namePerson/first','media/image/aspect11','media/image/default'); + goaway($openid->authUrl()); + } catch (Exception $e) { + notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'

    '. t('The error message was:').' '.$e->getMessage()); + } + + // if they're still here... + notice( t('Authentication failed.') . EOL); + return; + } + else { + + // Presumed Red identity. Perform reverse magic auth + + if(strpos($address,'@') === false) { + notice('Invalid address.'); + return; + } + + $r = null; + if($address) { + $r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1", + dbesc($address) + ); + } + if($r) { + $url = $r[0]['hubloc_url']; + } + else { + $url = 'https://' . substr($address,strpos($address,'@')+1); + } + + if($url) { + if($_SESSION['return_url']) + $dest = urlencode(z_root() . '/' . str_replace('zid=','zid_=',$_SESSION['return_url'])); + else + $dest = urlencode(z_root() . '/' . str_replace('zid=','zid_=',\App::$query_string)); + + goaway($url . '/magic' . '?f=&dest=' . $dest); + } + } + } + + + function get() { + + $o = replace_macros(get_markup_template('rmagic.tpl'),array( + '$title' => t('Remote Authentication'), + '$desc' => t('Enter your channel address (e.g. channel@example.com)'), + '$submit' => t('Authenticate') + )); + return $o; + + } +} diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php new file mode 100644 index 000000000..195949e1c --- /dev/null +++ b/Zotlabs/Module/Rpost.php @@ -0,0 +1,144 @@ + $arg) { + $url .= '&' . $key . '=' . $arg; + } + goaway($url); + } + } + + // The login procedure is going to bugger our $_REQUEST variables + // so save them in the session. + + if(array_key_exists('body',$_REQUEST)) { + $_SESSION['rpost'] = $_REQUEST; + } + return login(); + } + + // If we have saved rpost session variables, but nothing in the current $_REQUEST, recover the saved variables + + if((! array_key_exists('body',$_REQUEST)) && (array_key_exists('rpost',$_SESSION))) { + $_REQUEST = $_SESSION['rpost']; + unset($_SESSION['rpost']); + } + + if(array_key_exists('channel',$_REQUEST)) { + $r = q("select channel_id from channel where channel_account_id = %d and channel_address = '%s' limit 1", + intval(get_account_id()), + dbesc($_REQUEST['channel']) + ); + if($r) { + require_once('include/security.php'); + $change = change_channel($r[0]['channel_id']); + } + } + + if($_REQUEST['remote_return']) { + $_SESSION['remote_return'] = $_REQUEST['remote_return']; + } + if(argc() > 1 && argv(1) === 'return') { + if($_SESSION['remote_return']) + goaway($_SESSION['remote_return']); + goaway(z_root() . '/network'); + } + + $plaintext = true; + // if(feature_enabled(local_channel(),'richtext')) + // $plaintext = false; + + if(array_key_exists('type', $_REQUEST) && $_REQUEST['type'] === 'html') { + require_once('include/html2bbcode.php'); + $_REQUEST['body'] = html2bbcode($_REQUEST['body']); + } + + $channel = \App::get_channel(); + + + $acl = new \Zotlabs\Access\AccessList($channel); + + $channel_acl = $acl->get(); + + if($_REQUEST['url']) { + $x = z_fetch_url(z_root() . '/linkinfo?f=&url=' . urlencode($_REQUEST['url'])); + if($x['success']) + $_REQUEST['body'] = $_REQUEST['body'] . $x['body']; + } + + $x = array( + 'is_owner' => true, + 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), + 'default_location' => $channel['channel_location'], + 'nickname' => $channel['channel_address'], + 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), + 'acl' => populate_acl($channel_acl,true,(($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')), + 'bang' => '', + 'visitor' => true, + 'profile_uid' => local_channel(), + 'title' => $_REQUEST['title'], + 'body' => $_REQUEST['body'], + 'attachment' => $_REQUEST['attachment'], + 'source' => ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''), + 'return_path' => 'rpost/return', + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + + $editor = status_editor($a,$x); + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit post'), + '$editor' => $editor + )); + + return $o; + + } + + + +} diff --git a/Zotlabs/Module/Rsd_xml.php b/Zotlabs/Module/Rsd_xml.php new file mode 100644 index 000000000..114ecc49b --- /dev/null +++ b/Zotlabs/Module/Rsd_xml.php @@ -0,0 +1,29 @@ + + + + Red + http://friendica.com/ + + + + http://status.net/wiki/TwitterCompatibleAPI + false + + + + + + '; + die(); + } +} diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php new file mode 100644 index 000000000..9941ebbd2 --- /dev/null +++ b/Zotlabs/Module/Search.php @@ -0,0 +1,228 @@ +' . "\r\n"; + + $o = '
    ' . "\r\n"; + + $o .= '

    ' . t('Search') . '

    '; + + if(x(\App::$data,'search')) + $search = trim(\App::$data['search']); + else + $search = ((x($_GET,'search')) ? trim(rawurldecode($_GET['search'])) : ''); + + $tag = false; + if(x($_GET,'tag')) { + $tag = true; + $search = ((x($_GET,'tag')) ? trim(rawurldecode($_GET['tag'])) : ''); + } + + if((! local_channel()) || (! feature_enabled(local_channel(),'savedsearch'))) + $o .= search($search,'search-box','/search',((local_channel()) ? true : false)); + + if(strpos($search,'#') === 0) { + $tag = true; + $search = substr($search,1); + } + if(strpos($search,'@') === 0) { + $search = substr($search,1); + goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); + } + if(strpos($search,'?') === 0) { + $search = substr($search,1); + goaway(z_root() . '/help' . '?f=1&navsearch=1&search=' . $search); + } + + // look for a naked webbie + if(strpos($search,'@') !== false) { + goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); + } + + if(! $search) + return $o; + + if($tag) { + $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and type in ( %d , %d) and term = '%s') ", + intval(TERM_OBJ_POST), + intval(TERM_HASHTAG), + intval(TERM_COMMUNITYTAG), + dbesc(protect_sprintf($search)) + ); + } + else { + $regstr = db_getfunc('REGEXP'); + $sql_extra = sprintf(" AND `item`.`body` $regstr '%s' ", dbesc(protect_sprintf(preg_quote($search)))); + } + + // Here is the way permissions work in the search module... + // Only public posts can be shown + // OR your own posts if you are a logged in member + // No items will be shown if the member has a blocked profile wall. + + if((! $update) && (! $load)) { + + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, + // because browser prefetching might change it on us. We have to deliver it with the page. + + $o .= '' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'search', + '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '0', + '$cmax' => '0', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$fh' => '0', + '$nouveau' => '0', + '$wall' => '0', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$search' => (($tag) ? urlencode('#') : '') . $search, + '$order' => '', + '$file' => '', + '$cats' => '', + '$tags' => '', + '$mid' => '', + '$verb' => '', + '$dend' => '', + '$dbegin' => '' + )); + + + } + + $item_normal = item_normal(); + $pub_sql = public_permissions_sql($observer_hash); + + require_once('include/identity.php'); + + $sys = get_sys_channel(); + + if(($update) && ($load)) { + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + + // in case somebody turned off public access to sys channel content with permissions + + if(! perm_is_allowed($sys['channel_id'],$observer_hash,'view_stream')) + $sys['xchan_hash'] .= 'disabled'; + + if($load) { + $r = null; + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $prefix = 'distinct on (created, mid)'; + $suffix = 'ORDER BY created DESC, mid'; + } else { + $prefix = 'distinct'; + $suffix = 'group by mid ORDER BY created DESC'; + } + if(local_channel()) { + $r = q("SELECT $prefix mid, item.id as item_id, item.* from item + WHERE ((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND item_private = 0 ) + OR ( `item`.`uid` = %d )) OR item.owner_xchan = '%s' ) + $item_normal + $sql_extra + $suffix $pager_sql ", + intval(local_channel()), + dbesc($sys['xchan_hash']) + ); + } + if($r === null) { + $r = q("SELECT $prefix mid, item.id as item_id, item.* from item + WHERE (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' + AND `item`.`deny_gid` = '' AND item_private = 0 ) + and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) + $pub_sql ) OR owner_xchan = '%s') + $item_normal + $sql_extra + $suffix $pager_sql", + dbesc($sys['xchan_hash']) + ); + } + } + else { + $r = array(); + } + } + + if($r) { + xchan_query($r); + $items = fetch_post_tags($r,true); + } else { + $items = array(); + } + + + if($format == 'json') { + $result = array(); + require_once('include/conversation.php'); + foreach($items as $item) { + $item['html'] = bbcode($item['body']); + $x = encode_item($item); + $x['html'] = prepare_text($item['body'],$item['mimetype']); + $result[] = $x; + } + json_return_and_die(array('success' => true,'messages' => $result)); + } + + if($tag) + $o .= '

    ' . sprintf( t('Items tagged with: %s'),htmlspecialchars($search, ENT_COMPAT,'UTF-8')) . '

    '; + else + $o .= '

    ' . sprintf( t('Search results for: %s'),htmlspecialchars($search, ENT_COMPAT,'UTF-8')) . '

    '; + + $o .= conversation($a,$items,'search',$update,'client'); + + $o .= '
    '; + + return $o; + } + + +} diff --git a/Zotlabs/Module/Search_ac.php b/Zotlabs/Module/Search_ac.php new file mode 100644 index 000000000..78bcf374d --- /dev/null +++ b/Zotlabs/Module/Search_ac.php @@ -0,0 +1,82 @@ + $g['xchan_photo_s'], + "name" => '@'.$g['xchan_name'], + "id" => $g['abook_id'], + "link" => $g['xchan_url'], + "label" => '', + "nick" => '', + ); + } + } + + $r = q("select distinct term, tid, url from term where type in ( %d, %d ) $tag_sql_extra group by term order by term asc", + intval(TERM_HASHTAG), + intval(TERM_COMMUNITYTAG) + ); + + if(count($r)) { + foreach($r as $g) { + $results[] = array( + "photo" => z_root() . '/images/hashtag.png', + "name" => '#'.$g['term'], + "id" => $g['tid'], + "link" => $g['url'], + "label" => '', + "nick" => '', + ); + } + } + + header("content-type: application/json"); + $o = array( + 'start' => $start, + 'count' => $count, + 'items' => $results, + ); + echo json_encode($o); + + logger('search_ac: ' . print_r($x,true)); + + killme(); + } + + + +} diff --git a/Zotlabs/Module/Service_limits.php b/Zotlabs/Module/Service_limits.php new file mode 100644 index 000000000..2a1f78054 --- /dev/null +++ b/Zotlabs/Module/Service_limits.php @@ -0,0 +1,28 @@ + 1) && (argv(1) === 'oauth') && x($_POST,'remove')){ + check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); + + $key = $_POST['remove']; + q("DELETE FROM tokens WHERE id='%s' AND uid=%d", + dbesc($key), + local_channel()); + goaway(z_root()."/settings/oauth/"); + return; + } + + if((argc() > 2) && (argv(1) === 'oauth') && (argv(2) === 'edit'||(argv(2) === 'add')) && x($_POST,'submit')) { + + check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); + + $name = ((x($_POST,'name')) ? $_POST['name'] : ''); + $key = ((x($_POST,'key')) ? $_POST['key'] : ''); + $secret = ((x($_POST,'secret')) ? $_POST['secret'] : ''); + $redirect = ((x($_POST,'redirect')) ? $_POST['redirect'] : ''); + $icon = ((x($_POST,'icon')) ? $_POST['icon'] : ''); + $ok = true; + if($name == '') { + $ok = false; + notice( t('Name is required') . EOL); + } + if($key == '' || $secret == '') { + $ok = false; + notice( t('Key and Secret are required') . EOL); + } + + if($ok) { + if ($_POST['submit']==t("Update")){ + $r = q("UPDATE clients SET + client_id='%s', + pw='%s', + name='%s', + redirect_uri='%s', + icon='%s', + uid=%d + WHERE client_id='%s'", + dbesc($key), + dbesc($secret), + dbesc($name), + dbesc($redirect), + dbesc($icon), + intval(local_channel()), + dbesc($key)); + } else { + $r = q("INSERT INTO clients (client_id, pw, name, redirect_uri, icon, uid) + VALUES ('%s','%s','%s','%s','%s',%d)", + dbesc($key), + dbesc($secret), + dbesc($name), + dbesc($redirect), + dbesc($icon), + intval(local_channel()) + ); + $r = q("INSERT INTO xperm (xp_client, xp_channel, xp_perm) VALUES ('%s', %d, '%s') ", + dbesc($key), + intval(local_channel()), + dbesc('all') + ); + } + } + goaway(z_root()."/settings/oauth/"); + return; + } + + if((argc() > 1) && (argv(1) == 'featured')) { + check_form_security_token_redirectOnErr('/settings/featured', 'settings_featured'); + + call_hooks('feature_settings_post', $_POST); + + build_sync_packet(); + return; + } + + + + if((argc() > 1) && (argv(1) === 'features')) { + check_form_security_token_redirectOnErr('/settings/features', 'settings_features'); + + // Build list of features and check which are set + $features = get_features(); + $all_features = array(); + foreach($features as $k => $v) { + foreach($v as $f) + $all_features[] = $f[0]; + } + foreach($all_features as $k) { + if(x($_POST,"feature_$k")) + set_pconfig(local_channel(),'feature',$k, 1); + else + set_pconfig(local_channel(),'feature',$k, 0); + } + build_sync_packet(); + return; + } + + if((argc() > 1) && (argv(1) == 'display')) { + + check_form_security_token_redirectOnErr('/settings/display', 'settings_display'); + + $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : \App::$channel['channel_theme']); + $mobile_theme = ((x($_POST,'mobile_theme')) ? notags(trim($_POST['mobile_theme'])) : ''); + $preload_images = ((x($_POST,'preload_images')) ? intval($_POST['preload_images']) : 0); + $user_scalable = ((x($_POST,'user_scalable')) ? intval($_POST['user_scalable']) : 0); + $nosmile = ((x($_POST,'nosmile')) ? intval($_POST['nosmile']) : 0); + $title_tosource = ((x($_POST,'title_tosource')) ? intval($_POST['title_tosource']) : 0); + $channel_list_mode = ((x($_POST,'channel_list_mode')) ? intval($_POST['channel_list_mode']) : 0); + $network_list_mode = ((x($_POST,'network_list_mode')) ? intval($_POST['network_list_mode']) : 0); + + $channel_divmore_height = ((x($_POST,'channel_divmore_height')) ? intval($_POST['channel_divmore_height']) : 400); + if($channel_divmore_height < 50) + $channel_divmore_height = 50; + $network_divmore_height = ((x($_POST,'network_divmore_height')) ? intval($_POST['network_divmore_height']) : 400); + if($network_divmore_height < 50) + $network_divmore_height = 50; + + $browser_update = ((x($_POST,'browser_update')) ? intval($_POST['browser_update']) : 0); + $browser_update = $browser_update * 1000; + if($browser_update < 10000) + $browser_update = 10000; + + $itemspage = ((x($_POST,'itemspage')) ? intval($_POST['itemspage']) : 20); + if($itemspage > 100) + $itemspage = 100; + + + if ($mobile_theme == "---") + del_pconfig(local_channel(),'system','mobile_theme'); + else { + set_pconfig(local_channel(),'system','mobile_theme',$mobile_theme); + } + + set_pconfig(local_channel(),'system','preload_images',$preload_images); + set_pconfig(local_channel(),'system','user_scalable',$user_scalable); + set_pconfig(local_channel(),'system','update_interval', $browser_update); + set_pconfig(local_channel(),'system','itemspage', $itemspage); + set_pconfig(local_channel(),'system','no_smilies',1-intval($nosmile)); + set_pconfig(local_channel(),'system','title_tosource',$title_tosource); + set_pconfig(local_channel(),'system','channel_list_mode', $channel_list_mode); + set_pconfig(local_channel(),'system','network_list_mode', $network_list_mode); + set_pconfig(local_channel(),'system','channel_divmore_height', $channel_divmore_height); + set_pconfig(local_channel(),'system','network_divmore_height', $network_divmore_height); + + if ($theme == \App::$channel['channel_theme']){ + // call theme_post only if theme has not been changed + if( ($themeconfigfile = $this->get_theme_config_file($theme)) != null){ + require_once($themeconfigfile); + theme_post($a); + } + } + + $r = q("UPDATE channel SET channel_theme = '%s' WHERE channel_id = %d", + dbesc($theme), + intval(local_channel()) + ); + + call_hooks('display_settings_post', $_POST); + build_sync_packet(); + goaway(z_root() . '/settings/display' ); + return; // NOTREACHED + } + + + if(argc() > 1 && argv(1) === 'account') { + + check_form_security_token_redirectOnErr('/settings/account', 'settings_account'); + + call_hooks('account_settings_post', $_POST); + // call_hooks('settings_account', $_POST); + + $errs = array(); + + $email = ((x($_POST,'email')) ? trim(notags($_POST['email'])) : ''); + $account = \App::get_account(); + if($email != $account['account_email']) { + if(! valid_email($email)) + $errs[] = t('Not valid email.'); + $adm = trim(get_config('system','admin_email')); + if(($adm) && (strcasecmp($email,$adm) == 0)) { + $errs[] = t('Protected email address. Cannot change to that email.'); + $email = \App::$user['email']; + } + if(! $errs) { + $r = q("update account set account_email = '%s' where account_id = %d", + dbesc($email), + intval($account['account_id']) + ); + if(! $r) + $errs[] = t('System failure storing new email. Please try again.'); + } + } + + if($errs) { + foreach($errs as $err) + notice($err . EOL); + $errs = array(); + } + + + if((x($_POST,'npassword')) || (x($_POST,'confirm'))) { + + $origpass = trim($_POST['origpass']); + + require_once('include/auth.php'); + if(! account_verify_password($email,$origpass)) { + $errs[] = t('Password verification failed.'); + } + + $newpass = trim($_POST['npassword']); + $confirm = trim($_POST['confirm']); + + if($newpass != $confirm ) { + $errs[] = t('Passwords do not match. Password unchanged.'); + } + + if((! x($newpass)) || (! x($confirm))) { + $errs[] = t('Empty passwords are not allowed. Password unchanged.'); + } + + if(! $errs) { + $salt = random_string(32); + $password_encoded = hash('whirlpool', $salt . $newpass); + $r = q("update account set account_salt = '%s', account_password = '%s', account_password_changed = '%s' + where account_id = %d", + dbesc($salt), + dbesc($password_encoded), + dbesc(datetime_convert()), + intval(get_account_id()) + ); + if($r) + info( t('Password changed.') . EOL); + else + $errs[] = t('Password update failed. Please try again.'); + } + } + + + if($errs) { + foreach($errs as $err) + notice($err . EOL); + } + goaway(z_root() . '/settings/account' ); + } + + + check_form_security_token_redirectOnErr('/settings', 'settings'); + + call_hooks('settings_post', $_POST); + + $set_perms = ''; + + $role = ((x($_POST,'permissions_role')) ? notags(trim($_POST['permissions_role'])) : ''); + $oldrole = get_pconfig(local_channel(),'system','permissions_role'); + + if(($role != $oldrole) || ($role === 'custom')) { + + if($role === 'custom') { + $hide_presence = (((x($_POST,'hide_presence')) && (intval($_POST['hide_presence']) == 1)) ? 1: 0); + $publish = (((x($_POST,'profile_in_directory')) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0); + $def_group = ((x($_POST,'group-selection')) ? notags(trim($_POST['group-selection'])) : ''); + $r = q("update channel set channel_default_group = '%s' where channel_id = %d", + dbesc($def_group), + intval(local_channel()) + ); + + $global_perms = get_perms(); + + foreach($global_perms as $k => $v) { + $set_perms .= ', ' . $v[0] . ' = ' . intval($_POST[$k]) . ' '; + } + $acl = new \Zotlabs\Access\AccessList($channel); + $acl->set_from_array($_POST); + $x = $acl->get(); + + $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', + channel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", + dbesc($x['allow_cid']), + dbesc($x['allow_gid']), + dbesc($x['deny_cid']), + dbesc($x['deny_gid']), + intval(local_channel()) + ); + } + else { + $role_permissions = get_role_perms($_POST['permissions_role']); + if(! $role_permissions) { + notice('Permissions category could not be found.'); + return; + } + $hide_presence = 1 - (intval($role_permissions['online'])); + if($role_permissions['default_collection']) { + $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + intval(local_channel()), + dbesc( t('Friends') ) + ); + if(! $r) { + require_once('include/group.php'); + group_add(local_channel(), t('Friends')); + group_add_member(local_channel(),t('Friends'),$channel['channel_hash']); + $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + intval(local_channel()), + dbesc( t('Friends') ) + ); + } + if($r) { + q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", + dbesc($r[0]['hash']), + dbesc('<' . $r[0]['hash'] . '>'), + intval(local_channel()) + ); + } + else { + notice( sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL); + return; + } + } + // no default collection + else { + q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', + channel_deny_cid = '' where channel_id = %d", + intval(local_channel()) + ); + } + + $r = q("update abook set abook_my_perms = %d where abook_channel = %d and abook_self = 1", + intval((array_key_exists('perms_accept',$role_permissions)) ? $role_permissions['perms_accept'] : 0), + intval(local_channel()) + ); + set_pconfig(local_channel(),'system','autoperms',(($role_permissions['perms_auto']) ? intval($role_permissions['perms_accept']) : 0)); + + foreach($role_permissions as $p => $v) { + if(strpos($p,'channel_') !== false) { + $set_perms .= ', ' . $p . ' = ' . intval($v) . ' '; + } + if($p === 'directory_publish') { + $publish = intval($v); + } + } + } + + set_pconfig(local_channel(),'system','hide_online_status',$hide_presence); + set_pconfig(local_channel(),'system','permissions_role',$role); + } + + $username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : ''); + $timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : ''); + $defloc = ((x($_POST,'defloc')) ? notags(trim($_POST['defloc'])) : ''); + $openid = ((x($_POST,'openid_url')) ? notags(trim($_POST['openid_url'])) : ''); + $maxreq = ((x($_POST,'maxreq')) ? intval($_POST['maxreq']) : 0); + $expire = ((x($_POST,'expire')) ? intval($_POST['expire']) : 0); + $evdays = ((x($_POST,'evdays')) ? intval($_POST['evdays']) : 3); + $photo_path = ((x($_POST,'photo_path')) ? escape_tags(trim($_POST['photo_path'])) : ''); + $attach_path = ((x($_POST,'attach_path')) ? escape_tags(trim($_POST['attach_path'])) : ''); + + $channel_menu = ((x($_POST['channel_menu'])) ? htmlspecialchars_decode(trim($_POST['channel_menu']),ENT_QUOTES) : ''); + + $expire_items = ((x($_POST,'expire_items')) ? intval($_POST['expire_items']) : 0); + $expire_starred = ((x($_POST,'expire_starred')) ? intval($_POST['expire_starred']) : 0); + $expire_photos = ((x($_POST,'expire_photos'))? intval($_POST['expire_photos']) : 0); + $expire_network_only = ((x($_POST,'expire_network_only'))? intval($_POST['expire_network_only']) : 0); + + $allow_location = (((x($_POST,'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1: 0); + + $blocktags = (((x($_POST,'blocktags')) && (intval($_POST['blocktags']) == 1)) ? 0: 1); // this setting is inverted! + $unkmail = (((x($_POST,'unkmail')) && (intval($_POST['unkmail']) == 1)) ? 1: 0); + $cntunkmail = ((x($_POST,'cntunkmail')) ? intval($_POST['cntunkmail']) : 0); + $suggestme = ((x($_POST,'suggestme')) ? intval($_POST['suggestme']) : 0); + + $post_newfriend = (($_POST['post_newfriend'] == 1) ? 1: 0); + $post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0); + $post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0); + $adult = (($_POST['adult'] == 1) ? 1 : 0); + + $cal_first_day = (((x($_POST,'first_day')) && (intval($_POST['first_day']) == 1)) ? 1: 0); + + $channel = \App::get_channel(); + $pageflags = $channel['channel_pageflags']; + $existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0); + if($adult != $existing_adult) + $pageflags = ($pageflags ^ PAGE_ADULT); + + + $notify = 0; + + if(x($_POST,'notify1')) + $notify += intval($_POST['notify1']); + if(x($_POST,'notify2')) + $notify += intval($_POST['notify2']); + if(x($_POST,'notify3')) + $notify += intval($_POST['notify3']); + if(x($_POST,'notify4')) + $notify += intval($_POST['notify4']); + if(x($_POST,'notify5')) + $notify += intval($_POST['notify5']); + if(x($_POST,'notify6')) + $notify += intval($_POST['notify6']); + if(x($_POST,'notify7')) + $notify += intval($_POST['notify7']); + if(x($_POST,'notify8')) + $notify += intval($_POST['notify8']); + + + $vnotify = 0; + + if(x($_POST,'vnotify1')) + $vnotify += intval($_POST['vnotify1']); + if(x($_POST,'vnotify2')) + $vnotify += intval($_POST['vnotify2']); + if(x($_POST,'vnotify3')) + $vnotify += intval($_POST['vnotify3']); + if(x($_POST,'vnotify4')) + $vnotify += intval($_POST['vnotify4']); + if(x($_POST,'vnotify5')) + $vnotify += intval($_POST['vnotify5']); + if(x($_POST,'vnotify6')) + $vnotify += intval($_POST['vnotify6']); + if(x($_POST,'vnotify7')) + $vnotify += intval($_POST['vnotify7']); + if(x($_POST,'vnotify8')) + $vnotify += intval($_POST['vnotify8']); + if(x($_POST,'vnotify9')) + $vnotify += intval($_POST['vnotify9']); + if(x($_POST,'vnotify10')) + $vnotify += intval($_POST['vnotify10']); + if(x($_POST,'vnotify11')) + $vnotify += intval($_POST['vnotify11']); + + $always_show_in_notices = x($_POST,'always_show_in_notices') ? 1 : 0; + + $channel = \App::get_channel(); + + $err = ''; + + $name_change = false; + + if($username != $channel['channel_name']) { + $name_change = true; + require_once('include/identity.php'); + $err = validate_channelname($username); + if($err) { + notice($err); + return; + } + } + + if($timezone != $channel['channel_timezone']) { + if(strlen($timezone)) + date_default_timezone_set($timezone); + } + + set_pconfig(local_channel(),'system','use_browser_location',$allow_location); + set_pconfig(local_channel(),'system','suggestme', $suggestme); + set_pconfig(local_channel(),'system','post_newfriend', $post_newfriend); + set_pconfig(local_channel(),'system','post_joingroup', $post_joingroup); + set_pconfig(local_channel(),'system','post_profilechange', $post_profilechange); + set_pconfig(local_channel(),'system','blocktags',$blocktags); + set_pconfig(local_channel(),'system','channel_menu',$channel_menu); + set_pconfig(local_channel(),'system','vnotify',$vnotify); + set_pconfig(local_channel(),'system','always_show_in_notices',$always_show_in_notices); + set_pconfig(local_channel(),'system','evdays',$evdays); + set_pconfig(local_channel(),'system','photo_path',$photo_path); + set_pconfig(local_channel(),'system','attach_path',$attach_path); + set_pconfig(local_channel(),'system','cal_first_day',$cal_first_day); + + $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d", + dbesc($username), + intval($pageflags), + dbesc($timezone), + dbesc($defloc), + intval($notify), + intval($unkmail), + intval($maxreq), + intval($expire), + intval(local_channel()) + ); + if($r) + info( t('Settings updated.') . EOL); + + if(! is_null($publish)) { + $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", + intval($publish), + intval(local_channel()) + ); + } + + if($name_change) { + $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", + dbesc($username), + dbesc(datetime_convert()), + dbesc($channel['channel_hash']) + ); + $r = q("update profile set name = '%s' where uid = %d and is_default = 1", + dbesc($username), + intval($channel['channel_id']) + ); + } + + proc_run('php','include/directory.php',local_channel()); + + build_sync_packet(); + + + //$_SESSION['theme'] = $theme; + if($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) { + + // FIXME - set to un-verified, blocked and redirect to logout + // Why? Are we verifying people or email addresses? + + } + + goaway(z_root() . '/settings' ); + return; // NOTREACHED + } + + + + function get() { + + $o = ''; + nav_set_selected('settings'); + + + if((! local_channel()) || ($_SESSION['delegate'])) { + notice( t('Permission denied.') . EOL ); + return login(); + } + + + $channel = \App::get_channel(); + if($channel) + head_set_icon($channel['xchan_photo_s']); + + $yes_no = array(t('No'),t('Yes')); + + if((argc() > 1) && (argv(1) === 'oauth')) { + + if((argc() > 2) && (argv(2) === 'add')) { + $tpl = get_markup_template("settings_oauth_edit.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth"), + '$title' => t('Add application'), + '$submit' => t('Submit'), + '$cancel' => t('Cancel'), + '$name' => array('name', t('Name'), '', t('Name of application')), + '$key' => array('key', t('Consumer Key'), random_string(16), t('Automatically generated - change if desired. Max length 20')), + '$secret' => array('secret', t('Consumer Secret'), random_string(16), t('Automatically generated - change if desired. Max length 20')), + '$redirect' => array('redirect', t('Redirect'), '', t('Redirect URI - leave blank unless your application specifically requires this')), + '$icon' => array('icon', t('Icon url'), '', t('Optional')), + )); + return $o; + } + + if((argc() > 3) && (argv(2) === 'edit')) { + $r = q("SELECT * FROM clients WHERE client_id='%s' AND uid=%d", + dbesc(argv(3)), + local_channel()); + + if (!count($r)){ + notice(t('Application not found.')); + return; + } + $app = $r[0]; + + $tpl = get_markup_template("settings_oauth_edit.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth"), + '$title' => t('Add application'), + '$submit' => t('Update'), + '$cancel' => t('Cancel'), + '$name' => array('name', t('Name'), $app['name'] , ''), + '$key' => array('key', t('Consumer Key'), $app['client_id'], ''), + '$secret' => array('secret', t('Consumer Secret'), $app['pw'], ''), + '$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], ''), + '$icon' => array('icon', t('Icon url'), $app['icon'], ''), + )); + return $o; + } + + if((argc() > 3) && (argv(2) === 'delete')) { + check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth', 't'); + + $r = q("DELETE FROM clients WHERE client_id='%s' AND uid=%d", + dbesc(argv(3)), + local_channel()); + goaway(z_root()."/settings/oauth/"); + return; + } + + + $r = q("SELECT clients.*, tokens.id as oauth_token, (clients.uid=%d) AS my + FROM clients + LEFT JOIN tokens ON clients.client_id=tokens.client_id + WHERE clients.uid IN (%d,0)", + local_channel(), + local_channel()); + + + $tpl = get_markup_template("settings_oauth.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth"), + '$baseurl' => z_root(), + '$title' => t('Connected Apps'), + '$add' => t('Add application'), + '$edit' => t('Edit'), + '$delete' => t('Delete'), + '$consumerkey' => t('Client key starts with'), + '$noname' => t('No name'), + '$remove' => t('Remove authorization'), + '$apps' => $r, + )); + return $o; + + } + if((argc() > 1) && (argv(1) === 'featured')) { + $settings_addons = ""; + + $o = ''; + + $r = q("SELECT * FROM `hook` WHERE `hook` = 'feature_settings' "); + if(! $r) + $settings_addons = t('No feature settings configured'); + + call_hooks('feature_settings', $settings_addons); + + $tpl = get_markup_template("settings_addons.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_featured"), + '$title' => t('Feature/Addon Settings'), + '$settings_addons' => $settings_addons + )); + return $o; + } + + + /* + * ACCOUNT SETTINGS + */ + + + if((argc() > 1) && (argv(1) === 'account')) { + $account_settings = ""; + + call_hooks('account_settings', $account_settings); + + $email = \App::$account['account_email']; + + + $tpl = get_markup_template("settings_account.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_account"), + '$title' => t('Account Settings'), + '$origpass' => array('origpass', t('Current Password'), ' ',''), + '$password1'=> array('npassword', t('Enter New Password'), '', ''), + '$password2'=> array('confirm', t('Confirm New Password'), '', t('Leave password fields blank unless changing')), + '$submit' => t('Submit'), + '$email' => array('email', t('Email Address:'), $email, ''), + '$removeme' => t('Remove Account'), + '$removeaccount' => t('Remove this account including all its channels'), + '$account_settings' => $account_settings + )); + return $o; + } + + + + if((argc() > 1) && (argv(1) === 'features')) { + $arr = array(); + $features = get_features(); + + foreach($features as $fname => $fdata) { + $arr[$fname] = array(); + $arr[$fname][0] = $fdata[0]; + foreach(array_slice($fdata,1) as $f) { + $arr[$fname][1][] = array('feature_' .$f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); + } + } + + $tpl = get_markup_template("settings_features.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_features"), + '$title' => t('Additional Features'), + '$features' => $arr, + '$submit' => t('Submit'), + )); + + return $o; + } + + + + + + if((argc() > 1) && (argv(1) === 'connectors')) { + + $settings_connectors = ""; + + call_hooks('connector_settings', $settings_connectors); + + $r = null; + + $tpl = get_markup_template("settings_connectors.tpl"); + + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_connectors"), + '$title' => t('Connector Settings'), + '$submit' => t('Submit'), + '$settings_connectors' => $settings_connectors + )); + + call_hooks('display_settings', $o); + return $o; + } + + /* + * DISPLAY SETTINGS + */ + + if((argc() > 1) && (argv(1) === 'display')) { + $default_theme = get_config('system','theme'); + if(! $default_theme) + $default_theme = 'default'; + $default_mobile_theme = get_config('system','mobile_theme'); + if(! $mobile_default_theme) + $mobile_default_theme = 'none'; + + $allowed_themes_str = get_config('system','allowed_themes'); + $allowed_themes_raw = explode(',',$allowed_themes_str); + $allowed_themes = array(); + if(count($allowed_themes_raw)) + foreach($allowed_themes_raw as $x) + if(strlen(trim($x)) && is_dir("view/theme/$x")) + $allowed_themes[] = trim($x); + + + $themes = array(); + $files = glob('view/theme/*'); + if($allowed_themes) { + foreach($allowed_themes as $th) { + $f = $th; + $is_experimental = file_exists('view/theme/' . $th . '/experimental'); + $unsupported = file_exists('view/theme/' . $th . '/unsupported'); + $is_mobile = file_exists('view/theme/' . $th . '/mobile'); + $is_library = file_exists('view/theme/'. $th . '/library'); + $mobile_themes["---"] = t("No special theme for mobile devices"); + + if (!$is_experimental or ($is_experimental && (get_config('experimentals','exp_themes')==1 or get_config('experimentals','exp_themes')===false))){ + $theme_name = (($is_experimental) ? sprintf(t('%s - (Experimental)'), $f) : $f); + if (! $is_library) { + if($is_mobile) { + $mobile_themes[$f] = $themes[$f] = $theme_name . ' (' . t('mobile') . ')'; + } + else { + $mobile_themes[$f] = $themes[$f] = $theme_name; + } + } + } + + } + } + $theme_selected = (!x($_SESSION,'theme')? $default_theme : $_SESSION['theme']); + $mobile_theme_selected = (!x($_SESSION,'mobile_theme')? $default_mobile_theme : $_SESSION['mobile_theme']); + + $preload_images = get_pconfig(local_channel(),'system','preload_images'); + $preload_images = (($preload_images===false)? '0': $preload_images); // default if not set: 0 + + $user_scalable = get_pconfig(local_channel(),'system','user_scalable'); + $user_scalable = (($user_scalable===false)? '1': $user_scalable); // default if not set: 1 + + $browser_update = intval(get_pconfig(local_channel(), 'system','update_interval')); + $browser_update = (($browser_update == 0) ? 80 : $browser_update / 1000); // default if not set: 40 seconds + + $itemspage = intval(get_pconfig(local_channel(), 'system','itemspage')); + $itemspage = (($itemspage > 0 && $itemspage < 101) ? $itemspage : 20); // default if not set: 20 items + + $nosmile = get_pconfig(local_channel(),'system','no_smilies'); + $nosmile = (($nosmile===false)? '0': $nosmile); // default if not set: 0 + + $title_tosource = get_pconfig(local_channel(),'system','title_tosource'); + $title_tosource = (($title_tosource===false)? '0': $title_tosource); // default if not set: 0 + + $theme_config = ""; + if( ($themeconfigfile = $this->get_theme_config_file($theme_selected)) != null){ + require_once($themeconfigfile); + $theme_config = theme_content($a); + } + + $tpl = get_markup_template("settings_display.tpl"); + $o = replace_macros($tpl, array( + '$ptitle' => t('Display Settings'), + '$d_tset' => t('Theme Settings'), + '$d_ctset' => t('Custom Theme Settings'), + '$d_cset' => t('Content Settings'), + '$form_security_token' => get_form_security_token("settings_display"), + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$uid' => local_channel(), + + '$theme' => (($themes) ? array('theme', t('Display Theme:'), $theme_selected, '', $themes, 'preview') : false), + '$mobile_theme' => (($mobile_themes) ? array('mobile_theme', t('Mobile Theme:'), $mobile_theme_selected, '', $mobile_themes, '') : false), + '$preload_images' => array('preload_images', t("Preload images before rendering the page"), $preload_images, t("The subjective page load time will be longer but the page will be ready when displayed"), $yes_no), + '$user_scalable' => array('user_scalable', t("Enable user zoom on mobile devices"), $user_scalable, '', $yes_no), + '$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')), + '$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 100 items')), + '$nosmile' => array('nosmile', t("Show emoticons (smilies) as images"), 1-intval($nosmile), '', $yes_no), + '$title_tosource' => array('title_tosource', t("Link post titles to source"), $title_tosource, '', $yes_no), + '$layout_editor' => t('System Page Layout Editor - (advanced)'), + '$theme_config' => $theme_config, + '$expert' => feature_enabled(local_channel(),'expert'), + '$channel_list_mode' => array('channel_list_mode', t('Use blog/list mode on channel page'), get_pconfig(local_channel(),'system','channel_list_mode'), t('(comments displayed separately)'), $yes_no), + '$network_list_mode' => array('network_list_mode', t('Use blog/list mode on grid page'), get_pconfig(local_channel(),'system','network_list_mode'), t('(comments displayed separately)'), $yes_no), + '$channel_divmore_height' => array('channel_divmore_height', t('Channel page max height of content (in pixels)'), ((get_pconfig(local_channel(),'system','channel_divmore_height')) ? get_pconfig(local_channel(),'system','channel_divmore_height') : 400), t('click to expand content exceeding this height')), + '$network_divmore_height' => array('network_divmore_height', t('Grid page max height of content (in pixels)'), ((get_pconfig(local_channel(),'system','network_divmore_height')) ? get_pconfig(local_channel(),'system','network_divmore_height') : 400) , t('click to expand content exceeding this height')), + + + )); + + return $o; + } + + + + + + if(argv(1) === 'channel') { + + require_once('include/acl_selectors.php'); + require_once('include/permissions.php'); + + + $p = q("SELECT * FROM `profile` WHERE `is_default` = 1 AND `uid` = %d LIMIT 1", + intval(local_channel()) + ); + if(count($p)) + $profile = $p[0]; + + load_pconfig(local_channel(),'expire'); + + $channel = \App::get_channel(); + + + $global_perms = get_perms(); + + $permiss = array(); + + $perm_opts = array( + array( t('Nobody except yourself'), 0), + array( t('Only those you specifically allow'), PERMS_SPECIFIC), + array( t('Approved connections'), PERMS_CONTACTS), + array( t('Any connections'), PERMS_PENDING), + array( t('Anybody on this website'), PERMS_SITE), + array( t('Anybody in this network'), PERMS_NETWORK), + array( t('Anybody authenticated'), PERMS_AUTHED), + array( t('Anybody on the internet'), PERMS_PUBLIC) + ); + + + foreach($global_perms as $k => $perm) { + $options = array(); + foreach($perm_opts as $opt) { + if((! $perm[2]) && $opt[1] == PERMS_PUBLIC) + continue; + $options[$opt[1]] = $opt[0]; + } + $permiss[] = array($k,$perm[3],$channel[$perm[0]],$perm[4],$options); + } + + + // logger('permiss: ' . print_r($permiss,true)); + + + + $username = $channel['channel_name']; + $nickname = $channel['channel_address']; + $timezone = $channel['channel_timezone']; + $notify = $channel['channel_notifyflags']; + $defloc = $channel['channel_location']; + + $maxreq = $channel['channel_max_friend_req']; + $expire = $channel['channel_expire_days']; + $adult_flag = intval($channel['channel_pageflags'] & PAGE_ADULT); + $sys_expire = get_config('system','default_expire_days'); + + // $unkmail = \App::$user['unkmail']; + // $cntunkmail = \App::$user['cntunkmail']; + + $hide_presence = intval(get_pconfig(local_channel(), 'system','hide_online_status')); + + + $expire_items = get_pconfig(local_channel(), 'expire','items'); + $expire_items = (($expire_items===false)? '1' : $expire_items); // default if not set: 1 + + $expire_notes = get_pconfig(local_channel(), 'expire','notes'); + $expire_notes = (($expire_notes===false)? '1' : $expire_notes); // default if not set: 1 + + $expire_starred = get_pconfig(local_channel(), 'expire','starred'); + $expire_starred = (($expire_starred===false)? '1' : $expire_starred); // default if not set: 1 + + $expire_photos = get_pconfig(local_channel(), 'expire','photos'); + $expire_photos = (($expire_photos===false)? '0' : $expire_photos); // default if not set: 0 + + $expire_network_only = get_pconfig(local_channel(), 'expire','network_only'); + $expire_network_only = (($expire_network_only===false)? '0' : $expire_network_only); // default if not set: 0 + + + $suggestme = get_pconfig(local_channel(), 'system','suggestme'); + $suggestme = (($suggestme===false)? '0': $suggestme); // default if not set: 0 + + $post_newfriend = get_pconfig(local_channel(), 'system','post_newfriend'); + $post_newfriend = (($post_newfriend===false)? '0': $post_newfriend); // default if not set: 0 + + $post_joingroup = get_pconfig(local_channel(), 'system','post_joingroup'); + $post_joingroup = (($post_joingroup===false)? '0': $post_joingroup); // default if not set: 0 + + $post_profilechange = get_pconfig(local_channel(), 'system','post_profilechange'); + $post_profilechange = (($post_profilechange===false)? '0': $post_profilechange); // default if not set: 0 + + $blocktags = get_pconfig(local_channel(),'system','blocktags'); + $blocktags = (($blocktags===false) ? '0' : $blocktags); + + $timezone = date_default_timezone_get(); + + $opt_tpl = get_markup_template("field_checkbox.tpl"); + if(get_config('system','publish_all')) { + $profile_in_dir = ''; + } + else { + $profile_in_dir = replace_macros($opt_tpl,array( + '$field' => array('profile_in_directory', t('Publish your default profile in the network directory'), $profile['publish'], '', $yes_no), + )); + } + + $suggestme = replace_macros($opt_tpl,array( + '$field' => array('suggestme', t('Allow us to suggest you as a potential friend to new members?'), $suggestme, '', $yes_no), + + )); + + $subdir = ((strlen(\App::get_path())) ? '
    ' . t('or') . ' ' . z_root() . '/channel/' . $nickname : ''); + + $tpl_addr = get_markup_template("settings_nick_set.tpl"); + + $prof_addr = replace_macros($tpl_addr,array( + '$desc' => t('Your channel address is'), + '$nickname' => $nickname, + '$subdir' => $subdir, + '$basepath' => \App::get_hostname() + )); + + $stpl = get_markup_template('settings.tpl'); + + $acl = new \Zotlabs\Access\AccessList($channel); + $perm_defaults = $acl->get(); + + require_once('include/group.php'); + $group_select = mini_group_select(local_channel(),$channel['channel_default_group']); + + require_once('include/menu.php'); + $m1 = menu_list(local_channel()); + $menu = false; + if($m1) { + $menu = array(); + $current = get_pconfig(local_channel(),'system','channel_menu'); + $menu[] = array('name' => '', 'selected' => ((! $current) ? true : false)); + foreach($m1 as $m) { + $menu[] = array('name' => htmlspecialchars($m['menu_name'],ENT_COMPAT,'UTF-8'), 'selected' => (($m['menu_name'] === $current) ? ' selected="selected" ' : false)); + } + } + + $evdays = get_pconfig(local_channel(),'system','evdays'); + if(! $evdays) + $evdays = 3; + + $permissions_role = get_pconfig(local_channel(),'system','permissions_role'); + if(! $permissions_role) + $permissions_role = 'custom'; + + $permissions_set = (($permissions_role != 'custom') ? true : false); + + $vnotify = get_pconfig(local_channel(),'system','vnotify'); + $always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices'); + if($vnotify === false) + $vnotify = (-1); + + $o .= replace_macros($stpl,array( + '$ptitle' => t('Channel Settings'), + + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$uid' => local_channel(), + '$form_security_token' => get_form_security_token("settings"), + '$nickname_block' => $prof_addr, + '$h_basic' => t('Basic Settings'), + '$username' => array('username', t('Full Name:'), $username,''), + '$email' => array('email', t('Email Address:'), $email, ''), + '$timezone' => array('timezone_select' , t('Your Timezone:'), $timezone, '', get_timezones()), + '$defloc' => array('defloc', t('Default Post Location:'), $defloc, t('Geographical location to display on your posts')), + '$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_channel(),'system','use_browser_location')) ? 1 : ''), '', $yes_no), + + '$adult' => array('adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)'), $yes_no), + + '$h_prv' => t('Security and Privacy Settings'), + '$permissions_set' => $permissions_set, + '$server_role' => \Zotlabs\Project\System::get_server_role(), + '$perms_set_msg' => t('Your permissions are already configured. Click to view/adjust'), + + '$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online'), $yes_no), + + '$lbl_pmacro' => t('Simple Privacy Settings:'), + '$pmacro3' => t('Very Public - extremely permissive (should be used with caution)'), + '$pmacro2' => t('Typical - default public, privacy when desired (similar to social network permissions but with improved privacy)'), + '$pmacro1' => t('Private - default private, never open or public'), + '$pmacro0' => t('Blocked - default blocked to/from everybody'), + '$permiss_arr' => $permiss, + '$blocktags' => array('blocktags',t('Allow others to tag your posts'), 1-$blocktags, t('Often used by the community to retro-actively flag inappropriate content'), $yes_no), + + '$lbl_p2macro' => t('Advanced Privacy Settings'), + + '$expire' => array('expire',t('Expire other channel content after this many days'),$expire,sprintf( t('0 or blank to use the website limit. The website expires after %d days.'),intval($sys_expire))), + '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), + '$permissions' => t('Default Post Permissions'), + '$permdesc' => t("\x28click to open/close\x29"), + '$aclselect' => populate_acl($perm_defaults,false), + '$suggestme' => $suggestme, + '$group_select' => $group_select, + '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()), + + '$profile_in_dir' => $profile_in_dir, + '$hide_friends' => $hide_friends, + '$hide_wall' => $hide_wall, + '$unkmail' => $unkmail, + '$cntunkmail' => array('cntunkmail', t('Maximum private messages per day from unknown people:'), intval($channel['channel_max_anon_mail']) ,t("Useful to reduce spamming")), + + + '$h_not' => t('Notification Settings'), + '$activity_options' => t('By default post a status message when:'), + '$post_newfriend' => array('post_newfriend', t('accepting a friend request'), $post_newfriend, '', $yes_no), + '$post_joingroup' => array('post_joingroup', t('joining a forum/community'), $post_joingroup, '', $yes_no), + '$post_profilechange' => array('post_profilechange', t('making an interesting profile change'), $post_profilechange, '', $yes_no), + '$lbl_not' => t('Send a notification email when:'), + '$notify1' => array('notify1', t('You receive a connection request'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, '', $yes_no), + '$notify2' => array('notify2', t('Your connections are confirmed'), ($notify & NOTIFY_CONFIRM), NOTIFY_CONFIRM, '', $yes_no), + '$notify3' => array('notify3', t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), NOTIFY_WALL, '', $yes_no), + '$notify4' => array('notify4', t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), NOTIFY_COMMENT, '', $yes_no), + '$notify5' => array('notify5', t('You receive a private message'), ($notify & NOTIFY_MAIL), NOTIFY_MAIL, '', $yes_no), + '$notify6' => array('notify6', t('You receive a friend suggestion'), ($notify & NOTIFY_SUGGEST), NOTIFY_SUGGEST, '', $yes_no), + '$notify7' => array('notify7', t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, '', $yes_no), + '$notify8' => array('notify8', t('You are poked/prodded/etc. in a post'), ($notify & NOTIFY_POKE), NOTIFY_POKE, '', $yes_no), + + + '$lbl_vnot' => t('Show visual notifications including:'), + + '$vnotify1' => array('vnotify1', t('Unseen grid activity'), ($vnotify & VNOTIFY_NETWORK), VNOTIFY_NETWORK, '', $yes_no), + '$vnotify2' => array('vnotify2', t('Unseen channel activity'), ($vnotify & VNOTIFY_CHANNEL), VNOTIFY_CHANNEL, '', $yes_no), + '$vnotify3' => array('vnotify3', t('Unseen private messages'), ($vnotify & VNOTIFY_MAIL), VNOTIFY_MAIL, t('Recommended'), $yes_no), + '$vnotify4' => array('vnotify4', t('Upcoming events'), ($vnotify & VNOTIFY_EVENT), VNOTIFY_EVENT, '', $yes_no), + '$vnotify5' => array('vnotify5', t('Events today'), ($vnotify & VNOTIFY_EVENTTODAY), VNOTIFY_EVENTTODAY, '', $yes_no), + '$vnotify6' => array('vnotify6', t('Upcoming birthdays'), ($vnotify & VNOTIFY_BIRTHDAY), VNOTIFY_BIRTHDAY, t('Not available in all themes'), $yes_no), + '$vnotify7' => array('vnotify7', t('System (personal) notifications'), ($vnotify & VNOTIFY_SYSTEM), VNOTIFY_SYSTEM, '', $yes_no), + '$vnotify8' => array('vnotify8', t('System info messages'), ($vnotify & VNOTIFY_INFO), VNOTIFY_INFO, t('Recommended'), $yes_no), + '$vnotify9' => array('vnotify9', t('System critical alerts'), ($vnotify & VNOTIFY_ALERT), VNOTIFY_ALERT, t('Recommended'), $yes_no), + '$vnotify10' => array('vnotify10', t('New connections'), ($vnotify & VNOTIFY_INTRO), VNOTIFY_INTRO, t('Recommended'), $yes_no), + '$vnotify11' => array('vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no), + '$always_show_in_notices' => array('always_show_in_notices', t('Also show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no), + + '$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')), + + '$h_advn' => t('Advanced Account/Page Type Settings'), + '$h_descadvn' => t('Change the behaviour of this account for special situations'), + '$pagetype' => $pagetype, + '$expert' => feature_enabled(local_channel(),'expert'), + '$hint' => t('Please enable expert mode (in Settings > Additional features) to adjust!'), + '$lbl_misc' => t('Miscellaneous Settings'), + '$photo_path' => array('photo_path', t('Default photo upload folder'), get_pconfig(local_channel(),'system','photo_path'), t('%Y - current year, %m - current month')), + '$attach_path' => array('attach_path', t('Default file upload folder'), get_pconfig(local_channel(),'system','attach_path'), t('%Y - current year, %m - current month')), + '$menus' => $menu, + '$menu_desc' => t('Personal menu to display in your channel pages'), + '$removeme' => t('Remove Channel'), + '$removechannel' => t('Remove this channel.'), + '$firefoxshare' => t('Firefox Share $Projectname provider'), + '$cal_first_day' => array('first_day', t('Start calendar week on monday'), ((get_pconfig(local_channel(),'system','cal_first_day')) ? 1 : ''), '', $yes_no), + )); + + call_hooks('settings_form',$o); + + $o .= '' . "\r\n"; + + return $o; + } + } + + function get_theme_config_file($theme){ + + $base_theme = \App::$theme_info['extends']; + + if (file_exists("view/theme/$theme/php/config.php")){ + return "view/theme/$theme/php/config.php"; + } + if (file_exists("view/theme/$base_theme/php/config.php")){ + return "view/theme/$base_theme/php/config.php"; + } + return null; + } + + +} diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php new file mode 100644 index 000000000..3ac67e1c0 --- /dev/null +++ b/Zotlabs/Module/Setup.php @@ -0,0 +1,754 @@ +install_wizard_pass = intval($_POST['pass']); + else + $this->install_wizard_pass = 1; + + } + + /** + * @brief Handle the actions of the different setup steps. + * + * @param[in,out] App &$a + */ + function post() { + global $db; + + switch($this->install_wizard_pass) { + case 1: + case 2: + return; + break; // just in case return don't return :) + case 3: + $urlpath = \App::get_path(); + $dbhost = trim($_POST['dbhost']); + $dbport = intval(trim($_POST['dbport'])); + $dbuser = trim($_POST['dbuser']); + $dbpass = trim($_POST['dbpass']); + $dbdata = trim($_POST['dbdata']); + $dbtype = intval(trim($_POST['dbtype'])); + $phpath = trim($_POST['phpath']); + $adminmail = trim($_POST['adminmail']); + $siteurl = trim($_POST['siteurl']); + $advanced = ((intval($_POST['advanced'])) ? 1 : 0); + + // $siteurl should not have a trailing slash + + $siteurl = rtrim($siteurl,'/'); + + require_once('include/dba/dba_driver.php'); + unset($db); + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); + + if(! $db->connected) { + echo 'Database Connect failed: ' . $db->error; + killme(); + \App::$data['db_conn_failed']=true; + } + /*if(get_db_errno()) { + unset($db); + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, '', true); + + if(! get_db_errno()) { + $r = q("CREATE DATABASE '%s'", + dbesc($dbdata) + ); + if($r) { + unset($db); + $db = new dba($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true); + } else { + \App::$data['db_create_failed']=true; + } + } else { + \App::$data['db_conn_failed']=true; + return; + } + }*/ + //if(get_db_errno()) { + + //} + + return; + break; + case 4: + $urlpath = \App::get_path(); + $dbhost = notags(trim($_POST['dbhost'])); + $dbport = intval(notags(trim($_POST['dbport']))); + $dbuser = notags(trim($_POST['dbuser'])); + $dbpass = notags(trim($_POST['dbpass'])); + $dbdata = notags(trim($_POST['dbdata'])); + $dbtype = intval(notags(trim($_POST['dbtype']))); + $phpath = notags(trim($_POST['phpath'])); + $timezone = notags(trim($_POST['timezone'])); + $adminmail = notags(trim($_POST['adminmail'])); + $siteurl = notags(trim($_POST['siteurl'])); + $advanced = ((intval($_POST['advanced'])) ? 1 : 0); + + if($siteurl != z_root()) { + $test = z_fetch_url($siteurl."/setup/testrewrite"); + if((! $test['success']) || ($test['body'] != 'ok')) { + \App::$data['url_fail'] = true; + \App::$data['url_error'] = $test['error']; + return; + } + } + + // connect to db + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); + + if(! $db->connected) { + echo 'CRITICAL: DB not connected.'; + killme(); + } + + $tpl = get_intltext_template('htconfig.tpl'); + $txt = replace_macros($tpl,array( + '$dbhost' => $dbhost, + '$dbport' => $dbport, + '$dbuser' => $dbuser, + '$dbpass' => $dbpass, + '$dbdata' => $dbdata, + '$dbtype' => $dbtype, + '$uno' => 1 - $advanced, + '$timezone' => $timezone, + '$siteurl' => $siteurl, + '$site_id' => random_string(), + '$phpath' => $phpath, + '$adminmail' => $adminmail + )); + + $result = file_put_contents('.htconfig.php', $txt); + if(! $result) { + \App::$data['txt'] = $txt; + } + + $errors = $this->load_database($db); + + if($errors) + \App::$data['db_failed'] = $errors; + else + \App::$data['db_installed'] = true; + + return; + break; + } + } + + function get_db_errno() { + if(class_exists('mysqli')) + return mysqli_connect_errno(); + else + return mysql_errno(); + } + + /** + * @brief Get output for the setup page. + * + * Depending on the state we are currently in it returns different content. + * + * @param App &$a + * @return string parsed HTML output + */ + function get() { + global $db; + + $o = ''; + $wizard_status = ''; + $install_title = t('$Projectname Server - Setup'); + + if(x(\App::$data, 'db_conn_failed')) { + $this->install_wizard_pass = 2; + $wizard_status = t('Could not connect to database.'); + } + if(x(\App::$data, 'url_fail')) { + $this->install_wizard_pass = 3; + $wizard_status = t('Could not connect to specified site URL. Possible SSL certificate or DNS issue.'); + if(\App::$data['url_error']) + $wizard_status .= ' ' . \App::$data['url_error']; + } + + if(x(\App::$data, 'db_create_failed')) { + $this->install_wizard_pass = 2; + $wizard_status = t('Could not create table.'); + } + $db_return_text = ''; + if(x(\App::$data, 'db_installed')) { + $txt = '

    '; + $txt .= t('Your site database has been installed.') . EOL; + $db_return_text .= $txt; + } + if(x(\App::$data, 'db_failed')) { + $txt = t('You may need to import the file "install/schema_xxx.sql" manually using a database client.') . EOL; + $txt .= t('Please see the file "install/INSTALL.txt".') . EOL ."


    " ; + $txt .= "
    ".\App::$data['db_failed'] . "
    ". EOL ; + $db_return_text .= $txt; + } + if($db && $db->connected) { + $r = q("SELECT COUNT(*) as `total` FROM `account`"); + if($r && count($r) && $r[0]['total']) { + $tpl = get_markup_template('install.tpl'); + return replace_macros($tpl, array( + '$title' => $install_title, + '$pass' => '', + '$status' => t('Permission denied.'), + '$text' => '', + )); + } + } + + if(x(\App::$data, 'txt') && strlen(\App::$data['txt'])) { + $db_return_text .= $this->manual_config($a); + } + + if ($db_return_text != "") { + $tpl = get_markup_template('install.tpl'); + return replace_macros($tpl, array( + '$title' => $install_title, + '$pass' => '', + '$text' => $db_return_text . $this->what_next(), + )); + } + + switch ($this->install_wizard_pass){ + case 1: { // System check + + $checks = array(); + + $this->check_funcs($checks); + + $this->check_htconfig($checks); + + $this->check_store($checks); + + $this->check_smarty3($checks); + + $this->check_keys($checks); + + if (x($_POST, 'phpath')) + $phpath = notags(trim($_POST['phpath'])); + + $this->check_php($phpath, $checks); + + $this->check_phpconfig($checks); + + $this->check_htaccess($checks); + + $checkspassed = array_reduce($checks, "self::check_passed", true); + + $tpl = get_markup_template('install_checks.tpl'); + $o .= replace_macros($tpl, array( + '$title' => $install_title, + '$pass' => t('System check'), + '$checks' => $checks, + '$passed' => $checkspassed, + '$see_install' => t('Please see the file "install/INSTALL.txt".'), + '$next' => t('Next'), + '$reload' => t('Check again'), + '$phpath' => $phpath, + '$baseurl' => z_root(), + )); + return $o; + }; break; + + case 2: { // Database config + + $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : '127.0.0.1'); + $dbuser = notags(trim($_POST['dbuser'])); + $dbport = intval(notags(trim($_POST['dbport']))); + $dbpass = notags(trim($_POST['dbpass'])); + $dbdata = notags(trim($_POST['dbdata'])); + $dbtype = intval(notags(trim($_POST['dbtype']))); + $phpath = notags(trim($_POST['phpath'])); + $adminmail = notags(trim($_POST['adminmail'])); + $siteurl = notags(trim($_POST['siteurl'])); + + $tpl = get_markup_template('install_db.tpl'); + $o .= replace_macros($tpl, array( + '$title' => $install_title, + '$pass' => t('Database connection'), + '$info_01' => t('In order to install $Projectname we need to know how to connect to your database.'), + '$info_02' => t('Please contact your hosting provider or site administrator if you have questions about these settings.'), + '$info_03' => t('The database you specify below should already exist. If it does not, please create it before continuing.'), + + '$status' => $wizard_status, + + '$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, t('Default is 127.0.0.1')), + '$dbport' => array('dbport', t('Database Port'), $dbport, t('Communication port number - use 0 for default')), + '$dbuser' => array('dbuser', t('Database Login Name'), $dbuser, ''), + '$dbpass' => array('dbpass', t('Database Login Password'), $dbpass, ''), + '$dbdata' => array('dbdata', t('Database Name'), $dbdata, ''), + '$dbtype' => array('dbtype', t('Database Type'), $dbtype, '', array( 0=>'MySQL', 1=>'PostgreSQL' )), + + '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')), + '$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')), + '$lbl_10' => t('Please select a default timezone for your website'), + + '$baseurl' => z_root(), + + '$phpath' => $phpath, + + '$submit' => t('Submit'), + )); + return $o; + }; break; + case 3: { // Site settings + require_once('include/datetime.php'); + $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : '127.0.0.1'); + $dbport = intval(notags(trim($_POST['dbuser']))); + $dbuser = notags(trim($_POST['dbuser'])); + $dbpass = notags(trim($_POST['dbpass'])); + $dbdata = notags(trim($_POST['dbdata'])); + $dbtype = intval(notags(trim($_POST['dbtype']))); + $phpath = notags(trim($_POST['phpath'])); + + $adminmail = notags(trim($_POST['adminmail'])); + $siteurl = notags(trim($_POST['siteurl'])); + $timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles'); + + $tpl = get_markup_template('install_settings.tpl'); + $o .= replace_macros($tpl, array( + '$title' => $install_title, + '$pass' => t('Site settings'), + '$status' => $wizard_status, + + '$dbhost' => $dbhost, + '$dbport' => $dbport, + '$dbuser' => $dbuser, + '$dbpass' => $dbpass, + '$dbdata' => $dbdata, + '$phpath' => $phpath, + '$dbtype' => $dbtype, + + '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')), + + '$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')), + '$advanced' => array('advanced', t('Enable $Projectname advanced features?'), 1, t('Some advanced features, while useful - may be best suited for technically proficient audiences')), + + '$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()), + + '$baseurl' => z_root(), + + '$submit' => t('Submit'), + )); + return $o; + }; break; + } + } + + /** + * @brief Add a check result to the array for output. + * + * @param[in,out] array &$checks array passed to template + * @param string $title a title for the check + * @param boolean $status + * @param boolean $required + * @param[optional] string $help optional help string + */ + function check_add(&$checks, $title, $status, $required, $help = '') { + $checks[] = array( + 'title' => $title, + 'status' => $status, + 'required' => $required, + 'help' => $help + ); + } + + /** + * @brief Checks the PHP environment. + * + * @param[in,out] string &$phpath + * @param[out] array &$checks + */ + function check_php(&$phpath, &$checks) { + $help = ''; + + if (strlen($phpath)) { + $passed = file_exists($phpath); + } else { + if(is_windows()) + $phpath = trim(shell_exec('where php')); + else + $phpath = trim(shell_exec('which php')); + + $passed = strlen($phpath); + } + + if(!$passed) { + $help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL; + $help .= t('If you don\'t have a command line version of PHP installed on server, you will not be able to run background polling via cron.') . EOL; + $help .= EOL . EOL ; + $tpl = get_markup_template('field_input.tpl'); + $help .= replace_macros($tpl, array( + '$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable. You can leave this blank to continue the installation.')), + )); + $phpath = ''; + } + + $this->check_add($checks, t('Command line PHP').($passed?" ($phpath)":""), $passed, false, $help); + + if($passed) { + $str = autoname(8); + $cmd = "$phpath install/testargs.php $str"; + $result = trim(shell_exec($cmd)); + $passed2 = $result == $str; + $help = ''; + if(!$passed2) { + $help .= t('The command line version of PHP on your system does not have "register_argc_argv" enabled.'). EOL; + $help .= t('This is required for message delivery to work.'); + } + + $this->check_add($checks, t('PHP register_argc_argv'), $passed, true, $help); + } + } + + /** + * @brief Some PHP configuration checks. + * + * @todo Change how we display such informational text. Add more description + * how to change them. + * + * @param[out] array &$checks + */ + function check_phpconfig(&$checks) { + require_once 'include/environment.php'; + + $help = ''; + + $result = getPhpiniUploadLimits(); + $help = sprintf(t('Your max allowed total upload size is set to %s. Maximum size of one file to upload is set to %s. You are allowed to upload up to %d files at once.'), + userReadableSize($result['post_max_size']), + userReadableSize($result['max_upload_filesize']), + $result['max_file_uploads'] + ); + $help .= '
    ' . t('You can adjust these settings in the servers php.ini.'); + + $this->check_add($checks, t('PHP upload limits'), true, false, $help); + } + + /** + * @brief Check if the openssl implementation can generate keys. + * + * @param[out] array $checks + */ + function check_keys(&$checks) { + $help = ''; + $res = false; + + if (function_exists('openssl_pkey_new')) { + $res = openssl_pkey_new(array( + 'digest_alg' => 'sha1', + 'private_key_bits' => 4096, + 'encrypt_key' => false) + ); + } + + // Get private key + + if (! $res) { + $help .= t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'). EOL; + $help .= t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".'); + } + + $this->check_add($checks, t('Generate encryption keys'), $res, true, $help); + } + + /** + * @brief Check for some PHP functions and modules. + * + * @param[in,out] array &$checks + */ + function check_funcs(&$checks) { + $ck_funcs = array(); + + // add check metadata, the real check is done bit later and return values set + $this->check_add($ck_funcs, t('libCurl PHP module'), true, true); + $this->check_add($ck_funcs, t('GD graphics PHP module'), true, true); + $this->check_add($ck_funcs, t('OpenSSL PHP module'), true, true); + $this->check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true); + $this->check_add($ck_funcs, t('mb_string PHP module'), true, true); + $this->check_add($ck_funcs, t('mcrypt PHP module'), true, true); + $this->check_add($ck_funcs, t('xml PHP module'), true, true); + + if(function_exists('apache_get_modules')){ + if (! in_array('mod_rewrite', apache_get_modules())) { + $this->check_add($ck_funcs, t('Apache mod_rewrite module'), false, true, t('Error: Apache webserver mod-rewrite module is required but not installed.')); + } else { + $this->check_add($ck_funcs, t('Apache mod_rewrite module'), true, true); + } + } + if((! function_exists('proc_open')) || strstr(ini_get('disable_functions'),'proc_open')) { + $this->check_add($ck_funcs, t('proc_open'), false, true, t('Error: proc_open is required but is either not installed or has been disabled in php.ini')); + } + else { + $this->check_add($ck_funcs, t('proc_open'), true, true); + } + + if(! function_exists('curl_init')) { + $ck_funcs[0]['status'] = false; + $ck_funcs[0]['help'] = t('Error: libCURL PHP module required but not installed.'); + } + if(! function_exists('imagecreatefromjpeg')) { + $ck_funcs[1]['status'] = false; + $ck_funcs[1]['help'] = t('Error: GD graphics PHP module with JPEG support required but not installed.'); + } + if(! function_exists('openssl_public_encrypt')) { + $ck_funcs[2]['status'] = false; + $ck_funcs[2]['help'] = t('Error: openssl PHP module required but not installed.'); + } + if(! function_exists('mysqli_connect') && !function_exists('pg_connect')) { + $ck_funcs[3]['status'] = false; + $ck_funcs[3]['help'] = t('Error: mysqli or postgres PHP module required but neither are installed.'); + } + if(! function_exists('mb_strlen')) { + $ck_funcs[4]['status'] = false; + $ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.'); + } + if(! function_exists('mcrypt_encrypt')) { + $ck_funcs[5]['status'] = false; + $ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.'); + } + if(! extension_loaded('xml')) { + $ck_funcs[6]['status'] = false; + $ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.'); + } + + $checks = array_merge($checks, $ck_funcs); + } + + /** + * @brief Check for .htconfig requirements. + * + * @param[out] array &$checks + */ + function check_htconfig(&$checks) { + $status = true; + $help = ''; + + if( (file_exists('.htconfig.php') && !is_writable('.htconfig.php')) || + (!file_exists('.htconfig.php') && !is_writable('.')) ) { + $status = false; + $help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL; + $help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL; + $help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Red top folder.').EOL; + $help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "install/INSTALL.txt" for instructions.').EOL; + } + + $this->check_add($checks, t('.htconfig.php is writable'), $status, false, $help); + } + + /** + * @brief Checks for our templating engine Smarty3 requirements. + * + * @param[out] array &$checks + */ + function check_smarty3(&$checks) { + $status = true; + $help = ''; + + if(! is_writable(TEMPLATE_BUILD_PATH) ) { + $status = false; + $help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; + $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the Red top level folder.'), TEMPLATE_BUILD_PATH) . EOL; + $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; + $help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL; + } + + $this->check_add($checks, sprintf( t('%s is writable'), TEMPLATE_BUILD_PATH), $status, true, $help); + } + + /** + * @brief Check for store directory. + * + * @param[out] array &$checks + */ + function check_store(&$checks) { + $status = true; + $help = ''; + + @os_mkdir(TEMPLATE_BUILD_PATH, STORAGE_DEFAULT_PERMISSIONS, true); + + if(! is_writable('store')) { + $status = false; + $help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; + $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; + } + + $this->check_add($checks, t('store is writable'), $status, true, $help); + } + + /** + * @brief Check URL rewrite und SSL certificate. + * + * @param[out] array &$checks + */ + function check_htaccess(&$checks) { + $a = get_app(); + $status = true; + $help = ''; + $ssl_error = false; + + $url = z_root() . '/setup/testrewrite'; + + if (function_exists('curl_init')){ + $test = z_fetch_url($url); + if(! $test['success']) { + if(strstr($url,'https://')) { + $test = z_fetch_url($url,false,0,array('novalidate' => true)); + if($test['success']) { + $ssl_error = true; + } + } + else { + $test = z_fetch_url(str_replace('http://','https://',$url),false,0,array('novalidate' => true)); + if($test['success']) { + $ssl_error = true; + } + } + + if($ssl_error) { + $help = t('SSL certificate cannot be validated. Fix certificate or disable https access to this site.') . EOL; + $help .= t('If you have https access to your website or allow connections to TCP port 443 (the https: port), you MUST use a browser-valid certificate. You MUST NOT use self-signed certificates!') . EOL; + $help .= t('This restriction is incorporated because public posts from you may for example contain references to images on your own hub.') . EOL; + $help .= t('If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues.') . EOL; + $help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL; + $help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL; + + $this->check_add($checks, t('SSL certificate validation'), false, true, $help); + } + } + + if ((! $test['success']) || ($test['body'] != "ok")) { + $status = false; + $help = t('Url rewrite in .htaccess is not working. Check your server configuration.'.'Test: '.var_export($test,true)); + } + + $this->check_add($checks, t('Url rewrite is working'), $status, true, $help); + } else { + // cannot check modrewrite if libcurl is not installed + } + } + + + function manual_config(&$a) { + $data = htmlspecialchars(\App::$data['txt'], ENT_COMPAT, 'UTF-8'); + $o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.'); + $o .= ""; + + return $o; + } + + function load_database_rem($v, $i){ + $l = trim($i); + if (strlen($l)>1 && ($l[0]=="-" || ($l[0]=="/" && $l[1]=="*"))){ + return $v; + } else { + return $v."\n".$i; + } + } + + + function load_database($db) { + $str = file_get_contents($db->get_install_script()); + $arr = explode(';',$str); + $errors = false; + foreach($arr as $a) { + if(strlen(trim($a))) { + $r = @$db->q(trim($a)); + if(! $r) { + $errors .= t('Errors encountered creating database tables.') . $a . EOL; + } + } + } + + return $errors; + } + + function what_next() { + $a = get_app(); + // install the standard theme + set_config('system', 'allowed_themes', 'redbasic'); + + // Set a lenient list of ciphers if using openssl. Other ssl engines + // (e.g. NSS used in RedHat) require different syntax, so hopefully + // the default curl cipher list will work for most sites. If not, + // this can set via config. Many distros are now disabling RC4, + // but many Red sites still use it and are unable to change it. + // We do not use SSL for encryption, only to protect session cookies. + // z_fetch_url() is also used to import shared links and other content + // so in theory most any cipher could show up and we should do our best + // to make the content available rather than tell folks that there's a + // weird SSL error which they can't do anything about. + + $x = curl_version(); + if(stristr($x['ssl_version'],'openssl')) + set_config('system','curl_ssl_ciphers','ALL:!eNULL'); + + // Create a system channel + require_once ('include/identity.php'); + create_sys_channel(); + + $baseurl = z_root(); + return + t('

    What next

    ') + ."

    ".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.') + .t('Please see the file "install/INSTALL.txt".') + ."

    " + .t("Go to your new hub registration page and register as new member. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.") + ."

    "; + } + + + static private function check_passed($v, $c) { + if ($c['required']) + $v = $v && $c['status']; + + return $v; + } + + +} diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php new file mode 100644 index 000000000..73db01657 --- /dev/null +++ b/Zotlabs/Module/Share.php @@ -0,0 +1,93 @@ + 1) ? intval(argv(1)) : 0); + + if(! $post_id) + killme(); + + if(! (local_channel() || remote_channel())) + killme(); + + $r = q("SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1", + intval($post_id) + ); + if(! $r) + killme(); + if(($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss')) + killme(); + + $sql_extra = item_permissions_sql($r[0]['uid']); + + $r = q("select * from item where id = %d $sql_extra", + intval($post_id) + ); + if(! $r) + killme(); + + /** @FIXME we only share bbcode */ + + if($r[0]['mimetype'] !== 'text/bbcode') + killme(); + + /** @FIXME eventually we want to post remotely via rpost on your home site */ + // When that works remove this next bit: + + if(! local_channel()) + killme(); + + xchan_query($r); + + $is_photo = (($r[0]['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false); + if($is_photo) { + $object = json_decode($r[0]['object'],true); + $photo_bb = $object['body']; + } + + if (strpos($r[0]['body'], "[/share]") !== false) { + $pos = strpos($r[0]['body'], "[share"); + $o = substr($r[0]['body'], $pos); + } else { + $o = "[share author='".urlencode($r[0]['author']['xchan_name']). + "' profile='".$r[0]['author']['xchan_url'] . + "' avatar='".$r[0]['author']['xchan_photo_s']. + "' link='".$r[0]['plink']. + "' posted='".$r[0]['created']. + "' message_id='".$r[0]['mid']."']"; + if($r[0]['title']) + $o .= '[b]'.$r[0]['title'].'[/b]'."\r\n"; + $o .= (($is_photo) ? $photo_bb . "\r\n" . $r[0]['body'] : $r[0]['body']); + $o .= "[/share]"; + } + + if(local_channel()) { + echo $o; + killme(); + } + + $observer = \App::get_observer(); + $parsed = $observer['xchan_url']; + if($parsed) { + $post_url = $parsed['scheme'] . ':' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '') + . '/rpost'; + + /** + * @FIXME we were probably called from JS so we don't know the return page. + * In fact we won't be able to load the remote page. + * we might need an iframe + */ + + $x = z_post_url($post_url, array('f' => '', 'body' => $o )); + killme(); + } + } + +} diff --git a/Zotlabs/Module/Sharedwithme.php b/Zotlabs/Module/Sharedwithme.php new file mode 100644 index 000000000..8eaa47dba --- /dev/null +++ b/Zotlabs/Module/Sharedwithme.php @@ -0,0 +1,113 @@ + 2) && (argv(2) === 'drop')) { + + $id = intval(argv(1)); + + q("DELETE FROM item WHERE id = %d AND uid = %d", + intval($id), + intval(local_channel()) + ); + + goaway(z_root() . '/sharedwithme'); + } + + //drop all files - localuser + if((argc() > 1) && (argv(1) === 'dropall')) { + + q("DELETE FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d", + dbesc(ACTIVITY_POST), + dbesc(ACTIVITY_OBJ_FILE), + intval(local_channel()) + ); + + goaway(z_root() . '/sharedwithme'); + } + + //list files + $r = q("SELECT id, uid, object, item_unseen FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'", + dbesc(ACTIVITY_POST), + dbesc(ACTIVITY_OBJ_FILE), + intval(local_channel()), + dbesc($channel['channel_hash']) + ); + + $items =array(); + $ids = ''; + + if($r) { + + foreach($r as $rr) { + $object = json_decode($rr['object'],true); + + $item = array(); + $item['id'] = $rr['id']; + $item['objfiletype'] = $object['filetype']; + $item['objfiletypeclass'] = getIconFromType($object['filetype']); + $item['objurl'] = rawurldecode(get_rel_link($object['link'],'alternate')) . '?f=&zid=' . $channel['xchan_addr']; + $item['objfilename'] = $object['filename']; + $item['objfilesize'] = userReadableSize($object['filesize']); + $item['objedited'] = $object['edited']; + $item['unseen'] = $rr['item_unseen']; + + $items[] = $item; + + if($item['unseen'] > 0) { + $ids .= " '" . $rr['id'] . "',"; + } + + } + + } + + if($ids) { + + //remove trailing , + $ids = rtrim($ids, ","); + + q("UPDATE item SET item_unseen = 0 WHERE id IN ( $ids ) AND uid = %d", + intval(local_channel()) + ); + + } + + $o = profile_tabs($a, $is_owner, $channel['channel_address']); + + $o .= replace_macros(get_markup_template('sharedwithme.tpl'), array( + '$header' => t('Files: shared with me'), + '$name' => t('Name'), + '$label_new' => t('NEW'), + '$size' => t('Size'), + '$lastmod' => t('Last Modified'), + '$dropall' => t('Remove all files'), + '$drop' => t('Remove this file'), + '$items' => $items + )); + + return $o; + + } + + +} diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php new file mode 100644 index 000000000..ccca6ab43 --- /dev/null +++ b/Zotlabs/Module/Siteinfo.php @@ -0,0 +1,94 @@ + 16) + $commit = ''; + } + else { + $version = $commit = ''; + } + $visible_plugins = array(); + if(is_array(\App::$plugins) && count(\App::$plugins)) { + $r = q("select * from addon where hidden = 0"); + if(count($r)) + foreach($r as $rr) + $visible_plugins[] = $rr['name']; + } + + $plugins_list = ''; + if(count($visible_plugins)) { + $plugins_text = t('Installed plugins/addons/apps:'); + $sorted = $visible_plugins; + $s = ''; + sort($sorted); + foreach($sorted as $p) { + if(strlen($p)) { + if(strlen($s)) $s .= ', '; + $s .= $p; + } + } + $plugins_list .= $s; + } + else + $plugins_text = t('No installed plugins/addons/apps'); + + $txt = get_config('system','admininfo'); + $admininfo = bbcode($txt); + + if(file_exists('doc/site_donate.html')) + $donate .= file_get_contents('doc/site_donate.html'); + + if(function_exists('sys_getloadavg')) + $loadavg = sys_getloadavg(); + + $o = replace_macros(get_markup_template('siteinfo.tpl'), array( + '$title' => t('$Projectname'), + '$description' => t('This is a hub of $Projectname - a global cooperative network of decentralized privacy enhanced websites.'), + '$version' => $version, + '$tag_txt' => t('Tag: '), + '$tag' => $tag, + '$polled' => t('Last background fetch: '), + '$lastpoll' => get_poller_runtime(), + '$load_average' => t('Current load average: '), + '$loadavg_all' => $loadavg[0] . ', ' . $loadavg[1] . ', ' . $loadavg[2], + '$commit' => $commit, + '$web_location' => t('Running at web location') . ' ' . z_root(), + '$visit' => t('Please visit hubzilla.org to learn more about $Projectname.'), + '$bug_text' => t('Bug reports and issues: please visit'), + '$bug_link_url' => 'https://github.com/redmatrix/hubzilla/issues', + '$bug_link_text' => t('$projectname issues'), + '$contact' => t('Suggestions, praise, etc. - please email "redmatrix" at librelist - dot com'), + '$donate' => $donate, + '$adminlabel' => t('Site Administrators'), + '$admininfo' => $admininfo, + '$plugins_text' => $plugins_text, + '$plugins_list' => $plugins_list + )); + + call_hooks('about_hook', $o); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Siteinfo_json.php b/Zotlabs/Module/Siteinfo_json.php new file mode 100644 index 000000000..99c22610f --- /dev/null +++ b/Zotlabs/Module/Siteinfo_json.php @@ -0,0 +1,14 @@ + false); + + $r = q("select count(site_url) as total from site where site_type = %d $sql_extra ", + intval(SITE_TYPE_ZOT) + ); + + if($r) + $result['total'] = intval($r[0]['total']); + + $result['start'] = $start; + $result['limit'] = $limit; + + $r = q("select * from site where site_type = %d $sql_extra $sql_order $sql_limit", + intval(SITE_TYPE_ZOT) + ); + + $result['results'] = 0; + $result['entries'] = array(); + + if($r) { + $result['success'] = true; + $result['results'] = count($r); + + foreach($r as $rr) { + $result['entries'][] = array('url' => $rr['site_url']); + } + + } + + echo json_encode($result); + killme(); + + + } +} diff --git a/Zotlabs/Module/Smilies.php b/Zotlabs/Module/Smilies.php new file mode 100644 index 000000000..efac07f84 --- /dev/null +++ b/Zotlabs/Module/Smilies.php @@ -0,0 +1,21 @@ + $tmp['texts'][$i], 'icon' => $tmp['icons'][$i]); + } + json_return_and_die($results); + } + else { + return smilies('',true); + } + } + +} diff --git a/Zotlabs/Module/Sources.php b/Zotlabs/Module/Sources.php new file mode 100644 index 000000000..cca9e5ebf --- /dev/null +++ b/Zotlabs/Module/Sources.php @@ -0,0 +1,173 @@ + t('Channel Sources'), + '$desc' => t('Manage remote sources of content for your channel.'), + '$new' => t('New Source'), + '$sources' => $r + )); + return $o; + } + + if(argc() == 2 && argv(1) === 'new') { + // TODO add the words 'or RSS feed' and corresponding code to manage feeds and frequency + + $o = replace_macros(get_markup_template('sources_new.tpl'), array( + '$title' => t('New Source'), + '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), + '$words' => array( 'words', t('Only import content with these words (one per line)'),'',t('Leave blank to import all public content')), + '$name' => array( 'name', t('Channel Name'), '', ''), + '$submit' => t('Submit') + )); + return $o; + + } + + if(argc() == 2 && intval(argv(1))) { + // edit source + $r = q("select source.*, xchan.* from source left join xchan on src_xchan = xchan_hash where src_id = %d and src_channel_id = %d limit 1", + intval(argv(1)), + intval(local_channel()) + ); + if($r) { + $x = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc($r[0]['src_xchan']), + intval(local_channel()) + ); + } + if(! $r) { + notice( t('Source not found.') . EOL); + return ''; + } + + $r[0]['src_patt'] = htmlspecialchars($r[0]['src_patt'], ENT_QUOTES,'UTF-8'); + + $o = replace_macros(get_markup_template('sources_edit.tpl'), array( + '$title' => t('Edit Source'), + '$drop' => t('Delete Source'), + '$id' => $r[0]['src_id'], + '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), + '$words' => array( 'words', t('Only import content with these words (one per line)'),$r[0]['src_patt'],t('Leave blank to import all public content')), + '$xchan' => $r[0]['src_xchan'], + '$abook' => $x[0]['abook_id'], + '$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''), + '$submit' => t('Submit') + )); + return $o; + + } + + if(argc() == 3 && intval(argv(1)) && argv(2) === 'drop') { + $r = q("select * from source where src_id = %d and src_channel_id = %d limit 1", + intval(argv(1)), + intval(local_channel()) + ); + if(! $r) { + notice( t('Source not found.') . EOL); + return ''; + } + $r = q("delete from source where src_id = %d and src_channel_id = %d", + intval(argv(1)), + intval(local_channel()) + ); + if($r) + info( t('Source removed') . EOL); + else + notice( t('Unable to remove source.') . EOL); + + goaway(z_root() . '/sources'); + + } + + // shouldn't get here. + + } +} diff --git a/Zotlabs/Module/Sslify.php b/Zotlabs/Module/Sslify.php new file mode 100644 index 000000000..db73f85e0 --- /dev/null +++ b/Zotlabs/Module/Sslify.php @@ -0,0 +1,30 @@ + 1) + $message_id = intval(argv(1)); + if(! $message_id) + killme(); + + $r = q("SELECT item_flags FROM item WHERE uid = %d AND id = %d LIMIT 1", + intval(local_channel()), + intval($message_id) + ); + if(! count($r)) + killme(); + + $item_starred = (intval($r[0]['item_starred']) ? 0 : 1); + + $r = q("UPDATE item SET item_starred = %d WHERE uid = %d and id = %d", + intval($item_starred), + intval(local_channel()), + intval($message_id) + ); + + header('Content-type: application/json'); + echo json_encode(array('result' => $item_starred)); + killme(); + } + +} diff --git a/Zotlabs/Module/Subthread.php b/Zotlabs/Module/Subthread.php new file mode 100644 index 000000000..16a011a40 --- /dev/null +++ b/Zotlabs/Module/Subthread.php @@ -0,0 +1,169 @@ + 2) ? notags(trim(argv(2))) : 0); + + if(argv(1) === 'sub') + $activity = ACTIVITY_FOLLOW; + elseif(argv(1) === 'unsub') + $activity = ACTIVITY_UNFOLLOW; + + + $r = q("SELECT parent FROM item WHERE id = '%s'", + dbesc($item_id) + ); + + if($r) { + $r = q("select * from item where id = parent and id = %d limit 1", + dbesc($r[0]['parent']) + ); + } + + if((! $item_id) || (! $r)) { + logger('subthread: no item ' . $item_id); + return; + } + + $item = $r[0]; + + $owner_uid = $item['uid']; + $observer = \App::get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + if(! perm_is_allowed($owner_uid,$ob_hash,'post_comments')) + return; + + $sys = get_sys_channel(); + + $owner_uid = $item['uid']; + $owner_aid = $item['aid']; + + // if this is a "discover" item, (item['uid'] is the sys channel), + // fallback to the item comment policy, which should've been + // respected when generating the conversation thread. + // Even if the activity is rejected by the item owner, it should still get attached + // to the local discover conversation on this site. + + if(($owner_uid != $sys['channel_id']) && (! perm_is_allowed($owner_uid,$observer['xchan_hash'],'post_comments'))) { + notice( t('Permission denied') . EOL); + killme(); + } + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['owner_xchan']) + ); + if($r) + $thread_owner = $r[0]; + else + killme(); + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['author_xchan']) + ); + if($r) + $item_author = $r[0]; + else + killme(); + + + + + $mid = item_message_id(); + + $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); + + $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink'])); + $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); + + $body = $item['body']; + + $obj = json_encode(array( + 'type' => $objtype, + 'id' => $item['mid'], + 'parent' => (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']), + 'link' => $links, + 'title' => $item['title'], + 'content' => $item['body'], + 'created' => $item['created'], + 'edited' => $item['edited'], + 'author' => array( + 'name' => $item_author['xchan_name'], + 'address' => $item_author['xchan_addr'], + 'guid' => $item_author['xchan_guid'], + 'guid_sig' => $item_author['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']), + array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])), + ), + )); + + if(! intval($item['item_thread_top'])) + $post_type = 'comment'; + + if($activity === ACTIVITY_FOLLOW) + $bodyverb = t('%1$s is following %2$s\'s %3$s'); + if($activity === ACTIVITY_UNFOLLOW) + $bodyverb = t('%1$s stopped following %2$s\'s %3$s'); + + $arr = array(); + + $arr['mid'] = $mid; + $arr['aid'] = $owner_aid; + $arr['uid'] = $owner_uid; + $arr['parent'] = $item['id']; + $arr['parent_mid'] = $item['mid']; + $arr['thr_parent'] = $item['mid']; + $arr['owner_xchan'] = $thread_owner['xchan_hash']; + $arr['author_xchan'] = $observer['xchan_hash']; + $arr['item_origin'] = 1; + $arr['item_notshown'] = 1; + if(intval($item['item_wall'])) + $arr['item_wall'] = 1; + else + $arr['item_wall'] = 0; + + $ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]'; + + $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); + + $arr['verb'] = $activity; + $arr['obj_type'] = $objtype; + $arr['object'] = $obj; + + $arr['allow_cid'] = $item['allow_cid']; + $arr['allow_gid'] = $item['allow_gid']; + $arr['deny_cid'] = $item['deny_cid']; + $arr['deny_gid'] = $item['deny_gid']; + + $post = item_store($arr); + $post_id = $post['item_id']; + + $arr['id'] = $post_id; + + call_hooks('post_local_end', $arr); + + killme(); + + + } + + + + +} diff --git a/Zotlabs/Module/Suggest.php b/Zotlabs/Module/Suggest.php new file mode 100644 index 000000000..367308d90 --- /dev/null +++ b/Zotlabs/Module/Suggest.php @@ -0,0 +1,72 @@ + chanlink_url($rr['xchan_url']), + 'common' => $rr['total'], + 'profile' => $rr['xchan_url'], + 'name' => $rr['xchan_name'], + 'photo' => $rr['xchan_photo_m'], + 'ignlnk' => z_root() . '/suggest?ignore=' . $rr['xchan_hash'], + 'conntxt' => t('Connect'), + 'connlnk' => $connlnk, + 'ignore' => t('Ignore/Hide') + ); + } + + + $o = replace_macros(get_markup_template('suggest_page.tpl'),array( + '$title' => t('Channel Suggestions'), + '$entries' => $arr + )); + + return $o; + + } + +} diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php new file mode 100644 index 000000000..879cf3dbb --- /dev/null +++ b/Zotlabs/Module/Tagger.php @@ -0,0 +1,140 @@ + 1) ? notags(trim(argv(1))) : 0); + + logger('tagger: tag ' . $term . ' item ' . $item_id); + + + $r = q("SELECT * FROM item left join xchan on xchan_hash = author_xchan WHERE id = '%s' and uid = %d LIMIT 1", + dbesc($item_id), + intval(local_channel()) + ); + + if((! $item_id) || (! $r)) { + logger('tagger: no item ' . $item_id); + return; + } + + $item = $r[0]; + + $owner_uid = $item['uid']; + + switch($item['resource_type']) { + case 'photo': + $targettype = ACTIVITY_OBJ_PHOTO; + $post_type = t('photo'); + break; + case 'event': + $targgettype = ACTIVITY_OBJ_EVENT; + $post_type = t('event'); + break; + default: + $targettype = ACTIVITY_OBJ_NOTE; + $post_type = t('post'); + if($item['mid'] != $item['parent_mid']) + $post_type = t('comment'); + break; + } + + + $links = array(array('rel' => 'alternate','type' => 'text/html', + 'href' => z_root() . '/display/' . $item['mid'])); + + $target = json_encode(array( + 'type' => $targettype, + 'id' => $item['mid'], + 'link' => $links, + 'title' => $item['title'], + 'content' => $item['body'], + 'created' => $item['created'], + 'edited' => $item['edited'], + 'author' => array( + 'name' => $item['xchan_name'], + 'address' => $item['xchan_addr'], + 'guid' => $item['xchan_guid'], + 'guid_sig' => $item['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item['xchan_url']), + array('rel' => 'photo', 'type' => $item['xchan_photo_mimetype'], 'href' => $item['xchan_photo_m'])), + ), + )); + + + + $link = xmlify('' . "\n") ; + + $tagid = z_root() . '/search?tag=' . $term; + $objtype = ACTIVITY_OBJ_TAGTERM; + + $obj = json_encode(array( + 'type' => $objtype, + 'id' => $tagid, + 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $tagid)), + 'title' => $term, + 'content' => $term + )); + + $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s'); + + // saving here for reference + // also check out x22d5 and x2317 and x0d6b and x0db8 and x24d0 and xff20 !!! + + $termlink = html_entity_decode('⋕') . '[zrl=' . z_root() . '/search?tag=' . urlencode($term) . ']'. $term . '[/zrl]'; + + $channel = \App::get_channel(); + + $arr = array(); + + $arr['owner_xchan'] = $item['owner_xchan']; + $arr['author_xchan'] = $channel['channel_hash']; + + $arr['item_origin'] = 1; + $arr['item_wall'] = ((intval($item['item_wall'])) ? 1 : 0); + + $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; + $alink = '[zrl=' . $item['xchan_url'] . ']' . $item['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . $item['plink'] . ']' . $post_type . '[/zrl]'; + + $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink, $termlink ); + + $arr['verb'] = ACTIVITY_TAG; + $arr['tgt_type'] = $targettype; + $arr['target'] = $target; + $arr['obj_type'] = $objtype; + $arr['object'] = $obj; + $arr['parent_mid'] = $item['mid']; + + store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); + $ret = post_activity_item($arr); + + if($ret['success']) + proc_run('php','include/notifier.php','tag',$ret['activity']['id']); + + killme(); + + } + +} diff --git a/Zotlabs/Module/Tagrm.php b/Zotlabs/Module/Tagrm.php new file mode 100644 index 000000000..81ae30aa5 --- /dev/null +++ b/Zotlabs/Module/Tagrm.php @@ -0,0 +1,147 @@ +' . t('Remove Item Tag') . ''; + + $o .= '

    ' . t('Select a tag to remove: ') . '

    '; + + $o .= '
    '; + $o .= ''; + $o .= '
      '; + + + foreach($r[0]['term'] as $x) { + $o .= '
    • ' . bbcode($x['term']) . '
    • '; + } + + $o .= '
    '; + $o .= ''; + $o .= ''; + $o .= '
    '; + + return $o; + + } + + } + +} diff --git a/Zotlabs/Module/Tasks.php b/Zotlabs/Module/Tasks.php new file mode 100644 index 000000000..ab05f8be9 --- /dev/null +++ b/Zotlabs/Module/Tasks.php @@ -0,0 +1,112 @@ + 1 && argv(1) === 'fetch') { + if(argc() > 2 && argv(2) === 'all') + $arr['all'] = 1; + + $x = tasks_fetch($arr); + if($x['tasks']) { + $x['html'] = ''; + foreach($x['tasks'] as $y) { + $x['html'] .= '
    ' . $y['summary'] . '
    '; + } + } + json_return_and_die($x); + } + + } + + + + function post() { + + + // logger('post: ' . print_r($_POST,true)); + + + if(! local_channel()) + return; + + $channel = \App::get_channel(); + + if((argc() > 2) && (argv(1) === 'complete') && intval(argv(2))) { + $ret = array('success' => false); + $r = q("select * from event where `type` = 'task' and uid = %d and id = %d limit 1", + intval(local_channel()), + intval(argv(2)) + ); + if($r) { + $event = $r[0]; + if($event['event_status'] === 'COMPLETED') { + $event['event_status'] = 'IN-PROCESS'; + $event['event_status_date'] = NULL_DATE; + $event['event_percent'] = 0; + $event['event_sequence'] = $event['event_sequence'] + 1; + $event['edited'] = datetime_convert(); + } + else { + $event['event_status'] = 'COMPLETED'; + $event['event_status_date'] = datetime_convert(); + $event['event_percent'] = 100; + $event['event_sequence'] = $event['event_sequence'] + 1; + $event['edited'] = datetime_convert(); + } + $x = event_store_event($event); + if($x) + $ret['success'] = true; + } + json_return_and_die($ret); + } + + if(argc() == 2 && argv(1) === 'new') { + $text = escape_tags(trim($_REQUEST['summary'])); + if(! $text) + return array('success' => false); + $event = array(); + $event['account'] = $channel['channel_account_id']; + $event['uid'] = $channel['channel_id']; + $event['event_xchan'] = $channel['channel_hash']; + $event['type'] = 'task'; + $event['nofinish'] = true; + $event['created'] = $event['edited'] = $event['start'] = datetime_convert(); + $event['adjust'] = 1; + $event['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + $event['summary'] = escape_tags($_REQUEST['summary']); + $x = event_store_event($event); + if($x) + $x['success'] = true; + else + $x = array('success' => false); + json_return_and_die($x); + } + + + } + + + + + + function get() { + + if(! local_channel()) + return; + + + return ''; + } +} diff --git a/Zotlabs/Module/Test.php b/Zotlabs/Module/Test.php new file mode 100644 index 000000000..ff14e4691 --- /dev/null +++ b/Zotlabs/Module/Test.php @@ -0,0 +1,38 @@ + + + macgirvin@diasp.org + Mike + Macgirvin + https://diasp.org/uploads/images/thumb_large_d5f9b6384c91f532f280.jpg + https://diasp.org/uploads/images/thumb_small_d5f9b6384c91f532f280.jpg + https://diasp.org/uploads/images/thumb_medium_d5f9b6384c91f532f280.jpg + 1000-05-14 + + Creator of Friendica, Redmatrix, and Hubzilla. + Australia + true + false + #redmatrix #hubzilla + + '; + + $parsed_xml = xml2array($s,false,0,'tag'); + + $o = print_r($parsed_xml,true); + return $o; + + + // fix_system_urls('http://hz.macgirvin.com',z_root()); + + } + +} diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php new file mode 100644 index 000000000..e95ec53f6 --- /dev/null +++ b/Zotlabs/Module/Thing.php @@ -0,0 +1,368 @@ +set_from_array($_REQUEST); + } + + $x = $acl->get(); + + if($term_hash) { + $t = q("select * from obj where obj_obj = '%s' and obj_channel = %d limit 1", + dbesc($term_hash), + intval(local_channel()) + ); + if(! $t) { + notice( t('Item not found.') . EOL); + return; + } + $orig_record = $t[0]; + if($photo != $orig_record['obj_imgurl']) { + $arr = import_xchan_photo($photo,get_observer_hash(),true); + $local_photo = $arr[0]; + $local_photo_type = $arr[3]; + } + else + $local_photo = $orig_record['obj_imgurl']; + + $r = q("update obj set obj_term = '%s', obj_url = '%s', obj_imgurl = '%s', obj_edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where obj_obj = '%s' and obj_channel = %d ", + dbesc($name), + dbesc(($url) ? $url : z_root() . '/thing/' . $term_hash), + dbesc($local_photo), + dbesc(datetime_convert()), + dbesc($x['allow_cid']), + dbesc($x['allow_gid']), + dbesc($x['deny_cid']), + dbesc($x['deny_gid']), + dbesc($term_hash), + intval(local_channel()) + ); + + info( t('Thing updated') . EOL); + + $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", + intval(local_channel()), + dbesc($term_hash) + ); + if($r) { + build_sync_packet(0, array('obj' => $r)); + } + + return; + } + + $sql = (($profile_guid) ? " and profile_guid = '" . dbesc($profile_guid) . "' " : " and is_default = 1 "); + $p = q("select profile_guid, is_default from profile where uid = %d $sql limit 1", + intval(local_channel()) + ); + + if($p) + $profile = $p[0]; + else + return; + + $local_photo = null; + + if($photo) { + $arr = import_xchan_photo($photo,get_observer_hash(),true); + $local_photo = $arr[0]; + $local_photo_type = $arr[3]; + } + + $created = datetime_convert(); + $url = (($url) ? $url : z_root() . '/thing/' . $hash); + + $r = q("insert into obj ( obj_page, obj_verb, obj_type, obj_channel, obj_obj, obj_term, obj_url, obj_imgurl, obj_created, obj_edited, allow_cid, allow_gid, deny_cid, deny_gid ) values ('%s','%s', %d, %d, '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') ", + dbesc($profile['profile_guid']), + dbesc($verb), + intval(TERM_OBJ_THING), + intval(local_channel()), + dbesc($hash), + dbesc($name), + dbesc($url), + dbesc(($photo) ? $local_photo : ''), + dbesc($created), + dbesc($created), + dbesc($x['allow_cid']), + dbesc($x['allow_gid']), + dbesc($x['deny_cid']), + dbesc($x['deny_gid']) + ); + + if(! $r) { + notice( t('Object store: failed')); + return; + } + + info( t('Thing added')); + + $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", + intval(local_channel()), + dbesc($hash) + ); + if($r) { + build_sync_packet(0, array('obj' => $r)); + } + + if($activity) { + $arr = array(); + $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $url)); + if($local_photo) + $links[] = array('rel' => 'photo', 'type' => $local_photo_type, 'href' => $local_photo); + + $objtype = ACTIVITY_OBJ_THING; + + $obj = json_encode(array( + 'type' => $objtype, + 'id' => $url, + 'link' => $links, + 'title' => $name, + 'content' => $name + )); + + $bodyverb = str_replace('OBJ: ', '',t('OBJ: %1$s %2$s %3$s')); + + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; + + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; + $arr['item_thread_top'] = 1; + + $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; + $plink = '[zrl=' . $url . ']' . $name . '[/zrl]'; + + $arr['body'] = sprintf( $bodyverb, $ulink, $translated_verb, $plink ); + + if($local_photo) + $arr['body'] .= "\n\n[zmg]" . $local_photo . "[/zmg]"; + + $arr['verb'] = $verb; + $arr['obj_type'] = $objtype; + $arr['object'] = $obj; + + if(! $profile['is_default']) { + $arr['item_private'] = true; + $str = ''; + $r = q("select abook_xchan from abook where abook_channel = %d and abook_profile = '%s'", + intval(local_channel()), + dbesc($profile_guid) + ); + if($r) { + $arr['allow_cid'] = ''; + foreach($r as $rr) + $arr['allow_cid'] .= '<' . $rr['abook_xchan'] . '>'; + } + else + $arr['allow_cid'] = '<' . get_observer_hash() . '>'; + } + + $ret = post_activity_item($arr); + } + } + + + function get() { + + // @FIXME one problem with things is we can't share them unless we provide the channel in the url + // so we can definitively lookup the owner. + + if(argc() == 2) { + + $r = q("select obj_channel from obj where obj_type = %d and obj_obj = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc(argv(1)) + ); + if($r) + $sql_extra = permissions_sql($r[0]['obj_channel']); + + $r = q("select * from obj where obj_type = %d and obj_obj = '%s' $sql_extra limit 1", + intval(TERM_OBJ_THING), + dbesc(argv(1)) + ); + + if($r) { + return replace_macros(get_markup_template('show_thing.tpl'), array( + '$header' => t('Show Thing'), + '$edit' => t('Edit'), + '$delete' => t('Delete'), + '$canedit' => ((local_channel() && local_channel() == $r[0]['obj_channel']) ? true : false), + '$thing' => $r[0] )); + } + else { + notice( t('item not found.') . EOL); + return; + } + } + + $channel = \App::get_channel(); + + if(! (local_channel() && $channel)) { + notice( t('Permission denied.') . EOL); + return; + } + + $acl = new \Zotlabs\Access\AccessList($channel); + $channel_acl = $acl->get(); + + $lockstate = (($acl->is_private()) ? 'lock' : 'unlock'); + + $thing_hash = ''; + + if(argc() == 3 && argv(1) === 'edit') { + $thing_hash = argv(2); + + $r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc($thing_hash) + ); + + if((! $r) || ($r[0]['obj_channel'] != local_channel())) { + notice( t('Permission denied.') . EOL); + return ''; + } + + $o .= replace_macros(get_markup_template('thing_edit.tpl'),array( + '$thing_hdr' => t('Edit Thing'), + '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), + '$profile_lbl' => t('Select a profile'), + '$profile_select' => contact_profile_assign($r[0]['obj_page']), + '$verb_lbl' => $channel['channel_name'], + '$verb_select' => obj_verb_selector($r[0]['obj_verb']), + '$activity' => array('activity',t('Post an activity'),true,t('Only sends to viewers of the applicable profile')), + '$thing_hash' => $thing_hash, + '$thing_lbl' => t('Name of thing e.g. something'), + '$thething' => $r[0]['obj_term'], + '$url_lbl' => t('URL of thing (optional)'), + '$theurl' => $r[0]['obj_url'], + '$img_lbl' => t('URL for photo of thing (optional)'), + '$imgurl' => $r[0]['obj_imgurl'], + '$permissions' => t('Permissions'), + '$aclselect' => populate_acl($channel_acl,false), + '$lockstate' => $lockstate, + '$submit' => t('Submit') + )); + + return $o; + } + + if(argc() == 3 && argv(1) === 'drop') { + $thing_hash = argv(2); + + $r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc($thing_hash) + ); + + if((! $r) || ($r[0]['obj_channel'] != local_channel())) { + notice( t('Permission denied.') . EOL); + return ''; + } + + $x = q("delete from obj where obj_obj = '%s' and obj_type = %d and obj_channel = %d", + dbesc($thing_hash), + intval(TERM_OBJ_THING), + intval(local_channel()) + ); + + $r[0]['obj_deleted'] = 1; + + build_sync_packet(0,array('obj' => $r)); + + return $o; + } + + $o .= replace_macros(get_markup_template('thing_input.tpl'),array( + '$thing_hdr' => t('Add Thing to your Profile'), + '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), + '$profile_lbl' => t('Select a profile'), + '$profile_select' => contact_profile_assign(''), + '$verb_lbl' => $channel['channel_name'], + '$activity' => array('activity',t('Post an activity'),((array_key_exists('activity',$_REQUEST)) ? $_REQUEST['activity'] : true),t('Only sends to viewers of the applicable profile')), + '$verb_select' => obj_verb_selector(), + '$thing_lbl' => t('Name of thing e.g. something'), + '$url_lbl' => t('URL of thing (optional)'), + '$img_lbl' => t('URL for photo of thing (optional)'), + '$permissions' => t('Permissions'), + '$aclselect' => populate_acl($channel_acl,false), + '$lockstate' => $lockstate, + '$submit' => t('Submit') + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Toggle_mobile.php b/Zotlabs/Module/Toggle_mobile.php new file mode 100644 index 000000000..9d90c0821 --- /dev/null +++ b/Zotlabs/Module/Toggle_mobile.php @@ -0,0 +1,23 @@ + 1) { + $channel = \App::get_channel(); + + require_once('include/identity.php'); + + if(argc() > 1 && intval(argv(1)) > 1900) { + $year = intval(argv(1)); + } + + if(argc() > 2 && intval(argv(2)) > 0 && intval(argv(2)) <= 12) { + $month = intval(argv(2)); + } + + header('content-type: application/octet_stream'); + header('content-disposition: attachment; filename="' . $channel['channel_address'] . (($year) ? '-' . $year : '') . (($month) ? '-' . $month : '') . '.json"' ); + + if($year) { + echo json_encode(identity_export_year(local_channel(),$year,$month)); + killme(); + } + + if(argc() > 1 && argv(1) === 'basic') { + echo json_encode(identity_basic_export(local_channel())); + killme(); + } + + // FIXME - this basically doesn't work in the wild with a channel more than a few months old due to memory and execution time limits. + // It probably needs to be built at the CLI and offered to download as a tarball. Maybe stored in the members dav. + + if(argc() > 1 && argv(1) === 'complete') { + echo json_encode(identity_basic_export(local_channel(),true)); + killme(); + } + } + } + + function get() { + + $y = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); + + $yearurl = z_root() . '/uexport/' . $y; + $janurl = z_root() . '/uexport/' . $y . '/1'; + $impurl = '/import_items'; + $o = replace_macros(get_markup_template('uexport.tpl'), array( + '$title' => t('Export Channel'), + '$basictitle' => t('Export Channel'), + '$basic' => t('Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content.'), + '$fulltitle' => t('Export Content'), + '$full' => t('Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin.'), + '$by_year' => t('Export your posts from a given year.'), + + '$extra' => t('You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range.'), + '$extra2' => sprintf( t('To select all posts for a given year, such as this year, visit %2$s'),$yearurl,$yearurl), + '$extra3' => sprintf( t('To select all posts for a given month, such as January of this year, visit %2$s'),$janurl,$janurl), + '$extra4' => sprintf( t('These content files may be imported or restored by visiting %2$s on any site containing your channel. For best results please import or restore these in date order (oldest first).'),$impurl,$impurl) + + )); + return $o; + } + +} diff --git a/Zotlabs/Module/Update_display.php b/Zotlabs/Module/Update_display.php new file mode 100644 index 000000000..13b04204d --- /dev/null +++ b/Zotlabs/Module/Update_display.php @@ -0,0 +1,48 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + header("Content-type: text/html"); + echo "\r\n"; + echo (($_GET['msie'] == 1) ? '
    ' : '
    '); + + $mod = new Display(); + $text = $mod->get($profile_uid, $load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + */ + echo str_replace("\t",' ',$text); + echo (($_GET['msie'] == 1) ? '
    ' : ''); + echo "\r\n"; + // logger('update_display: ' . $text); + killme(); + + } + +} diff --git a/Zotlabs/Module/Update_home.php b/Zotlabs/Module/Update_home.php new file mode 100644 index 000000000..0f699482e --- /dev/null +++ b/Zotlabs/Module/Update_home.php @@ -0,0 +1,42 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + header("Content-type: text/html"); + echo "\r\n"; + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : '
    '); + + $mod = new Home(); + $text = $mod->get($profile_uid, $load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + */ + echo str_replace("\t",' ',$text); + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : ''); + echo "\r\n"; + // logger('update_home: ' . $text); + killme(); + + } +} diff --git a/Zotlabs/Module/Update_network.php b/Zotlabs/Module/Update_network.php new file mode 100644 index 000000000..c27b7614a --- /dev/null +++ b/Zotlabs/Module/Update_network.php @@ -0,0 +1,44 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + header("Content-type: text/html"); + echo "\r\n"; + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : '
    '); + + $mod = new Network(); + $text = $mod->get($profile_uid, $load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + */ + echo str_replace("\t",' ',$text); + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : ''); + echo "\r\n"; + // logger('update_network: ' . $text); + killme(); + + } +} diff --git a/Zotlabs/Module/Update_pubstream.php b/Zotlabs/Module/Update_pubstream.php new file mode 100644 index 000000000..153db56ba --- /dev/null +++ b/Zotlabs/Module/Update_pubstream.php @@ -0,0 +1,42 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + header("Content-type: text/html"); + echo "\r\n"; + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : '
    '); + + $mod = new Pubstream(); + $text = $mod->get($profile_uid, $load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + */ + echo str_replace("\t",' ',$text); + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '
    ' : ''); + echo "\r\n"; + killme(); + + } +} diff --git a/Zotlabs/Module/Update_search.php b/Zotlabs/Module/Update_search.php new file mode 100644 index 000000000..4491f40f4 --- /dev/null +++ b/Zotlabs/Module/Update_search.php @@ -0,0 +1,69 @@ + 1) && (argv(1) == 'load')) ? 1 : 0); + + header("Content-type: text/html"); + echo "\r\n"; + + /** + * We can remove this hack once Internet Explorer recognises HTML5 natively + */ + + echo (($_GET['msie'] == 1) ? '
    ' : '
    '); + + /** + * + * Grab the page inner contents by calling the content function from the profile module directly, + * but move any image src attributes to another attribute name. This is because + * some browsers will prefetch all the images for the page even if we don't need them. + * The only ones we need to fetch are those for new page additions, which we'll discover + * on the client side and then swap the image back. + * + */ + + $mod = new Search(); + $text = $mod->get($profile_uid,$load); + + $pattern = "/]*) src=\"([^\"]*)\"/"; + $replace = "'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + */ + /** + * reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well + */ + + echo str_replace("\t",' ',$text); + echo (($_GET['msie'] == 1) ? '
    ' : ''); + echo "\r\n"; + killme(); + + } +} diff --git a/Zotlabs/Module/View.php b/Zotlabs/Module/View.php new file mode 100644 index 000000000..85497a2a4 --- /dev/null +++ b/Zotlabs/Module/View.php @@ -0,0 +1,20 @@ + 1) + profile_load($a,argv(1)); + } + + function get() { + + if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + notice( t('Public access denied.') . EOL); + return; + } + + if(((! count(\App::$profile)) || (\App::$profile['hide_friends']))) { + notice( t('Permission denied.') . EOL); + return; + } + + if(! perm_is_allowed(\App::$profile['uid'], get_observer_hash(),'view_contacts')) { + notice( t('Permission denied.') . EOL); + return; + } + + if(! $_REQUEST['aj']) + $_SESSION['return_url'] = \App::$query_string; + + + $is_owner = ((local_channel() && local_channel() == \App::$profile['uid']) ? true : false); + + $abook_flags = " and abook_pending = 0 and abook_self = 0 "; + $sql_extra = ''; + + if(! $is_owner) { + $abook_flags = " and abook_hidden = 0 "; + $sql_extra = " and xchan_hidden = 0 "; + } + + $r = q("SELECT count(*) as total FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ", + intval(\App::$profile['uid']) + ); + if($r) { + \App::set_pager_total($r[0]['total']); + } + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra order by xchan_name LIMIT %d OFFSET %d ", + intval(\App::$profile['uid']), + intval(\App::$pager['itemspage']), + intval(\App::$pager['start']) + ); + + if((! $r) && (! $_REQUEST['aj'])) { + info( t('No connections.') . EOL ); + return $o; + } + + $contacts = array(); + + foreach($r as $rr) { + + $url = chanlink_url($rr['xchan_url']); + if($url) { + $contacts[] = array( + 'id' => $rr['abook_id'], + 'archived' => (intval($rr['abook_archived']) ? true : false), + 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $rr['xchan_name'], $rr['xchan_url']), + 'thumb' => $rr['xchan_photo_m'], + 'name' => substr($rr['xchan_name'],0,20), + 'username' => $rr['xchan_addr'], + 'link' => $url, + 'sparkle' => '', + 'itemurl' => $rr['url'], + 'network' => '', + ); + } + } + + + if($_REQUEST['aj']) { + if($contacts) { + $o = replace_macros(get_markup_template('viewcontactsajax.tpl'),array( + '$contacts' => $contacts + )); + } + else { + $o = '
    '; + } + echo $o; + killme(); + } + else { + $o .= ""; + $tpl = get_markup_template("viewcontact_template.tpl"); + $o .= replace_macros($tpl, array( + '$title' => t('View Connections'), + '$contacts' => $contacts, + // '$paginate' => paginate($a), + )); + } + + if(! $contacts) + $o .= '
    '; + + return $o; + } + +} diff --git a/Zotlabs/Module/Viewsrc.php b/Zotlabs/Module/Viewsrc.php new file mode 100644 index 000000000..63cc5e717 --- /dev/null +++ b/Zotlabs/Module/Viewsrc.php @@ -0,0 +1,53 @@ + 1) ? intval(argv(1)) : 0); + $json = ((argc() > 2 && argv(2) === 'json') ? true : false); + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + } + + + if(! $item_id) { + \App::$error = 404; + notice( t('Item not found.') . EOL); + } + + $item_normal = item_normal(); + + if(local_channel() && $item_id) { + $r = q("select id, item_flags, item_obscured, body from item where uid in (%d , %d) and id = %d $item_normal limit 1", + intval(local_channel()), + intval($sys['channel_id']), + intval($item_id) + ); + + if($r) { + if(intval($r[0]['item_obscured'])) + $r[0]['body'] = crypto_unencapsulate(json_decode($r[0]['body'],true),get_config('system','prvkey')); + $o = (($json) ? json_encode($r[0]['body']) : str_replace("\n",'
    ',$r[0]['body'])); + } + } + + if(is_ajax()) { + print '
    ' . t('Source of Item') . ' ' . $r[0]['id'] . '
    '; + echo $o; + killme(); + } + + return $o; + } + + +} diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php new file mode 100644 index 000000000..5bdecfa75 --- /dev/null +++ b/Zotlabs/Module/Wall_attach.php @@ -0,0 +1,55 @@ + 1) + $channel = get_channel_by_nick(argv(1)); + + if(! $channel) + killme(); + + $observer = \App::get_observer(); + + + $def_album = get_pconfig($channel['channel_id'],'system','photo_path'); + $def_attach = get_pconfig($channel['channel_id'],'system','attach_path'); + + $r = attach_store($channel,(($observer) ? $observer['xchan_hash'] : ''),'', array('source' => 'editor', 'visible' => 0, 'album' => $def_album, 'directory' => $def_attach, 'allow_cid' => '<' . $channel['channel_hash'] . '>')); + + if(! $r['success']) { + notice( $r['message'] . EOL); + killme(); + } + + if(intval($r['data']['is_photo'])) { + $s = "\n\n" . $r['body'] . "\n\n"; + } + else { + $s = "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n"; + } + + if($using_api) + return $s; + + echo $s; + killme(); + + } + +} diff --git a/Zotlabs/Module/Wall_upload.php b/Zotlabs/Module/Wall_upload.php new file mode 100644 index 000000000..fff3ed03a --- /dev/null +++ b/Zotlabs/Module/Wall_upload.php @@ -0,0 +1,57 @@ + 1) + $nick = argv(1); + } + + $channel = (($nick) ? get_channel_by_nick($nick) : false); + + if(! $channel) { + if($using_api) + return; + notice( t('Channel not found.') . EOL); + killme(); + } + + $observer = \App::get_observer(); + + $args = array( 'source' => 'editor', 'visible' => 0, 'contact_allow' => array($channel['channel_hash'])); + + $ret = photo_upload($channel,$observer,$args); + + if(! $ret['success']) { + if($using_api) + return; + notice($ret['message']); + killme(); + } + + if($using_api) + return("\n\n" . $ret['body'] . "\n\n"); + else + echo "\n\n" . $ret['body'] . "\n\n"; + killme(); + } + +} diff --git a/Zotlabs/Module/Webfinger.php b/Zotlabs/Module/Webfinger.php new file mode 100644 index 000000000..c50680de7 --- /dev/null +++ b/Zotlabs/Module/Webfinger.php @@ -0,0 +1,54 @@ +Webfinger Diagnostic'; + + $o .= '
    '; + $o .= 'Lookup address: '; + $o .= '
    '; + + $o .= '

    '; + + $old = false; + if(x($_GET,'addr')) { + $addr = trim($_GET['addr']); + // if(strpos($addr,'@') !== false) { + $res = webfinger_rfc7033($addr,true); + if(! $res) { + $res = old_webfinger($addr); + $old = true; + } + // } + // else { + // if(function_exists('lrdd')) + // $res = lrdd($addr); + // } + + if($res && $old) { + foreach($res as $r) { + if($r['@attributes']['rel'] === 'http://microformats.org/profile/hcard') { + $hcard = unamp($r['@attributes']['href']); + require_once('library/HTML5/Parser.php'); + $res['vcard'] = scrape_vcard($hcard); + break; + } + } + } + + + $o .= '
    ';
    +			$o .= str_replace("\n",'
    ',print_r($res,true)); + $o .= '
    '; + } + return $o; + } + +} diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php new file mode 100644 index 000000000..84d58058e --- /dev/null +++ b/Zotlabs/Module/Webpages.php @@ -0,0 +1,207 @@ + 1 && argv(1) === 'sys' && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + \App::$is_sys = true; + } + } + + if(argc() > 1) + $which = argv(1); + else + return; + + profile_load($a,$which); + + } + + + function get() { + + if(! \App::$profile) { + notice( t('Requested profile is not available.') . EOL ); + \App::$error = 404; + return; + } + + $which = argv(1); + + $_SESSION['return_url'] = \App::$query_string; + + $uid = local_channel(); + $owner = 0; + $channel = null; + $observer = \App::get_observer(); + + $channel = \App::get_channel(); + + if(\App::$is_sys && is_site_admin()) { + $sys = get_sys_channel(); + if($sys && intval($sys['channel_id'])) { + $uid = $owner = intval($sys['channel_id']); + $channel = $sys; + $observer = $sys; + } + } + + if(! $owner) { + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + } + + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + $mimetype = (($_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype')); + + if(! $mimetype) { + $mimetype = 'choose'; + } + + $layout = (($_REQUEST['layout']) ? $_REQUEST['layout'] : get_pconfig($owner,'system','page_layout')); + if(! $layout) + $layout = 'choose'; + + // Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages + // Nickname is set to the observers xchan, and profile_uid to the owner's. + // This lets you post pages at other people's channels. + + if((! $channel) && ($uid) && ($uid == \App::$profile_uid)) { + $channel = \App::get_channel(); + } + if($channel) { + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + } + else + $channel_acl = array(); + + $is_owner = ($uid && $uid == $owner); + $o = profile_tabs($a, $is_owner, \App::$profile['channel_address']); + + $x = array( + 'webpage' => ITEM_TYPE_WEBPAGE, + 'is_owner' => true, + 'nickname' => \App::$profile['channel_address'], + 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'bang' => '', + 'acl' => (($is_owner) ? populate_acl($channel_acl,false) : ''), + 'showacl' => (($is_owner) ? true : false), + 'visitor' => true, + 'profile_uid' => intval($owner), + 'mimetype' => $mimetype, + 'layout' => $layout, + 'expanded' => true, + 'novoting'=> true, + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true + ); + + if($_REQUEST['title']) + $x['title'] = $_REQUEST['title']; + if($_REQUEST['body']) + $x['body'] = $_REQUEST['body']; + if($_REQUEST['pagetitle']) + $x['pagetitle'] = $_REQUEST['pagetitle']; + + $editor = status_editor($a,$x); + + // Get a list of webpages. We can't display all them because endless scroll makes that unusable, + // so just list titles and an edit link. + + + /** @TODO - this should be replaced with pagelist_widget */ + + $sql_extra = item_permissions_sql($owner); + + $r = q("select * from item_id left join item on item_id.iid = item.id + where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc", + intval($owner), + intval(ITEM_TYPE_WEBPAGE) + ); + + $pages = null; + + if($r) { + $pages = array(); + foreach($r as $rr) { + unobscure($rr); + + $lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock'); + + $element_arr = array( + 'type' => 'webpage', + 'title' => $rr['title'], + 'body' => $rr['body'], + 'created' => $rr['created'], + 'edited' => $rr['edited'], + 'mimetype' => $rr['mimetype'], + 'pagetitle' => $rr['sid'], + 'mid' => $rr['mid'], + 'layout_mid' => $rr['layout_mid'] + ); + $pages[$rr['iid']][] = array( + 'url' => $rr['iid'], + 'pagetitle' => $rr['sid'], + 'title' => $rr['title'], + 'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']), + 'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']), + 'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]', + 'lockstate' => $lockstate + ); + } + } + + + //Build the base URL for edit links + $url = z_root() . '/editwebpage/' . $which; + + $o .= replace_macros(get_markup_template('webpagelist.tpl'), array( + '$listtitle' => t('Webpages'), + '$baseurl' => $url, + '$create' => t('Create'), + '$edit' => t('Edit'), + '$share' => t('Share'), + '$delete' => t('Delete'), + '$pages' => $pages, + '$channel' => $which, + '$editor' => $editor, + '$view' => t('View'), + '$preview' => t('Preview'), + '$actions_txt' => t('Actions'), + '$pagelink_txt' => t('Page Link'), + '$title_txt' => t('Page Title'), + '$created_txt' => t('Created'), + '$edited_txt' => t('Edited') + )); + + return $o; + } + +} diff --git a/Zotlabs/Module/Xchan.php b/Zotlabs/Module/Xchan.php new file mode 100644 index 000000000..526580fad --- /dev/null +++ b/Zotlabs/Module/Xchan.php @@ -0,0 +1,47 @@ +' . t('Xchan Lookup') . ''; + + $o .= '
    '; + $o .= t('Lookup xchan beginning with (or webbie): '); + $o .= ''; + $o .= '
    '; + $o .= '

    '; + + if(x($_GET, 'addr')) { + $addr = trim($_GET['addr']); + + $r = q("select * from xchan where xchan_hash like '%s%%' or xchan_addr = '%s' group by xchan_hash", + dbesc($addr), + dbesc($addr) + ); + + if($r) { + foreach($r as $rr) { + $o .= str_replace(array("\n", " "), array("
    ", " "), print_r($rr, true)) . EOL; + + $s = q("select * from hubloc where hubloc_hash like '%s'", + dbesc($r[0]['xchan_hash']) + ); + + if($s) { + foreach($s as $rrr) + $o .= str_replace(array("\n", " "), array("
    ", " "), print_r($rrr, true)) . EOL; + } + } + } + else + notice( t('Not found.') . EOL); + + } + return $o; + } + +} diff --git a/Zotlabs/Module/Xpoco.php b/Zotlabs/Module/Xpoco.php new file mode 100644 index 000000000..3ff05c4e1 --- /dev/null +++ b/Zotlabs/Module/Xpoco.php @@ -0,0 +1,13 @@ + z_root(), + '$dspr_guid' => $r[0]['channel_guid'] . str_replace('.','',\App::get_hostname()), + '$dspr_key' => base64_encode(pemtorsa($r[0]['channel_pubkey'])) + )); + + $salmon_key = salmon_key($r[0]['channel_pubkey']); + + header('Access-Control-Allow-Origin: *'); + header("Content-type: application/xrd+xml"); + + + $aliases = array('acct:' . $r[0]['channel_address'] . '@' . \App::get_hostname(), z_root() . '/channel/' . $r[0]['channel_address'], z_root() . '/~' . $r[0]['channel_address']); + + for($x = 0; $x < count($aliases); $x ++) { + if($aliases[$x] === $resource) + unset($aliases[$x]); + } + + + $o = replace_macros(get_markup_template('xrd_person.tpl'), array( + '$nick' => $r[0]['channel_address'], + '$accturi' => $resource, + '$aliases' => $aliases, + '$profile_url' => z_root() . '/channel/' . $r[0]['channel_address'], + '$hcard_url' => z_root() . '/hcard/' . $r[0]['channel_address'], + '$atom' => z_root() . '/feed/' . $r[0]['channel_address'], + '$zot_post' => z_root() . '/post/' . $r[0]['channel_address'], + '$poco_url' => z_root() . '/poco/' . $r[0]['channel_address'], + '$photo' => z_root() . '/photo/profile/l/' . $r[0]['channel_id'], + '$dspr' => $dspr, + // '$salmon' => z_root() . '/salmon/' . $r[0]['channel_address'], + // '$salmen' => z_root() . '/salmon/' . $r[0]['channel_address'] . '/mention', + '$modexp' => 'data:application/magic-public-key,' . $salmon_key, + '$subscribe' => z_root() . '/follow?url={uri}', + '$bigkey' => salmon_key($r[0]['channel_pubkey']) + )); + + + $arr = array('user' => $r[0], 'xml' => $o); + call_hooks('personal_xrd', $arr); + + echo $arr['xml']; + killme(); + + } + +} diff --git a/Zotlabs/Module/Xref.php b/Zotlabs/Module/Xref.php new file mode 100644 index 000000000..e9d494da4 --- /dev/null +++ b/Zotlabs/Module/Xref.php @@ -0,0 +1,26 @@ + 2) + $url = argv(2); + + goaway (z_root() . '/' . $url); + + } + +} diff --git a/Zotlabs/Module/Zcard.php b/Zotlabs/Module/Zcard.php new file mode 100644 index 000000000..b8967023e --- /dev/null +++ b/Zotlabs/Module/Zcard.php @@ -0,0 +1,107 @@ + 1) + $which = argv(1); + if(! $which) + return; + + + $arr = array(); + $arr['links'] = array(); + + $r = q("select * from channel left join xchan on xchan_hash = channel_hash where channel_address = '%s' limit 1", + dbesc($which) + ); + + if(! $which) { + notice( t('Channel not found.' ) . EOL); + return; + } + + $channel = $r[0]; + $channel['channel_addr'] = $r[0]['channel_address'] . '@' . \App::get_hostname(); + $arr['chan'] = $channel; + + if(perm_is_allowed($channel['channel_id'],get_observer_hash(),'view_profile')) { + $p = q("select * from profile where is_default = 1 and uid = %d limit 1", + intval($channel['channel_id']) + ); + } + $profile = (($p) ? $p[0] : false); + + $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale >= %d and photo_usage = %d", + intval($channel['channel_id']), + intval(PHOTO_RES_COVER_1200), + intval(PHOTO_COVER) + ); + + if($r) { + foreach($r as $rr) { + $arr['links'][] = array('rel' => 'cover_photo', 'type' => $rr['type'], 'width' => intval($rr['width']) , 'height' => intval($rr['height']), 'href' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale']); + } + } + + $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 48 , 'height' => 48, 'href' => $channel['xchan_photo_s']); + + + + $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", + intval(\App::$profile['profile_uid']), + dbesc(ACTIVITY_OBJ_PROFILE), + dbesc(ACTIVITY_LIKE) + ); + $profile['likers'] = array(); + $profile['like_count'] = count($likers); + $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); + if($likers) { + foreach($likers as $l) + $profile['likers'][] = array('name' => $l['xchan_name'],'url' => $l['xchan_url'], 'photo' => $l['xchan_photo_s']); + } + + $arr['profile'] = $profile; + + logger('zcard: ' . print_r($arr,true)); + + if(argc() > 2) + \App::$data['zcard'] = $arr; + else { + echo json_encode($arr); + killme(); + + } + */ + } + + + + function get() { + + $channel = channelx_by_nick(argv(1)); + if(! $channel) + return; + + $o = get_zcard($channel,get_observer_hash(),array('width' => $_REQUEST['width'], 'height' => $_REQUEST['height'])); + + // $o .= replace_macros(get_markup_template('zcard.tpl'),array( + // '$scale' => $scale, + // '$cover' => $cover, + // '$pphoto' => $pphoto, + // '$zcard' => $zcard, + // '$size' => 'small' + // )); + + return $o; + + + } +} diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php new file mode 100644 index 000000000..28040149f --- /dev/null +++ b/Zotlabs/Module/Zotfeed.php @@ -0,0 +1,52 @@ + false); + + $mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : ''); + if(! $mindate) + $mindate = datetime_convert('UTC','UTC', 'now - 14 days'); + + if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { + $result['message'] = 'Public access denied'; + json_return_and_die($result); + } + + $observer = \App::get_observer(); + + + $channel_address = ((argc() > 1) ? argv(1) : ''); + if($channel_address) { + $r = q("select channel_id, channel_name from channel where channel_address = '%s' and channel_removed = 0 limit 1", + dbesc(argv(1)) + ); + } + else { + $x = get_sys_channel(); + if($x) + $r = array($x); + $mindate = datetime_convert('UTC','UTC', 'now - 14 days'); + } + if(! $r) { + $result['message'] = 'Channel not found.'; + json_return_and_die($result); + } + + logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG); + + $result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate)); + $result['success'] = true; + json_return_and_die($result); + + + } + +} diff --git a/Zotlabs/Module/Zping.php b/Zotlabs/Module/Zping.php new file mode 100644 index 000000000..d6128fa66 --- /dev/null +++ b/Zotlabs/Module/Zping.php @@ -0,0 +1,33 @@ + Date: Mon, 18 Apr 2016 20:47:11 -0700 Subject: a bit more namespace wrangling --- Zotlabs/Module/Cloud.php | 8 ++++---- Zotlabs/Module/Impel.php | 2 +- Zotlabs/Module/Item.php | 2 +- Zotlabs/Module/New_channel.php | 4 ++-- Zotlabs/Module/Openid.php | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 0e04cb68b..5f40f4af1 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -7,7 +7,7 @@ namespace Zotlabs\Module; * Module for accessing the DAV storage area. */ -use Sabre\DAV; +use Sabre\DAV as SDAV; use \Zotlabs\Storage; // composer autoloader for SabreDAV @@ -70,10 +70,10 @@ class Cloud extends \Zotlabs\Web\Controller { $rootDirectory = new \Zotlabs\Storage\Directory('/', $auth); // A SabreDAV server-object - $server = new DAV\Server($rootDirectory); + $server = new SDAV\Server($rootDirectory); // prevent overwriting changes each other with a lock backend - $lockBackend = new DAV\Locks\Backend\File('store/[data]/locks'); - $lockPlugin = new DAV\Locks\Plugin($lockBackend); + $lockBackend = new SDAV\Locks\Backend\File('store/[data]/locks'); + $lockPlugin = new SDAV\Locks\Plugin($lockBackend); $server->addPlugin($lockPlugin); diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php index bdf5042dd..e326f7818 100644 --- a/Zotlabs/Module/Impel.php +++ b/Zotlabs/Module/Impel.php @@ -135,7 +135,7 @@ class Impel extends \Zotlabs\Web\Controller { if($j['pagetitle']) { require_once('library/urlify/URLify.php'); - $pagetitle = strtolower(URLify::transliterate($j['pagetitle'])); + $pagetitle = strtolower(\URLify::transliterate($j['pagetitle'])); } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 2c7a7b572..58660a839 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -130,7 +130,7 @@ class Item extends \Zotlabs\Web\Controller { if($pagetitle) { require_once('library/urlify/URLify.php'); - $pagetitle = strtolower(URLify::transliterate($pagetitle)); + $pagetitle = strtolower(\URLify::transliterate($pagetitle)); } diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index b77b2660b..3dca1b0b4 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -17,7 +17,7 @@ class New_channel extends \Zotlabs\Web\Controller { $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['name']); - $x = strtolower(URLify::transliterate($n)); + $x = strtolower(\URLify::transliterate($n)); $test = array(); @@ -43,7 +43,7 @@ class New_channel extends \Zotlabs\Web\Controller { $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['nick']); - $x = strtolower(URLify::transliterate($n)); + $x = strtolower(\URLify::transliterate($n)); $test = array(); diff --git a/Zotlabs/Module/Openid.php b/Zotlabs/Module/Openid.php index c24686e33..7a6e4a81f 100644 --- a/Zotlabs/Module/Openid.php +++ b/Zotlabs/Module/Openid.php @@ -121,7 +121,7 @@ class Openid extends \Zotlabs\Web\Controller { } require_once('library/urlify/URLify.php'); - $x = strtolower(URLify::transliterate($nick)); + $x = strtolower(\URLify::transliterate($nick)); if($nick & $host) $addr = $nick . '@' . $host; $network = 'unknown'; -- cgit v1.2.3 From 7594796ee11c0b245d02d145868a13ac3d84ebfc Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 19 Apr 2016 05:52:16 -0400 Subject: Try toggling context help using onclick attribute --- Zotlabs/Module/Admin.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 8cc08fd13..d360f7b9d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -264,6 +264,7 @@ class Admin extends \Zotlabs\Web\Controller { $force_publish = ((x($_POST,'publish_all')) ? True : False); $disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True); $login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False); + $enable_context_help = ((x($_POST,'enable_context_help')) ? True : False); $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : ''); $no_community_page = !((x($_POST,'no_community_page')) ? True : False); $default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0); @@ -288,6 +289,7 @@ class Admin extends \Zotlabs\Web\Controller { set_config('system', 'mirror_frontpage', $mirror_frontpage); set_config('system', 'sitename', $sitename); set_config('system', 'login_on_homepage', $login_on_homepage); + set_config('system', 'enable_context_help', $enable_context_help); set_config('system', 'verify_email', $verify_email); set_config('system', 'default_expire_days', $default_expire_days); @@ -488,7 +490,8 @@ class Admin extends \Zotlabs\Web\Controller { '$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")), '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), '$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')), - '$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.")), + '$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.")), '$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null), -- cgit v1.2.3 From 974390d5d295b852343e92ce30b7deb793220906 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 19 Apr 2016 19:02:48 -0700 Subject: remove test files which were committed by accident --- Zotlabs/Module/Pushcall.php | 19 -------- Zotlabs/Module/Test.php | 38 ---------------- Zotlabs/Module/Zcard.php | 107 -------------------------------------------- 3 files changed, 164 deletions(-) delete mode 100644 Zotlabs/Module/Pushcall.php delete mode 100644 Zotlabs/Module/Test.php delete mode 100644 Zotlabs/Module/Zcard.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pushcall.php b/Zotlabs/Module/Pushcall.php deleted file mode 100644 index c0b95159d..000000000 --- a/Zotlabs/Module/Pushcall.php +++ /dev/null @@ -1,19 +0,0 @@ - - - macgirvin@diasp.org - Mike - Macgirvin - https://diasp.org/uploads/images/thumb_large_d5f9b6384c91f532f280.jpg - https://diasp.org/uploads/images/thumb_small_d5f9b6384c91f532f280.jpg - https://diasp.org/uploads/images/thumb_medium_d5f9b6384c91f532f280.jpg - 1000-05-14 - - Creator of Friendica, Redmatrix, and Hubzilla. - Australia - true - false - #redmatrix #hubzilla - - '; - - $parsed_xml = xml2array($s,false,0,'tag'); - - $o = print_r($parsed_xml,true); - return $o; - - - // fix_system_urls('http://hz.macgirvin.com',z_root()); - - } - -} diff --git a/Zotlabs/Module/Zcard.php b/Zotlabs/Module/Zcard.php deleted file mode 100644 index b8967023e..000000000 --- a/Zotlabs/Module/Zcard.php +++ /dev/null @@ -1,107 +0,0 @@ - 1) - $which = argv(1); - if(! $which) - return; - - - $arr = array(); - $arr['links'] = array(); - - $r = q("select * from channel left join xchan on xchan_hash = channel_hash where channel_address = '%s' limit 1", - dbesc($which) - ); - - if(! $which) { - notice( t('Channel not found.' ) . EOL); - return; - } - - $channel = $r[0]; - $channel['channel_addr'] = $r[0]['channel_address'] . '@' . \App::get_hostname(); - $arr['chan'] = $channel; - - if(perm_is_allowed($channel['channel_id'],get_observer_hash(),'view_profile')) { - $p = q("select * from profile where is_default = 1 and uid = %d limit 1", - intval($channel['channel_id']) - ); - } - $profile = (($p) ? $p[0] : false); - - $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale >= %d and photo_usage = %d", - intval($channel['channel_id']), - intval(PHOTO_RES_COVER_1200), - intval(PHOTO_COVER) - ); - - if($r) { - foreach($r as $rr) { - $arr['links'][] = array('rel' => 'cover_photo', 'type' => $rr['type'], 'width' => intval($rr['width']) , 'height' => intval($rr['height']), 'href' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale']); - } - } - - $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); - $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); - $arr['links'][] = array('rel' => 'profile_photo', 'type' => $channel['xchan_photo_mimetype'], 'width' => 48 , 'height' => 48, 'href' => $channel['xchan_photo_s']); - - - - $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", - intval(\App::$profile['profile_uid']), - dbesc(ACTIVITY_OBJ_PROFILE), - dbesc(ACTIVITY_LIKE) - ); - $profile['likers'] = array(); - $profile['like_count'] = count($likers); - $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); - if($likers) { - foreach($likers as $l) - $profile['likers'][] = array('name' => $l['xchan_name'],'url' => $l['xchan_url'], 'photo' => $l['xchan_photo_s']); - } - - $arr['profile'] = $profile; - - logger('zcard: ' . print_r($arr,true)); - - if(argc() > 2) - \App::$data['zcard'] = $arr; - else { - echo json_encode($arr); - killme(); - - } - */ - } - - - - function get() { - - $channel = channelx_by_nick(argv(1)); - if(! $channel) - return; - - $o = get_zcard($channel,get_observer_hash(),array('width' => $_REQUEST['width'], 'height' => $_REQUEST['height'])); - - // $o .= replace_macros(get_markup_template('zcard.tpl'),array( - // '$scale' => $scale, - // '$cover' => $cover, - // '$pphoto' => $pphoto, - // '$zcard' => $zcard, - // '$size' => 'small' - // )); - - return $o; - - - } -} -- cgit v1.2.3 From 9040ee53e45f61b13a98a7e9b82f223b9f0265e7 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 19 Apr 2016 19:09:35 -0700 Subject: missing class instance pointer in Pconfig module upgrade --- Zotlabs/Module/Pconfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php index 01899ffdb..b6264bddc 100644 --- a/Zotlabs/Module/Pconfig.php +++ b/Zotlabs/Module/Pconfig.php @@ -55,7 +55,7 @@ class Pconfig extends \Zotlabs\Web\Controller { $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . ']' . EOL . EOL; $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . escape_tags(argv(2)) . '] = ' . get_pconfig(local_channel(),escape_tags(argv(1)),escape_tags(argv(2))) . EOL; - if(in_array(argv(2),disallowed_pconfig())) { + if(in_array(argv(2),$this->disallowed_pconfig())) { notice( t('This setting requires special processing and editing has been blocked.') . EOL); return $content; } -- cgit v1.2.3 From dff9e18c1e7051c6ff340f91feb118c6f177b7d8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 20 Apr 2016 19:54:26 -0700 Subject: We no longer require the diaspora_meta service locally. --- Zotlabs/Module/Item.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 58660a839..74fbeed67 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -984,9 +984,9 @@ class Item extends \Zotlabs\Web\Controller { if(($parent) && ($parent != $post_id)) { // Store the comment signature information in case we need to relay to Diaspora - $ditem = $datarray; - $ditem['author'] = $observer; - store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); + //$ditem = $datarray; + //$ditem['author'] = $observer; + //store_diaspora_comment_sig($ditem,$channel,$parent_item, $post_id, (($walltowall_comment) ? 1 : 0)); } else { $r = q("select * from item where id = %d", -- cgit v1.2.3 From 2b0a04ea9e91196e2966844be0f6b673bd87f032 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 20 Apr 2016 22:10:00 -0700 Subject: revert the reversal of checkjs logic, but still restrict the behaviour scope to just those urls that require it --- Zotlabs/Module/Channel.php | 2 +- Zotlabs/Module/Display.php | 2 +- Zotlabs/Module/Nojs.php | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index cae561266..36f13e775 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -57,7 +57,7 @@ function get($update = 0, $load = false) { if($load) $_SESSION['loadtime'] = datetime_convert(); - $checkjs = new \Zotlabs\Web\CheckJS(); + $checkjs = new \Zotlabs\Web\CheckJS(1); $category = $datequery = $datequery2 = ''; diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 3d24c6c9a..2a5a04a2a 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -10,7 +10,7 @@ class Display extends \Zotlabs\Web\Controller { // logger("mod-display: update = $update load = $load"); - $checkjs = new \Zotlabs\Web\CheckJS(); + $checkjs = new \Zotlabs\Web\CheckJS(1); if($load) diff --git a/Zotlabs/Module/Nojs.php b/Zotlabs/Module/Nojs.php index 5e48c5b5f..6fd6d8106 100644 --- a/Zotlabs/Module/Nojs.php +++ b/Zotlabs/Module/Nojs.php @@ -5,11 +5,11 @@ namespace Zotlabs\Module; class Nojs extends \Zotlabs\Web\Controller { function init() { - - setcookie('jsdisabled', 1, 0); - $p = $_GET['query']; + $n = ((argc() > 1) ? intval(argv(1)) : 1); + setcookie('jsdisabled', $n, 0, '/'); + $p = $_GET['redir']; $hasq = strpos($p,'?'); - goaway(z_root() . (($p) ? '/' . $p : '') . (($hasq) ? '' : '?f=' ) . '&jsdisabled=1'); + goaway(z_root() . (($p) ? '/' . $p : '') . (($hasq) ? '' : '?f=' ) . '&jsdisabled=' . $n); } } -- cgit v1.2.3 From 82de68c3d3ff931fad4ddb48a69cf62576a5397a Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 21 Apr 2016 06:41:55 -0400 Subject: Added admin/site setting that toggles context help panel. If disabled, original help menu button behavior is restored. --- Zotlabs/Module/Admin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index d360f7b9d..1ff9065cd 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -455,6 +455,7 @@ class Admin extends \Zotlabs\Web\Controller { $homelogin = get_config('system','login_on_homepage'); + $enable_context_help = get_config('system','enable_context_help'); $t = get_markup_template("admin_site.tpl"); return replace_macros($t, array( @@ -491,7 +492,7 @@ class Admin extends \Zotlabs\Web\Controller { '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), '$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')), '$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.")), + '$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.")), '$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null), -- cgit v1.2.3 From 5a427dcee3ca9bce3fcb5de6a67292a405ee6736 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 21 Apr 2016 20:14:55 -0700 Subject: No idea how long RSD (Really Simple Discovery) has been broken. I had no idea it was even here. --- Zotlabs/Module/Rsd_xml.php | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Rsd_xml.php b/Zotlabs/Module/Rsd_xml.php index 114ecc49b..06af39ad1 100644 --- a/Zotlabs/Module/Rsd_xml.php +++ b/Zotlabs/Module/Rsd_xml.php @@ -1,29 +1,17 @@ - - - Red - http://friendica.com/ - - - - http://status.net/wiki/TwitterCompatibleAPI - false - - - - - - '; - die(); + echo replace_macros(get_markup_template('rsd.tpl'),array( + '$project' => \Zotlabs\Project\System::get_platform_name(), + '$baseurl' => z_root(), + '$apipath' => z_root() . '/api/' + )); + killme(); } + } + -- cgit v1.2.3 From a3ce194bf52c6db63513754b0c3e8676928a2cfd Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 21 Apr 2016 22:16:57 -0700 Subject: Some issues discovered with linkinfo module, and update the doco about using object modules in addons; as there were a couple of surprises. --- Zotlabs/Module/Linkinfo.php | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php index a1008f7c4..ef34bb465 100644 --- a/Zotlabs/Module/Linkinfo.php +++ b/Zotlabs/Module/Linkinfo.php @@ -111,7 +111,7 @@ class Linkinfo extends \Zotlabs\Web\Controller { killme(); } - $siteinfo = parseurl_getsiteinfo($url); + $siteinfo = self::parseurl_getsiteinfo($url); // If this is a Red site, use zrl rather than url so they get zids sent to them by default @@ -172,14 +172,14 @@ class Linkinfo extends \Zotlabs\Web\Controller { } - function deletexnode(&$doc, $node) { - $xpath = new DomXPath($doc); + public static function deletexnode(&$doc, $node) { + $xpath = new \DomXPath($doc); $list = $xpath->query("//".$node); foreach ($list as $child) $child->parentNode->removeChild($child); } - function completeurl($url, $scheme) { + public static function completeurl($url, $scheme) { $urlarr = parse_url($url); if (isset($urlarr["scheme"])) @@ -207,7 +207,7 @@ class Linkinfo extends \Zotlabs\Web\Controller { } - function parseurl_getsiteinfo($url) { + public static function parseurl_getsiteinfo($url) { $siteinfo = array(); @@ -221,22 +221,22 @@ class Linkinfo extends \Zotlabs\Web\Controller { $body = mb_convert_encoding($body, 'UTF-8', 'UTF-8'); $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); - $doc = new DOMDocument(); + $doc = new \DOMDocument(); @$doc->loadHTML($body); - $this->deletexnode($doc, 'style'); - $this->deletexnode($doc, 'script'); - $this->deletexnode($doc, 'option'); - $this->deletexnode($doc, 'h1'); - $this->deletexnode($doc, 'h2'); - $this->deletexnode($doc, 'h3'); - $this->deletexnode($doc, 'h4'); - $this->deletexnode($doc, 'h5'); - $this->deletexnode($doc, 'h6'); - $this->deletexnode($doc, 'ol'); - $this->deletexnode($doc, 'ul'); + self::deletexnode($doc, 'style'); + self::deletexnode($doc, 'script'); + self::deletexnode($doc, 'option'); + self::deletexnode($doc, 'h1'); + self::deletexnode($doc, 'h2'); + self::deletexnode($doc, 'h3'); + self::deletexnode($doc, 'h4'); + self::deletexnode($doc, 'h5'); + self::deletexnode($doc, 'h6'); + self::deletexnode($doc, 'ol'); + self::deletexnode($doc, 'ul'); - $xpath = new DomXPath($doc); + $xpath = new \DomXPath($doc); //$list = $xpath->query("head/title"); $list = $xpath->query("//title"); @@ -303,7 +303,7 @@ class Linkinfo extends \Zotlabs\Web\Controller { foreach ($node->attributes as $attribute) $attr[$attribute->name] = $attribute->value; - $src = $this->completeurl($attr["src"], $url); + $src = self::completeurl($attr["src"], $url); $photodata = @getimagesize($src); if (($photodata) && ($photodata[0] > 150) and ($photodata[1] > 150)) { @@ -322,7 +322,7 @@ class Linkinfo extends \Zotlabs\Web\Controller { } } else { - $src = $this->completeurl($siteinfo["image"], $url); + $src = self::completeurl($siteinfo["image"], $url); unset($siteinfo["image"]); -- cgit v1.2.3 From a9d926886e6f8ed389031791799ffd352b8cb651 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Mon, 25 Apr 2016 10:00:50 +0200 Subject: make it more obvious what is behind the dropdowns --- Zotlabs/Module/Connedit.php | 5 +++-- Zotlabs/Module/Photos.php | 1 + Zotlabs/Module/Profiles.php | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 2b524096f..a1268510d 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -514,7 +514,7 @@ class Connedit extends \Zotlabs\Web\Controller { $contact_id = \App::$poi['abook_id']; $contact = \App::$poi; - $buttons = array( + $tools = array( 'view' => array( 'label' => t('View Profile'), @@ -711,7 +711,8 @@ class Connedit extends \Zotlabs\Web\Controller { '$notself' => (($self) ? '' : '1'), '$self' => (($self) ? '1' : ''), '$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'), - '$buttons' => (($self) ? '' : $buttons), + '$tools_label' => t('Connection Tools'), + '$tools' => (($self) ? '' : $tools), '$lbl_slider' => t('Slide to adjust your degree of friendship'), '$lbl_rating' => t('Rating'), '$lbl_rating_label' => t('Slide to adjust your rating'), diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 00a577847..ce350666f 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -1231,6 +1231,7 @@ class Photos extends \Zotlabs\Web\Controller { $o .= replace_macros($photo_tpl, array( '$id' => $ph[0]['id'], '$album' => $album_e, + '$tools_label' => t('Photo Tools'), '$tools' => $tools, '$lock' => $lockstate[1], '$photo' => $photo, diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 30ec337f8..72edf396f 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -691,6 +691,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$submit' => t('Submit'), '$viewprof' => t('View this profile'), '$editvis' => t('Edit visibility'), + '$tools_label' => t('Profile Tools'), '$coverpic' => t('Change cover photo'), '$profpic' => t('Change profile photo'), '$cr_prof' => t('Create a new profile using these settings'), -- cgit v1.2.3 From a6baa5a6da5f5231c119cab3170f68cf271f703b Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 27 Apr 2016 11:36:02 +0200 Subject: some refinements on jot --- Zotlabs/Module/Editblock.php | 17 +++++------------ Zotlabs/Module/Editwebpage.php | 15 ++++----------- 2 files changed, 9 insertions(+), 23 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 90016952e..2821b3fe0 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -143,16 +143,11 @@ class Editblock extends \Zotlabs\Web\Controller { '$underline' => t('Underline'), '$quote' => t('Quote'), '$code' => t('Code'), - '$writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_storage'), - '$upload' => t('Upload photo'), + '$writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), '$attach' => t('Attach file'), - '$weblink' => t('Insert web link'), - '$youtube' => t('Insert YouTube video'), - '$video' => t('Insert Vorbis [.ogg] video'), - '$audio' => t('Insert Vorbis [.ogg] audio'), - '$setloc' => t('Set your location'), - '$noloc' => t('Clear browser location'), - '$wait' => t('Please wait'), + '$weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), + '$setloc' => false, + '$noloc' => false, '$permset' => t('Permission settings'), '$ptyp' => $itm[0]['type'], '$mimeselect' => $mimeselect, @@ -160,7 +155,7 @@ class Editblock extends \Zotlabs\Web\Controller { '$post_id' => $post_id, '$baseurl' => z_root(), '$defloc' => $channel['channel_location'], - '$visitor' => false, + '$visitor' => true, '$public' => t('Public post'), '$jotnets' => $jotnets, '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), @@ -177,8 +172,6 @@ class Editblock extends \Zotlabs\Web\Controller { '$jotplugins' => $jotplugins, '$sourceapp' => $itm[0]['app'], '$defexpire' => '', - '$feature_expire' => false, - '$expires' => t('Set expiration date'), '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) )); diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 01d9e8aad..d3b031db2 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -176,7 +176,7 @@ class Editwebpage extends \Zotlabs\Web\Controller { '$webpage' => ITEM_TYPE_WEBPAGE, '$placeholdpagetitle' => t('Page link title'), '$pagetitle' => $page_title, - '$writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_storage'), + '$writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), '$action' => 'item', '$share' => t('Edit'), '$bold' => t('Bold'), @@ -184,15 +184,10 @@ class Editwebpage extends \Zotlabs\Web\Controller { '$underline' => t('Underline'), '$quote' => t('Quote'), '$code' => t('Code'), - '$upload' => t('Upload photo'), '$attach' => t('Attach file'), - '$weblink' => t('Insert web link'), - '$youtube' => t('Insert YouTube video'), - '$video' => t('Insert Vorbis [.ogg] video'), - '$audio' => t('Insert Vorbis [.ogg] audio'), - '$setloc' => t('Set your location'), - '$noloc' => ((get_pconfig($uid, 'system', 'use_browser_location')) ? t('Clear browser location') : ''), - '$wait' => t('Please wait'), + '$weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), + '$setloc' => false, //t('Set your location'), + '$noloc' => false, //((get_pconfig($uid, 'system', 'use_browser_location')) ? t('Clear browser location') : ''), '$permset' => t('Permission settings'), '$ptyp' => $itm[0]['type'], '$content' => undo_post_tagging($itm[0]['body']), @@ -218,8 +213,6 @@ class Editwebpage extends \Zotlabs\Web\Controller { '$jotplugins' => $jotplugins, '$sourceapp' => \App::$sourcename, '$defexpire' => '', - '$feature_expire' => false, - '$expires' => t('Set expiration date'), '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) )); -- cgit v1.2.3 From 30a6ae3daa42da8d1d9560fcc4c706b3e41c4d80 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 28 Apr 2016 20:17:05 -0700 Subject: This setting isn't implemented so remove the UI until it is. --- Zotlabs/Module/Admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 1ff9065cd..1d37b41bc 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -725,7 +725,7 @@ class Admin extends \Zotlabs\Web\Controller { '$embed_allow' => array('embed_allow', t('Allow embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), - '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), +// '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), '$submit' => t('Submit') )); } -- cgit v1.2.3 From bb96f44861c66e9eb334e18e4b4b659685433008 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 28 Apr 2016 21:02:27 -0700 Subject: allow engineering units (e.g. 400M, 1G) as service class limits --- Zotlabs/Module/Item.php | 4 ++-- Zotlabs/Module/Photos.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 74fbeed67..93570fdec 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -1243,14 +1243,14 @@ class Item extends \Zotlabs\Web\Controller { } if (!$iswebpage) { - $max = service_class_fetch($channel_id,'total_items'); + $max = engr_units_to_bytes(service_class_fetch($channel_id,'total_items')); if(! service_class_allows($channel_id,'total_items',$r[0]['total'])) { $result['message'] .= upgrade_message() . sprintf( t('You have reached your limit of %1$.0f top level posts.'),$max); return $result; } } else { - $max = service_class_fetch($channel_id,'total_pages'); + $max = engr_units_to_bytes(service_class_fetch($channel_id,'total_pages')); if(! service_class_allows($channel_id,'total_pages',$r[0]['total'])) { $result['message'] .= upgrade_message() . sprintf( t('You have reached your limit of %1$.0f webpages.'),$max); return $result; diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index ce350666f..15a1f4d9c 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -615,7 +615,7 @@ class Photos extends \Zotlabs\Web\Controller { ); - $limit = service_class_fetch(\App::$data['channel']['channel_id'],'photo_upload_limit'); + $limit = engr_units_to_bytes(service_class_fetch(\App::$data['channel']['channel_id'],'photo_upload_limit')); if($limit !== false) { $usage_message = sprintf( t("%1$.2f MB of %2$.2f MB photo storage used."), $r[0]['total'] / 1024000, $limit / 1024000 ); } -- cgit v1.2.3 From b797528b78107b707dc1c56d70e07136d7c31028 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 29 Apr 2016 13:18:42 +0200 Subject: some work on making mod editpost use status_editor() - if you find anything related to jot broken please revert this commit --- Zotlabs/Module/Editpost.php | 115 +++++++++++--------------------------------- 1 file changed, 28 insertions(+), 87 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index d8b971f6c..fd9912fe9 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -5,7 +5,7 @@ require_once('include/acl_selectors.php'); require_once('include/crypto.php'); require_once('include/items.php'); require_once('include/taxonomy.php'); - +require_once('include/conversation.php'); class Editpost extends \Zotlabs\Web\Controller { @@ -49,20 +49,7 @@ class Editpost extends \Zotlabs\Web\Controller { // $plaintext = false; $channel = \App::get_channel(); - - \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( - '$baseurl' => z_root(), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$pretext' => '', - '$ispublic' => ' ', // t('Visible to everybody'), - '$geotag' => $geotag, - '$nickname' => $channel['channel_address'], - '$expireswhen' => t('Expires YYYY-MM-DD HH:MM'), - '$confirmdelete' => t('Delete item?'), - '$editor_autocomplete'=> true, - '$bbco_autocomplete'=> 'bbcode' - )); - + if(intval($itm[0]['item_obscured'])) { $key = get_config('system','prvkey'); if($itm[0]['title']) @@ -71,18 +58,6 @@ class Editpost extends \Zotlabs\Web\Controller { $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); } - $tpl = get_markup_template("jot.tpl"); - - $jotplugins = ''; - $jotnets = ''; - - call_hooks('jot_tool', $jotplugins); - call_hooks('jot_networks', $jotnets); - - //$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins)); - - $voting = feature_enabled($owner_uid,'consensus_tools'); - $category = ''; $catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : ''); @@ -106,66 +81,32 @@ class Editpost extends \Zotlabs\Web\Controller { } } } - - $cipher = get_pconfig(\App::$profile['profile_uid'],'system','default_cipher'); - if(! $cipher) - $cipher = 'aes256'; - - - $editor = replace_macros($tpl,array( - '$return_path' => $_SESSION['return_url'], - '$action' => 'item', - '$share' => t('Edit'), - '$bold' => t('Bold'), - '$italic' => t('Italic'), - '$underline' => t('Underline'), - '$quote' => t('Quote'), - '$code' => t('Code'), - '$upload' => t('Upload photo'), - '$attach' => t('Attach file'), - '$weblink' => t('Insert web link'), - '$youtube' => t('Insert YouTube video'), - '$video' => t('Insert Vorbis [.ogg] video'), - '$audio' => t('Insert Vorbis [.ogg] audio'), - '$setloc' => t('Set your location'), - '$noloc' => t('Clear browser location'), - '$voting' => t('Toggle voting'), - '$feature_voting' => $voting, - '$consensus' => intval($itm[0]['item_consensus']), - '$wait' => t('Please wait'), - '$permset' => t('Permission settings'), - '$ptyp' => $itm[0]['obj_type'], - '$content' => undo_post_tagging($itm[0]['body']), - '$post_id' => $post_id, - '$parent' => (($itm[0]['parent'] != $itm[0]['id']) ? $itm[0]['parent'] : ''), - '$baseurl' => z_root(), - '$defloc' => $channel['channel_location'], - '$visitor' => false, - '$public' => t('Public post'), - '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), - '$placeholdertitle' => t('Title (optional)'), - '$category' => $category, - '$placeholdercategory' => t('Categories (optional, comma-separated list)'), - '$emtitle' => t('Example: bob@example.com, mary@example.com'), - '$lockstate' => $lockstate, - '$acl' => '', - '$bang' => '', - '$profile_uid' => $owner_uid, - '$preview' => t('Preview'), - '$jotplugins' => $jotplugins, - '$sourceapp' => t(\App::$sourcename), - '$catsenabled' => $catsenabled, - '$defexpire' => datetime_convert('UTC', date_default_timezone_get(),$itm[0]['expires']), - '$feature_expire' => ((feature_enabled(\App::$profile['profile_uid'],'content_expire') && (! $webpage)) ? true : false), - '$expires' => t('Set expiration date'), - '$feature_encrypt' => ((feature_enabled(\App::$profile['profile_uid'],'content_encrypt') && (! $webpage)) ? true : false), - '$encrypt' => t('Encrypt text'), - '$cipher' => $cipher, - '$expiryModalOK' => t('OK'), - '$expiryModalCANCEL' => t('Cancel'), - '$bbcode' => true - )); + + $x = array( + 'ispublic' => ' ', + 'nickname' => $channel['channel_address'], + 'editor_autocomplete'=> true, + 'bbco_autocomplete'=> 'bbcode', + 'return_path' => $_SESSION['return_url'], + 'button' => t('Edit'), + 'hide_voting' => true, + 'hide_future' => true, + 'hide_location' => true, + 'ptyp' => $itm[0]['obj_type'], + 'body' => undo_post_tagging($itm[0]['body']), + 'post_id' => $post_id, + 'defloc' => $channel['channel_location'], + 'visitor' => true, + 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + 'category' => $category, + 'showacl' => false, + 'profile_uid' => $owner_uid, + 'catsenabled' => $catsenabled, + 'hide_expire' => true, + 'bbcode' => true + ); + + $editor = status_editor($a, $x); $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit post'), -- cgit v1.2.3 From 931a4fafe316b23bacf92ac1ff35f9b8467415dd Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 29 Apr 2016 21:38:36 +0200 Subject: get rid of the unused ispublic variable --- Zotlabs/Module/Cal.php | 2 +- Zotlabs/Module/Editpost.php | 1 - Zotlabs/Module/Photos.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php index 89967bca1..958ce5aa6 100644 --- a/Zotlabs/Module/Cal.php +++ b/Zotlabs/Module/Cal.php @@ -38,7 +38,7 @@ class Cal extends \Zotlabs\Web\Controller { head_set_icon(\App::$data['channel']['xchan_photo_s']); - \App::$page['htmlhead'] .= "" ; + \App::$page['htmlhead'] .= "" ; } diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index fd9912fe9..1c2c2a30b 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -83,7 +83,6 @@ class Editpost extends \Zotlabs\Web\Controller { } $x = array( - 'ispublic' => ' ', 'nickname' => $channel['channel_address'], 'editor_autocomplete'=> true, 'bbco_autocomplete'=> 'bbcode', diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 15a1f4d9c..2b7f5525f 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -42,7 +42,7 @@ class Photos extends \Zotlabs\Web\Controller { head_set_icon(\App::$data['channel']['xchan_photo_s']); - \App::$page['htmlhead'] .= "" ; + \App::$page['htmlhead'] .= "" ; } -- cgit v1.2.3 From 7d380570df62b3f90daf197a1044d45e073c97a7 Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 1 May 2016 04:13:30 +1000 Subject: update icon names in Zotlabs/ --- Zotlabs/Module/Pubsites.php | 6 +++--- Zotlabs/Module/Viewsrc.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index 559c8f2f1..9313a3c5a 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -34,16 +34,16 @@ class Pubsites extends \Zotlabs\Web\Controller { if($jj['project'] !== \Zotlabs\Project\System::get_platform_name()) continue; $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); - $rate_links = ((local_channel()) ? ' ' . t('Rate') . '' : ''); + $rate_links = ((local_channel()) ? ' ' . t('Rate') . '' : ''); $location = ''; if(!empty($jj['location'])) { - $location = '

    ' . $jj['location'] . '

    '; + $location = '

    ' . $jj['location'] . '

    '; } else { $location = '
     '; } $urltext = str_replace(array('https://'), '', $jj['url']); - $o .= ' ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '' . $rate_links . ''; + $o .= ' ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '' . $rate_links . ''; } } diff --git a/Zotlabs/Module/Viewsrc.php b/Zotlabs/Module/Viewsrc.php index 63cc5e717..fa755a3ec 100644 --- a/Zotlabs/Module/Viewsrc.php +++ b/Zotlabs/Module/Viewsrc.php @@ -41,7 +41,7 @@ class Viewsrc extends \Zotlabs\Web\Controller { } if(is_ajax()) { - print '
    ' . t('Source of Item') . ' ' . $r[0]['id'] . '
    '; + print '
    ' . t('Source of Item') . ' ' . $r[0]['id'] . '
    '; echo $o; killme(); } -- cgit v1.2.3 From ab17b2e0d68cbd7e7fdbb510b4cc20a202077586 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 30 Apr 2016 20:47:52 +0200 Subject: minor cleanup --- Zotlabs/Module/Editpost.php | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 1c2c2a30b..25ba1a39a 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -10,44 +10,38 @@ require_once('include/conversation.php'); class Editpost extends \Zotlabs\Web\Controller { function get() { - + $o = ''; - + if(! local_channel()) { notice( t('Permission denied.') . EOL); return; } - + $post_id = ((argc() > 1) ? intval(argv(1)) : 0); - + if(! $post_id) { notice( t('Item not found') . EOL); return; } - + $itm = q("SELECT * FROM `item` WHERE `id` = %d AND ( owner_xchan = '%s' OR author_xchan = '%s' ) LIMIT 1", intval($post_id), dbesc(get_observer_hash()), dbesc(get_observer_hash()) ); - + if(! count($itm)) { notice( t('Item is not editable') . EOL); return; } - + if($itm[0]['resource_type'] === 'event' && $itm[0]['resource_id']) { goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1'); } - - + $owner_uid = $itm[0]['uid']; - - - $plaintext = true; - // if(feature_enabled(local_channel(),'richtext')) - // $plaintext = false; - + $channel = \App::get_channel(); if(intval($itm[0]['item_obscured'])) { @@ -57,10 +51,10 @@ class Editpost extends \Zotlabs\Web\Controller { if($itm[0]['body']) $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); } - + $category = ''; $catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : ''); - + if ($catsenabled){ $itm = fetch_post_tags($itm); @@ -72,7 +66,7 @@ class Editpost extends \Zotlabs\Web\Controller { $category .= $cat['term']; } } - + if($itm[0]['attach']) { $j = json_decode($itm[0]['attach'],true); if($j) { @@ -106,16 +100,14 @@ class Editpost extends \Zotlabs\Web\Controller { ); $editor = status_editor($a, $x); - + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit post'), '$editor' => $editor )); - + return $o; - + } - - - + } -- cgit v1.2.3 From c96b20c55969f96ba191d40908cf005b7f6a58da Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 30 Apr 2016 21:56:52 +0200 Subject: make mod editlayout use status_editor() --- Zotlabs/Module/Editlayout.php | 161 ++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 107 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index cec55f5cc..de3117e57 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -3,45 +3,45 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); - +require_once('include/conversation.php'); class Editlayout extends \Zotlabs\Web\Controller { function init() { - + if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { \App::$is_sys = true; } } - + if(argc() > 1) $which = argv(1); else return; - + profile_load($a,$which); - + } - - function get() { - + + function get() { + if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); \App::$error = 404; return; } - + $which = argv(1); - + $uid = local_channel(); $owner = 0; $channel = null; $observer = \App::get_observer(); - + $channel = \App::get_channel(); - + if(\App::$is_sys && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { @@ -50,7 +50,7 @@ class Editlayout extends \Zotlabs\Web\Controller { $observer = $sys; } } - + if(! $owner) { // Figure out who the page owner is. $r = q("select channel_id from channel where channel_address = '%s'", @@ -60,136 +60,83 @@ class Editlayout extends \Zotlabs\Web\Controller { $owner = intval($r[0]['channel_id']); } } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { notice( t('Permission denied.') . EOL); return; } - + $is_owner = (($uid && $uid == $owner) ? true : false); - + $o = ''; - + // Figure out which post we're editing $post_id = ((argc() > 2) ? intval(argv(2)) : 0); - - + if(! $post_id) { notice( t('Item not found') . EOL); return; } - + // Now we've got a post and an owner, let's find out if we're allowed to edit it - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + $perms = get_all_perms($owner,$ob_hash); - + if(! $perms['write_pages']) { notice( t('Permission denied.') . EOL); return; } - - + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", intval($post_id), intval($owner) ); - + $item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1", intval($itm[0]['id']) ); if($item_id) $layout_title = $item_id[0]['sid']; - - $plaintext = true; - - \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( - '$baseurl' => z_root(), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$pretext' => '', - '$ispublic' => ' ', // t('Visible to everybody'), - '$geotag' => $geotag, - '$nickname' => $channel['channel_address'], - '$confirmdelete' => t('Delete layout?'), - '$bbco_autocomplete'=> 'comanche' - )); - - - $tpl = get_markup_template("jot.tpl"); - - $jotplugins = ''; - $jotnets = ''; - - call_hooks('jot_tool', $jotplugins); - call_hooks('jot_networks', $jotnets); - - - // FIXME A return path with $_SESSION doesn't always work for observer - it may WSoD - // instead of loading a sensible page. So, send folk to the webpage list. - + $rp = 'layouts/' . $which; - - $editor = replace_macros($tpl,array( - '$return_path' => $rp, - '$action' => 'item', - '$webpage' => ITEM_TYPE_PDL, - '$share' => t('Edit'), - '$bold' => t('Bold'), - '$italic' => t('Italic'), - '$underline' => t('Underline'), - '$quote' => t('Quote'), - '$code' => t('Code'), - '$upload' => t('Upload photo'), - '$attach' => t('Attach file'), - '$weblink' => t('Insert web link'), - '$youtube' => t('Insert YouTube video'), - '$video' => t('Insert Vorbis [.ogg] video'), - '$audio' => t('Insert Vorbis [.ogg] audio'), - '$setloc' => t('Set your location'), - '$noloc' => t('Clear browser location'), - '$wait' => t('Please wait'), - '$permset' => t('Permission settings'), - '$ptyp' => $itm[0]['type'], - '$content' => undo_post_tagging($itm[0]['body']), - '$post_id' => $post_id, - '$baseurl' => z_root(), - '$defloc' => $channel['channel_location'], - '$visitor' => false, - '$public' => t('Public post'), - '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), - '$placeholdertitle' => t('Layout Description (Optional)'), - '$pagetitle' => $layout_title, - '$placeholdpagetitle' => t('Layout Name'), - '$category' => '', - '$placeholdercategory' => t('Categories (optional, comma-separated list)'), - '$emtitle' => t('Example: bob@example.com, mary@example.com'), - '$lockstate' => $lockstate, - '$acl' => '', - '$bang' => '', - '$profile_uid' => (intval($owner)), - '$jotplugins' => $jotplugins, - '$sourceapp' => t(\App::$sourcename), - '$defexpire' => '', - '$feature_expire' => false, - '$expires' => t('Set expiration date'), - )); - - + + $x = array( + 'webpage' => ITEM_TYPE_PDL, + 'nickname' => $channel['channel_address'], + 'editor_autocomplete'=> true, + 'bbco_autocomplete'=> 'comanche', + 'return_path' => $rp, + 'button' => t('Edit'), + 'hide_voting' => true, + 'hide_future' => true, + 'hide_location' => true, + 'hide_preview' => true, + 'ptyp' => $itm[0]['obj_type'], + 'body' => undo_post_tagging($itm[0]['body']), + 'post_id' => $post_id, + 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + 'pagetitle' => $layout_title, + 'showacl' => false, + 'profile_uid' => intval($owner), + 'catsenabled' => $catsenabled, + 'hide_expire' => true, + ); + + $editor = status_editor($a, $x); + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Layout'), '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), '$id' => $itm[0]['id'], '$editor' => $editor )); - + return $o; - + } - - - + } -- cgit v1.2.3 From d43c7603bff9553283b111934b36412bd8721b0e Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 30 Apr 2016 22:21:00 +0200 Subject: more work on layout editors --- Zotlabs/Module/Editlayout.php | 6 +++--- Zotlabs/Module/Layouts.php | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index de3117e57..2d20de52d 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -113,17 +113,17 @@ class Editlayout extends \Zotlabs\Web\Controller { 'button' => t('Edit'), 'hide_voting' => true, 'hide_future' => true, - 'hide_location' => true, + 'hide_expire' => true, 'hide_preview' => true, 'ptyp' => $itm[0]['obj_type'], 'body' => undo_post_tagging($itm[0]['body']), 'post_id' => $post_id, 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), 'pagetitle' => $layout_title, + 'ptlabel' => t('Layout Name'), + 'placeholdertitle' => t('Layout Description (Optional)'), 'showacl' => false, 'profile_uid' => intval($owner), - 'catsenabled' => $catsenabled, - 'hide_expire' => true, ); $editor = status_editor($a, $x); diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php index 50cb401bc..ce84b6bf1 100644 --- a/Zotlabs/Module/Layouts.php +++ b/Zotlabs/Module/Layouts.php @@ -118,10 +118,12 @@ class Layouts extends \Zotlabs\Web\Controller { 'webpage' => ITEM_TYPE_PDL, 'is_owner' => true, 'nickname' => \App::$profile['channel_address'], - 'bang' => '', 'showacl' => false, 'visitor' => false, - 'nopreview' => 1, + 'hide_voting' => true, + 'hide_future' => true, + 'hide_expire' => true, + 'hide_preview'=> true, 'ptlabel' => t('Layout Name'), 'profile_uid' => intval($owner), 'expanded' => true, -- cgit v1.2.3 From 026787fc73cb76975b55425cdec9b6701a097935 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 30 Apr 2016 22:26:45 +0200 Subject: whitespace --- Zotlabs/Module/Layouts.php | 71 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 36 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php index ce84b6bf1..aafe4342e 100644 --- a/Zotlabs/Module/Layouts.php +++ b/Zotlabs/Module/Layouts.php @@ -5,47 +5,45 @@ require_once('include/identity.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); - class Layouts extends \Zotlabs\Web\Controller { function init() { - + if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { \App::$is_sys = true; } } - + if(argc() > 1) $which = argv(1); else return; - + profile_load($a,$which); - + } - - - function get() { - + + function get() { + if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); \App::$error = 404; return; } - + $which = argv(1); - + $_SESSION['return_url'] = \App::$query_string; - + $uid = local_channel(); $owner = 0; $channel = null; $observer = \App::get_observer(); - + $channel = \App::get_channel(); - + if(\App::$is_sys && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { @@ -54,7 +52,7 @@ class Layouts extends \Zotlabs\Web\Controller { $observer = $sys; } } - + if(! $owner) { // Figure out who the page owner is. $r = q("select channel_id from channel where channel_address = '%s'", @@ -64,34 +62,34 @@ class Layouts extends \Zotlabs\Web\Controller { $owner = intval($r[0]['channel_id']); } } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + $perms = get_all_perms($owner,$ob_hash); - + if(! $perms['write_pages']) { notice( t('Permission denied.') . EOL); return; } - + // Block design features from visitors - + if((! $uid) || ($uid != $owner)) { notice( t('Permission denied.') . EOL); return; } - + // Get the observer, check their permissions - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + $perms = get_all_perms($owner,$ob_hash); - + if(! $perms['write_pages']) { notice( t('Permission denied.') . EOL); return; } - + //This feature is not exposed in redbasic ui since it is not clear why one would want to //download a json encoded pdl file - we dont have a possibility to import it. //Use the buildin share/install feature instead. @@ -109,11 +107,11 @@ class Layouts extends \Zotlabs\Web\Controller { killme(); } } - + // Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages // Nickname is set to the observers xchan, and profile_uid to the owners. // This lets you post pages at other people's channels. - + $x = array( 'webpage' => ITEM_TYPE_PDL, 'is_owner' => true, @@ -131,24 +129,24 @@ class Layouts extends \Zotlabs\Web\Controller { 'novoting' => true, 'bbco_autocomplete' => 'comanche' ); - + if($_REQUEST['title']) $x['title'] = $_REQUEST['title']; if($_REQUEST['body']) $x['body'] = $_REQUEST['body']; if($_REQUEST['pagetitle']) $x['pagetitle'] = $_REQUEST['pagetitle']; - + $editor = status_editor($a,$x); - + $r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc", intval($owner), intval(ITEM_TYPE_PDL) ); - + $pages = null; - + if($r) { $pages = array(); foreach($r as $rr) { @@ -173,10 +171,10 @@ class Layouts extends \Zotlabs\Web\Controller { ); } } - + //Build the base URL for edit links $url = z_root() . '/editlayout/' . $which; - + $o .= replace_macros(get_markup_template('layoutlist.tpl'), array( '$title' => t('Layouts'), '$create' => t('Create'), @@ -194,8 +192,9 @@ class Layouts extends \Zotlabs\Web\Controller { '$channel' => $which, '$view' => t('View'), )); - + return $o; + } - + } -- cgit v1.2.3 From fa80a5c113582dc757de33199df610e0ef8503aa Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sun, 1 May 2016 15:45:42 +0200 Subject: make weblink and attach button hideable and some minor fixes --- Zotlabs/Module/Editlayout.php | 3 +++ Zotlabs/Module/Layouts.php | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index 2d20de52d..c5b50235a 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -114,6 +114,9 @@ class Editlayout extends \Zotlabs\Web\Controller { 'hide_voting' => true, 'hide_future' => true, 'hide_expire' => true, + 'hide_location' => true, + 'hide_weblink' => true, + 'hide_attach' => true, 'hide_preview' => true, 'ptyp' => $itm[0]['obj_type'], 'body' => undo_post_tagging($itm[0]['body']), diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php index aafe4342e..8a7207fc2 100644 --- a/Zotlabs/Module/Layouts.php +++ b/Zotlabs/Module/Layouts.php @@ -117,11 +117,13 @@ class Layouts extends \Zotlabs\Web\Controller { 'is_owner' => true, 'nickname' => \App::$profile['channel_address'], 'showacl' => false, - 'visitor' => false, 'hide_voting' => true, 'hide_future' => true, 'hide_expire' => true, - 'hide_preview'=> true, + 'hide_location' => true, + 'hide_weblink' => true, + 'hide_attach' => true, + 'hide_preview' => true, 'ptlabel' => t('Layout Name'), 'profile_uid' => intval($owner), 'expanded' => true, -- cgit v1.2.3 From 95b96692130e0a949375e133c1aa879efd0cfb2e Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 1 May 2016 21:20:49 -0400 Subject: Create form on admin/plugins page to add plugin git repo using PHPGit --- Zotlabs/Module/Admin.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 1d37b41bc..bad717567 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1326,7 +1326,16 @@ class Admin extends \Zotlabs\Web\Controller { } } } - + + $admin_plugins_add_repo_form= replace_macros( + get_markup_template('admin_plugins_addrepo.tpl'), array( + '$post' => 'admin/plugins', + '$desc' => t('Enter the public git repository URL of the plugin repo.'), + '$repoURL' => array('repoURL', t('Plugin repo git URL'), '', ''), + '$submit' => t('Download Plugin Repo') + ) + ); + $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( '$title' => t('Administration'), @@ -1337,6 +1346,9 @@ class Admin extends \Zotlabs\Web\Controller { '$plugins' => $plugins, '$disabled' => t('Disabled - version incompatibility'), '$form_security_token' => get_form_security_token('admin_plugins'), + '$addclone' => t('Add Plugin Repo'), + '$expandform' => false, + '$form' => $admin_plugins_add_repo_form )); } -- cgit v1.2.3 From b1ae4d776c7c093c7f3ff6905e1a5302fbd5e3f6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 1 May 2016 21:25:15 -0400 Subject: fixed tpl --- Zotlabs/Module/Admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index bad717567..1f228a991 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1346,7 +1346,7 @@ class Admin extends \Zotlabs\Web\Controller { '$plugins' => $plugins, '$disabled' => t('Disabled - version incompatibility'), '$form_security_token' => get_form_security_token('admin_plugins'), - '$addclone' => t('Add Plugin Repo'), + '$addrepo' => t('Add Plugin Repo'), '$expandform' => false, '$form' => $admin_plugins_add_repo_form )); -- cgit v1.2.3 From cd518625bf561f1ed42db0b78030b74c32435136 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 1 May 2016 19:19:17 -0700 Subject: some much needed work on oembed security --- Zotlabs/Module/Admin.php | 29 +++++++++++++++++++---------- Zotlabs/Module/Oep.php | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 1d37b41bc..b22931b1a 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -568,25 +568,25 @@ class Admin extends \Zotlabs\Web\Controller { $block_public = ((x($_POST,'block_public')) ? True : False); set_config('system','block_public',$block_public); - $ws = trim_array_elems(explode("\n",$_POST['whitelisted_sites'])); + $ws = $this->trim_array_elems(explode("\n",$_POST['whitelisted_sites'])); set_config('system','whitelisted_sites',$ws); - $bs = trim_array_elems(explode("\n",$_POST['blacklisted_sites'])); + $bs = $this->trim_array_elems(explode("\n",$_POST['blacklisted_sites'])); set_config('system','blacklisted_sites',$bs); - $wc = trim_array_elems(explode("\n",$_POST['whitelisted_channels'])); + $wc = $this->trim_array_elems(explode("\n",$_POST['whitelisted_channels'])); set_config('system','whitelisted_channels',$wc); - $bc = trim_array_elems(explode("\n",$_POST['blacklisted_channels'])); + $bc = $this->trim_array_elems(explode("\n",$_POST['blacklisted_channels'])); set_config('system','blacklisted_channels',$bc); $embed_coop = ((x($_POST,'embed_coop')) ? True : False); set_config('system','embed_coop',$embed_coop); - $we = trim_array_elems(explode("\n",$_POST['embed_allow'])); + $we = $this->trim_array_elems(explode("\n",$_POST['embed_allow'])); set_config('system','embed_allow',$we); - $be = trim_array_elems(explode("\n",$_POST['embed_deny'])); + $be = $this->trim_array_elems(explode("\n",$_POST['embed_deny'])); set_config('system','embed_deny',$be); goaway(z_root() . '/admin/security'); @@ -708,9 +708,13 @@ class Admin extends \Zotlabs\Web\Controller { $embed_coop = intval(get_config('system','embed_coop')); - // wait to implement this until we have a co-op in place. - // if((! $whiteembeds) && (! $blackembeds) && (! $embed_coop)) - // $whiteembeds_str = "youtube.com\nyoutu.be\ntwitter.com\nvimeo.com\nsoundcloud.com\nwikipedia.com"; + if((! $whiteembeds) && (! $blackembeds)) { + $embedhelp1 = t("By default, unfiltered HTML is allowed in embedded media. This is inherently insecure."); + } + + $embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:"); + $embedhelp3 = t("youtube.com
    youtu.be
    twitter.com
    vimeo.com
    soundcloud.com
    wikipedia.com
    "); + $embedhelp4 = t("All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."); $t = get_markup_template('admin_security.tpl'); return replace_macros($t, array( @@ -722,10 +726,15 @@ class Admin extends \Zotlabs\Web\Controller { '$blacklisted_sites' => array('blacklisted_sites', t('Block communications from these sites'), $blacksites_str, ''), '$whitelisted_channels' => array('whitelisted_channels', t('Allow communications only from these channels'), $whitechannels_str, t('One channel (hash) per line. Leave empty to allow from any channel by default')), '$blacklisted_channels' => array('blacklisted_channels', t('Block communications from these channels'), $blackchannels_str, ''), - '$embed_allow' => array('embed_allow', t('Allow embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), + '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), // '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), + '$embedhelp1' => $embedhelp1, + '$embedhelp2' => $embedhelp2, + '$embedhelp3' => $embedhelp3, + '$embedhelp4' => $embedhelp4, + '$submit' => t('Submit') )); } diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index f36a452e8..638ea7e2d 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -220,7 +220,7 @@ class Oep extends \Zotlabs\Web\Controller { $ret['width'] = intval($width); $ret['height'] = intval($height); - $ret['html'] = get_zcard($c,get_observer_hash(),array('width' => $width, 'height' => $height)); + $ret['html'] = get_zcard_embed($c,get_observer_hash(),array('width' => $width, 'height' => $height)); return $ret; -- cgit v1.2.3 From f284558007583c7b882071fa995f994661bb97cc Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 1 May 2016 19:29:30 -0700 Subject: use only the std_version --- Zotlabs/Module/Admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index b22931b1a..5eaede6a6 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -221,7 +221,7 @@ class Admin extends \Zotlabs\Web\Controller { '$pending' => array( t('Pending registrations'), $pending), '$channels' => array( t('Registered channels'), $channels), '$plugins' => array( t('Active plugins'), $plugins ), - '$version' => array( t('Version'), RED_VERSION), + '$version' => array( t('Version'), STD_VERSION), '$build' => get_config('system', 'db_version') )); } -- cgit v1.2.3 From c2d15e6c3bd8a29bae89d184a999ddac15fcb807 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 1 May 2016 22:29:51 -0400 Subject: New plugin repo is cloned to /store/pluginrepos/REPONAME for analysis --- Zotlabs/Module/Admin.php | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 1f228a991..9bc0482c0 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1,5 +1,8 @@ admin_page_channels_post($a); break; case 'plugins': + if (argc() > 2 && argv(2) === 'addrepo') { + $this->admin_page_plugins_post('addrepo'); + break; + } if (argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")){ @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); @@ -1329,7 +1336,7 @@ class Admin extends \Zotlabs\Web\Controller { $admin_plugins_add_repo_form= replace_macros( get_markup_template('admin_plugins_addrepo.tpl'), array( - '$post' => 'admin/plugins', + '$post' => 'admin/plugins/addrepo', '$desc' => t('Enter the public git repository URL of the plugin repo.'), '$repoURL' => array('repoURL', t('Plugin repo git URL'), '', ''), '$submit' => t('Download Plugin Repo') @@ -1638,6 +1645,55 @@ class Admin extends \Zotlabs\Web\Controller { )); } + function admin_page_plugins_post($action) { + switch($action) { + case 'addrepo': + + if(array_key_exists('repoURL',$_REQUEST)) { + require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies + info('Repo URL submitted: ' . $_REQUEST['repoURL']); + //$git = new Git(); + $repoURL = $_REQUEST['repoURL']; + //logger('hubsites: new git object created: ' . json_encode($git)); + $urlpath = parse_url($repoURL, PHP_URL_PATH); + $lastslash = strrpos($urlpath, '/') + 1; + $gitext = strrpos($urlpath, '.'); + if ($gitext) { + $reponame = substr($urlpath, $lastslash, $gitext - $lastslash); + } else { + logger('invalid git repo URL'); + notice('Invalid git repo URL'); + break; + } + $storepath = realpath(__DIR__ . '/../../store/'); + logger('storepath: ' . $storepath); + $repopath = $storepath . '/pluginrepos/' . $reponame; + + if (!file_exists($repopath)) { + logger('epopath does not exist'); + if (mkdir($repopath, 0770, true)) { + logger('repopath created'); + $git = new Git(); + logger('new git object created'); + $cloned = $git->clone($repoURL, $repopath); + if (!$cloned) { + logger('git clone failed'); + notice('Repo coule not be cloned. Filesystem path error.'); + return null; + } + } else { + logger('repopath could not be created'); + notice('Repo coule not be cloned. Filesystem path error.'); + return null; + } + } + } + break; + default: + break; + } + } + function admin_page_profs_post(&$a) { if(array_key_exists('basic',$_REQUEST)) { -- cgit v1.2.3 From 5e458491f1e0fce5ec9e4855dac13340af627ded Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 1 May 2016 20:43:57 -0700 Subject: sort addons based on the internal display name instead of the filename --- Zotlabs/Module/Admin.php | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 5eaede6a6..6dad11ab8 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1336,6 +1336,8 @@ class Admin extends \Zotlabs\Web\Controller { } } + usort($plugins,'self::plugin_sort'); + $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( '$title' => t('Administration'), @@ -1349,6 +1351,11 @@ class Admin extends \Zotlabs\Web\Controller { )); } + static public function plugin_sort($a,$b) { + return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name']))); + } + + /** * @param array $themes * @param string $th -- cgit v1.2.3 From a10fe5f13e67faa33a72caa33c49c36113213ffe Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 1 May 2016 22:45:38 -0700 Subject: a couple of bugfixes from earlier checkins and implementation of source tags --- Zotlabs/Module/Sources.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Sources.php b/Zotlabs/Module/Sources.php index cca9e5ebf..ef32991ee 100644 --- a/Zotlabs/Module/Sources.php +++ b/Zotlabs/Module/Sources.php @@ -7,7 +7,7 @@ class Sources extends \Zotlabs\Web\Controller { function post() { if(! local_channel()) return; - + if(! feature_enabled(local_channel(),'channel_sources')) return ''; @@ -17,6 +17,7 @@ class Sources extends \Zotlabs\Web\Controller { $words = $_REQUEST['words']; $frequency = $_REQUEST['frequency']; $name = $_REQUEST['name']; + $tags = $_REQUEST['tags']; $channel = \App::get_channel(); @@ -36,14 +37,15 @@ class Sources extends \Zotlabs\Web\Controller { notice ( t('Failed to create source. No channel selected.') . EOL); return; } - + if(! $source) { - $r = q("insert into source ( src_channel_id, src_channel_xchan, src_xchan, src_patt ) - values ( %d, '%s', '%s', '%s' ) ", + $r = q("insert into source ( src_channel_id, src_channel_xchan, src_xchan, src_patt, src_tag ) + values ( %d, '%s', '%s', '%s', '%s' ) ", intval(local_channel()), dbesc($channel['channel_hash']), dbesc($xchan), - dbesc($words) + dbesc($words), + dbesc($tags) ); if($r) { info( t('Source created.') . EOL); @@ -51,9 +53,10 @@ class Sources extends \Zotlabs\Web\Controller { goaway(z_root() . '/sources'); } else { - $r = q("update source set src_xchan = '%s', src_patt = '%s' where src_channel_id = %d and src_id = %d", + $r = q("update source set src_xchan = '%s', src_patt = '%s', src_tag = '%s' where src_channel_id = %d and src_id = %d", dbesc($xchan), dbesc($words), + dbesc($tags), intval(local_channel()), intval($source) ); @@ -62,6 +65,7 @@ class Sources extends \Zotlabs\Web\Controller { } } + } @@ -105,6 +109,8 @@ class Sources extends \Zotlabs\Web\Controller { '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), '$words' => array( 'words', t('Only import content with these words (one per line)'),'',t('Leave blank to import all public content')), '$name' => array( 'name', t('Channel Name'), '', ''), + '$tags' => array('tags', t('Add the following tags to posts imported from this source (comma separated)','','')), + '$submit' => t('Submit') )); return $o; @@ -138,6 +144,7 @@ class Sources extends \Zotlabs\Web\Controller { '$words' => array( 'words', t('Only import content with these words (one per line)'),$r[0]['src_patt'],t('Leave blank to import all public content')), '$xchan' => $r[0]['src_xchan'], '$abook' => $x[0]['abook_id'], + '$tags' => array('tags', t('Add the following tags to posts imported from this source (comma separated)'),$r[0]['src_tag'],''), '$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''), '$submit' => t('Submit') )); -- cgit v1.2.3 From 559ed3f0a8cbe90b6c20cc4ada649bc063f41c25 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 2 May 2016 01:18:18 -0700 Subject: sort out the rest of the source categories --- Zotlabs/Module/Sources.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Sources.php b/Zotlabs/Module/Sources.php index ef32991ee..a180d9b6e 100644 --- a/Zotlabs/Module/Sources.php +++ b/Zotlabs/Module/Sources.php @@ -109,7 +109,7 @@ class Sources extends \Zotlabs\Web\Controller { '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), '$words' => array( 'words', t('Only import content with these words (one per line)'),'',t('Leave blank to import all public content')), '$name' => array( 'name', t('Channel Name'), '', ''), - '$tags' => array('tags', t('Add the following tags to posts imported from this source (comma separated)','','')), + '$tags' => array('tags', t('Add the following categories to posts imported from this source (comma separated)'),'',t('Optional')), '$submit' => t('Submit') )); @@ -144,7 +144,7 @@ class Sources extends \Zotlabs\Web\Controller { '$words' => array( 'words', t('Only import content with these words (one per line)'),$r[0]['src_patt'],t('Leave blank to import all public content')), '$xchan' => $r[0]['src_xchan'], '$abook' => $x[0]['abook_id'], - '$tags' => array('tags', t('Add the following tags to posts imported from this source (comma separated)'),$r[0]['src_tag'],''), + '$tags' => array('tags', t('Add the following categories to posts imported from this source (comma separated)'),$r[0]['src_tag'],t('Optional')), '$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''), '$submit' => t('Submit') )); -- cgit v1.2.3 From b371c028ad31180b4c73f92b45c4ca8f5fff259e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 2 May 2016 22:28:27 -0700 Subject: more security stuff --- Zotlabs/Module/Admin.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 6dad11ab8..e1eaa6e0e 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -580,8 +580,8 @@ class Admin extends \Zotlabs\Web\Controller { $bc = $this->trim_array_elems(explode("\n",$_POST['blacklisted_channels'])); set_config('system','blacklisted_channels',$bc); - $embed_coop = ((x($_POST,'embed_coop')) ? True : False); - set_config('system','embed_coop',$embed_coop); + $embed_sslonly = ((x($_POST,'embed_sslonly')) ? True : False); + set_config('system','embed_sslonly',$embed_sslonly); $we = $this->trim_array_elems(explode("\n",$_POST['embed_allow'])); set_config('system','embed_allow',$we); @@ -589,6 +589,12 @@ class Admin extends \Zotlabs\Web\Controller { $be = $this->trim_array_elems(explode("\n",$_POST['embed_deny'])); set_config('system','embed_deny',$be); + $ts = ((x($_POST,'transport_security')) ? True : False); + set_config('system','transport_security_header',$ts); + + $cs = ((x($_POST,'content_security')) ? True : False); + set_config('system','content_security_policy',$cs); + goaway(z_root() . '/admin/security'); } @@ -713,7 +719,7 @@ class Admin extends \Zotlabs\Web\Controller { } $embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:"); - $embedhelp3 = t("youtube.com
    youtu.be
    twitter.com
    vimeo.com
    soundcloud.com
    wikipedia.com
    "); + $embedhelp3 = t("https://youtube.com/
    https://www.youtube.com/
    https://youtu.be/
    https://vimeo.com/
    https://soundcloud.com/
    "); $embedhelp4 = t("All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."); $t = get_markup_template('admin_security.tpl'); @@ -722,18 +728,17 @@ class Admin extends \Zotlabs\Web\Controller { '$page' => t('Security'), '$form_security_token' => get_form_security_token('admin_security'), '$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated.")), + '$transport_security' => array('transport_security', t('Set "Transport Security" HTTP header'),intval(get_config('system','transport_security_header')),''), + '$content_security' => array('content_security', t('Set "Content Security Policy" HTTP header'),intval(get_config('system','content_security_policy')),''), '$whitelisted_sites' => array('whitelisted_sites', t('Allow communications only from these sites'), $whitesites_str, t('One site per line. Leave empty to allow communication from anywhere by default')), '$blacklisted_sites' => array('blacklisted_sites', t('Block communications from these sites'), $blacksites_str, ''), '$whitelisted_channels' => array('whitelisted_channels', t('Allow communications only from these channels'), $whitechannels_str, t('One channel (hash) per line. Leave empty to allow from any channel by default')), '$blacklisted_channels' => array('blacklisted_channels', t('Block communications from these channels'), $blackchannels_str, ''), - '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), + '$embed_sslonly' => array('embed_sslonly',t('Only allow embeds from secure (SSL) websites and links.'), intval(get_config('system','embed_sslonly')),''), + '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. By default embedded content is filtered.')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), // '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), - '$embedhelp1' => $embedhelp1, - '$embedhelp2' => $embedhelp2, - '$embedhelp3' => $embedhelp3, - '$embedhelp4' => $embedhelp4, '$submit' => t('Submit') )); -- cgit v1.2.3 From 9619d02be988a5af7746fa5524b17e645f99d40d Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 3 May 2016 06:30:46 -0400 Subject: AJAX and spinner for add repo form submission. Repo info will be displayed below the form. --- Zotlabs/Module/Admin.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 9bc0482c0..ae0a0ad85 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1651,10 +1651,8 @@ class Admin extends \Zotlabs\Web\Controller { if(array_key_exists('repoURL',$_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies - info('Repo URL submitted: ' . $_REQUEST['repoURL']); - //$git = new Git(); + logger('Repo URL submitted: ' . $_REQUEST['repoURL']); $repoURL = $_REQUEST['repoURL']; - //logger('hubsites: new git object created: ' . json_encode($git)); $urlpath = parse_url($repoURL, PHP_URL_PATH); $lastslash = strrpos($urlpath, '/') + 1; $gitext = strrpos($urlpath, '.'); @@ -1666,27 +1664,32 @@ class Admin extends \Zotlabs\Web\Controller { break; } $storepath = realpath(__DIR__ . '/../../store/'); - logger('storepath: ' . $storepath); + //logger('storepath: ' . $storepath); $repopath = $storepath . '/pluginrepos/' . $reponame; if (!file_exists($repopath)) { - logger('epopath does not exist'); + //logger('repopath does not exist'); if (mkdir($repopath, 0770, true)) { - logger('repopath created'); + //logger('repopath created'); $git = new Git(); - logger('new git object created'); + //logger('new git object created'); $cloned = $git->clone($repoURL, $repopath); if (!$cloned) { logger('git clone failed'); notice('Repo coule not be cloned. Filesystem path error.'); - return null; + json_return_and_die(array('message' => 'Repo coule not be cloned. Filesystem path error.', 'success' => false)); } + json_return_and_die(array('message' => 'Successfully cloned to: ' . $repopath , 'success' => true)); } else { logger('repopath could not be created'); notice('Repo coule not be cloned. Filesystem path error.'); - return null; + json_return_and_die(array('message' => 'Repo coule not be cloned. Filesystem path error', 'success' => false)); } - } + } else { + json_return_and_die(array('message' => 'Repo already exists at: ' . $repopath, 'success' => true)); + } + } else { + json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); } break; default: -- cgit v1.2.3 From 5686ee13b4540bfc0ce6c40f07b6e43c3c55e9a8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 3 May 2016 21:49:52 -0400 Subject: Increased PHPGit timeout to 120 seconds for large repos. Retrieve Readme.md and render on plugins page. --- Zotlabs/Module/Admin.php | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index d23b508f0..ddec02916 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1671,6 +1671,7 @@ class Admin extends \Zotlabs\Web\Controller { switch($action) { case 'addrepo': + require_once('library/markdown.php'); if(array_key_exists('repoURL',$_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies logger('Repo URL submitted: ' . $_REQUEST['repoURL']); @@ -1688,28 +1689,39 @@ class Admin extends \Zotlabs\Web\Controller { $storepath = realpath(__DIR__ . '/../../store/'); //logger('storepath: ' . $storepath); $repopath = $storepath . '/pluginrepos/' . $reponame; - + $git = new Git(); if (!file_exists($repopath)) { //logger('repopath does not exist'); if (mkdir($repopath, 0770, true)) { - //logger('repopath created'); - $git = new Git(); - //logger('new git object created'); $cloned = $git->clone($repoURL, $repopath); if (!$cloned) { logger('git clone failed'); notice('Repo coule not be cloned. Filesystem path error.'); - json_return_and_die(array('message' => 'Repo coule not be cloned. Filesystem path error.', 'success' => false)); + json_return_and_die(array('message' => 'Repo could not be cloned. Filesystem path error.', 'success' => false)); } - json_return_and_die(array('message' => 'Successfully cloned to: ' . $repopath , 'success' => true)); + //json_return_and_die(array('repo'=> $repo, 'message' => 'Successfully cloned to: ' . $repopath , 'success' => true)); } else { logger('repopath could not be created'); notice('Repo coule not be cloned. Filesystem path error.'); - json_return_and_die(array('message' => 'Repo coule not be cloned. Filesystem path error', 'success' => false)); + json_return_and_die(array('message' => 'Repo could not be cloned. Filesystem path error', 'success' => false)); + } + } + $git->setRepository($repopath); + $repo = array(); + $repo['url'] = $repoURL; + $repo['branches'] = $git->branch(['all' => true]); + $repo['objects'] = array(); + $repo['readme'] = $repo['manifest'] = null; + foreach ($git->tree('master') as $object) { + if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { + $repo['readme'] = Markdown($git->cat->blob($object['hash'])); + } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { + $repo['manifest'] = $git->cat->blob($object['hash']); } - } else { - json_return_and_die(array('message' => 'Repo already exists at: ' . $repopath, 'success' => true)); } + //logger('repo: ' . json_encode($repo)); + json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); + } else { json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); } -- cgit v1.2.3 From 191298ec93968c8c5804c021d320c536dac32c12 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 3 May 2016 20:37:05 -0700 Subject: more background work for app management - give every member a copy of all the system apps so that they can edit and delete them to taste/preference. This needs further work to pick up changes in system apps (additions, edits, deletions, etc.). Currently this is done once and never attempted again. --- Zotlabs/Module/Apps.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index 4066966ca..ea6ab1913 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -17,16 +17,21 @@ class Apps extends \Zotlabs\Web\Controller { $apps = array(); - $syslist = get_system_apps(); if(local_channel()) { + import_system_apps(); + $syslist = array(); $list = app_list(local_channel()); if($list) { foreach($list as $x) { $syslist[] = app_encode($x); } } + translate_system_apps($syslist); } + else + $syslist = get_system_apps(true); + usort($syslist,'app_name_compare'); // logger('apps: ' . print_r($syslist,true)); -- cgit v1.2.3 From 1685548a4cff333b2f923960f33a7f87394afcc5 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 3 May 2016 21:59:26 -0700 Subject: ensure that important system fields are passed through the appman editor --- Zotlabs/Module/Appman.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index 96e4cdd87..b0dd887f4 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -23,6 +23,8 @@ class Appman extends \Zotlabs\Web\Controller { 'photo' => escape_tags($_REQUEST['photo']), 'version' => escape_tags($_REQUEST['version']), 'price' => escape_tags($_REQUEST['price']), + 'requires' => escape_tags($_REQUEST['requires']), + 'system' => intval($_REQUEST['system']), 'sig' => escape_tags($_REQUEST['sig']) ); @@ -64,7 +66,7 @@ class Appman extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -99,6 +101,8 @@ class Appman extends \Zotlabs\Web\Controller { '$version' => array('version', t('Version ID'),(($app) ? $app['app_version'] : ''), ''), '$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''), '$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''), + '$system' => (($app) ? intval($app['app_system']) : 0), + '$requires' => (($app) ? $app['app_requires'] : ''), '$embed' => $embed, '$submit' => t('Submit') )); -- cgit v1.2.3 From 0db8d3f6c6dcf72aa90a9cbf45708882c90e0402 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 4 May 2016 11:49:29 +0200 Subject: whitespace --- Zotlabs/Module/Editblock.php | 74 ++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 40 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 2821b3fe0..b13ab22f3 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -4,46 +4,43 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); - class Editblock extends \Zotlabs\Web\Controller { function init() { - + if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { \App::$is_sys = true; } } - + if(argc() > 1) $which = argv(1); else return; - + profile_load($a,$which); - + } - - - - function get() { - + + function get() { + if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); \App::$error = 404; return; } - + $which = argv(1); - + $uid = local_channel(); $owner = 0; $channel = null; $observer = \App::get_observer(); - + $channel = \App::get_channel(); - + if(\App::$is_sys && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { @@ -52,7 +49,7 @@ class Editblock extends \Zotlabs\Web\Controller { $observer = $sys; } } - + if(! $owner) { // Figure out who the page owner is. $r = q("select channel_id from channel where channel_address = '%s'", @@ -62,27 +59,26 @@ class Editblock extends \Zotlabs\Web\Controller { $owner = intval($r[0]['channel_id']); } } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { notice( t('Permission denied.') . EOL); return; } - + $is_owner = (($uid && $uid == $owner) ? true : false); - + $o = ''; - + // Figure out which post we're editing $post_id = ((argc() > 2) ? intval(argv(2)) : 0); - - + if(! ($post_id && $owner)) { notice( t('Item not found') . EOL); return; } - + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", intval($post_id), intval($owner) @@ -98,20 +94,20 @@ class Editblock extends \Zotlabs\Web\Controller { notice( t('Item not found') . EOL); return; } - + $plaintext = true; - + $mimeselect = ''; $mimetype = $itm[0]['mimetype']; - + if($mimetype != 'text/bbcode') $plaintext = true; - + if(get_config('system','page_mimetype')) $mimeselect = ''; else $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); - + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => z_root(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), @@ -122,17 +118,17 @@ class Editblock extends \Zotlabs\Web\Controller { '$confirmdelete' => t('Delete block?'), '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : 'comanche-block') )); - + $tpl = get_markup_template("jot.tpl"); - + $jotplugins = ''; $jotnets = ''; - + call_hooks('jot_tool', $jotplugins); call_hooks('jot_networks', $jotnets); - + $rp = 'blocks/' . $channel['channel_address']; - + $editor = replace_macros($tpl,array( '$return_path' => $rp, '$action' => 'item', @@ -174,18 +170,16 @@ class Editblock extends \Zotlabs\Web\Controller { '$defexpire' => '', '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) )); - + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Block'), '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), '$id' => $itm[0]['id'], '$editor' => $editor )); - + return $o; - + } - - - -} + +} \ No newline at end of file -- cgit v1.2.3 From 9fe33bb67df2f9cea25e3815ddfe503dfabb3fd6 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 4 May 2016 11:53:38 +0200 Subject: whitespace --- Zotlabs/Module/Editblock.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index b13ab22f3..0204d0994 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -24,7 +24,7 @@ class Editblock extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); @@ -104,7 +104,7 @@ class Editblock extends \Zotlabs\Web\Controller { $plaintext = true; if(get_config('system','page_mimetype')) - $mimeselect = ''; + $mimeselect = ''; else $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); @@ -182,4 +182,4 @@ class Editblock extends \Zotlabs\Web\Controller { } -} \ No newline at end of file +} -- cgit v1.2.3 From 33a8d845c12a9a6394a5fb8fa8edd851126e19e2 Mon Sep 17 00:00:00 2001 From: Treer Date: Wed, 4 May 2016 23:55:32 +1000 Subject: Refine permissions dialog UI --- Zotlabs/Module/Channel.php | 10 +++++++++- Zotlabs/Module/Network.php | 12 ++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 36f13e775..ee7140475 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -126,13 +126,21 @@ function get($update = 0, $load = false) { if($perms['post_wall']) { + // I'm trying to make two points in this description text - warn about finality of wall + // post permissions, and try to clear up confusion that these permissions set who is + // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking + // the "Show" button on a group does not post it to the feed of people in that group, it + // mearly allows those people to view the post if they are viewing/following this channel. + $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); + $aclContextHelpCmd = ''; + $x = array( 'is_owner' => $is_owner, 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), 'nickname' => \App::$profile['channel_address'], 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')) : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd) : ''), 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 77353da05..a6b36ad3c 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -154,6 +154,14 @@ class Network extends \Zotlabs\Web\Controller { } nav_set_selected('network'); + + // I'm trying to make two points in this description text - warn about finality of wall + // post permissions, and try to clear up confusion that these permissions set who is + // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking + // the "Show" button on a group does not post it to the feed of people in that group, it + // mearly allows those people to view the post if they are viewing/following this channel. + $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); + $aclContextHelpCmd = ''; $channel_acl = array( 'allow_cid' => $channel['channel_allow_cid'], @@ -161,7 +169,7 @@ class Network extends \Zotlabs\Web\Controller { 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid'] ); - + $private_editing = ((($group || $cid) && (! intval($_GET['pf']))) ? true : false); $x = array( @@ -170,7 +178,7 @@ class Network extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd), 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel(), -- cgit v1.2.3 From e1e56936c971bee54f58664df3aa58796a71ead4 Mon Sep 17 00:00:00 2001 From: Treer Date: Thu, 5 May 2016 02:09:47 +1000 Subject: add help to some permissions dialogs --- Zotlabs/Module/Channel.php | 2 +- Zotlabs/Module/Network.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index ee7140475..d0c6d83d8 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -132,7 +132,7 @@ function get($update = 0, $load = false) { // the "Show" button on a group does not post it to the feed of people in that group, it // mearly allows those people to view the post if they are viewing/following this channel. $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); - $aclContextHelpCmd = ''; + $aclContextHelpCmd = 'acl_dialog_post'; $x = array( 'is_owner' => $is_owner, diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index a6b36ad3c..e4b936dc2 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -161,7 +161,7 @@ class Network extends \Zotlabs\Web\Controller { // the "Show" button on a group does not post it to the feed of people in that group, it // mearly allows those people to view the post if they are viewing/following this channel. $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); - $aclContextHelpCmd = ''; + $aclContextHelpCmd = 'acl_dialog_post'; $channel_acl = array( 'allow_cid' => $channel['channel_allow_cid'], -- cgit v1.2.3 From 50fb525b280069e4a95f9ae133b15460e8b02318 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 4 May 2016 17:35:27 -0700 Subject: add categories to apps (wip) --- Zotlabs/Module/Appman.php | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index b0dd887f4..ba2a64f35 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -1,5 +1,6 @@ - escape_tags($_REQUEST['price']), 'requires' => escape_tags($_REQUEST['requires']), 'system' => intval($_REQUEST['system']), - 'sig' => escape_tags($_REQUEST['sig']) + 'sig' => escape_tags($_REQUEST['sig']), + 'categories' => escape_tags($_REQUEST['categories']) ); $_REQUEST['appid'] = app_install(local_channel(),$arr); @@ -81,8 +83,23 @@ class Appman extends \Zotlabs\Web\Controller { dbesc($_REQUEST['appid']), dbesc(local_channel()) ); - if($r) + if($r) { $app = $r[0]; + + $term = q("select * from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($r[0]['id']) + ); + if($term) { + $app['categories'] = ''; + foreach($term as $t) { + if($app['categories']) + $app['categories'] .= ','; + $app['categories'] .= $t['term']; + } + } + } + $embed = array('embed', t('Embed code'), app_encode($app,true),'', 'onclick="this.select();"'); } @@ -98,6 +115,7 @@ class Appman extends \Zotlabs\Web\Controller { '$url' => array('url', t('Location (URL) of app'),(($app) ? $app['app_url'] : ''), t('Required')), '$desc' => array('desc', t('Description'),(($app) ? $app['app_desc'] : ''), ''), '$photo' => array('photo', t('Photo icon URL'),(($app) ? $app['app_photo'] : ''), t('80 x 80 pixels - optional')), + '$categories' => array('categories',t('Categories (optional, comma separated list)'),(($app) ? $app['categories'] : ''),''), '$version' => array('version', t('Version ID'),(($app) ? $app['app_version'] : ''), ''), '$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''), '$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''), -- cgit v1.2.3 From 566667a263abd6f4b2a8a24579323e65d0016d7c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 4 May 2016 18:27:46 -0700 Subject: provide a tag cloud for app categories and allow filtering apps from this --- Zotlabs/Module/Apps.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index ea6ab1913..33259b319 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -21,7 +21,7 @@ class Apps extends \Zotlabs\Web\Controller { if(local_channel()) { import_system_apps(); $syslist = array(); - $list = app_list(local_channel()); + $list = app_list(local_channel(), false, $_GET['cat']); if($list) { foreach($list as $x) { $syslist[] = app_encode($x); @@ -42,6 +42,7 @@ class Apps extends \Zotlabs\Web\Controller { return replace_macros(get_markup_template('myapps.tpl'), array( '$sitename' => get_config('system','sitename'), + '$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? ' - ' . escape_tags($_GET['cat']) : ''), '$title' => t('Apps'), '$apps' => $apps, )); -- cgit v1.2.3 From 9b19a51fc6cf38c1b465be5c97f92c840f257a40 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 4 May 2016 20:24:47 -0700 Subject: Allow follow to work with a pasted webbie from the profile page (where we've replaced the '@' sign with a UTF-8 look-alike) --- Zotlabs/Module/Follow.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index d3114557b..1701328bf 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -19,7 +19,10 @@ class Follow extends \Zotlabs\Web\Controller { $confirm = intval($_REQUEST['confirm']); $channel = \App::get_channel(); - + + // Warning: Do not edit the following line. The first symbol is UTF-8 @ + $url = str_replace('@','@',$url); + $result = new_contact($uid,$url,$channel,true,$confirm); if($result['success'] == false) { -- cgit v1.2.3 From 2174cdcd0ebda4ba62653791489f003bf085f282 Mon Sep 17 00:00:00 2001 From: Treer Date: Fri, 6 May 2016 01:34:52 +1000 Subject: Unify permissions dialog for network posts, channel posts, and remote posts * changes the warning from being about when a post is "sent" to when it's "shared", to match the Share button. * hyperlinks the "cannot be changed" part of the warning to the help file * adds some more content to the help file --- Zotlabs/Module/Channel.php | 10 +--------- Zotlabs/Module/Network.php | 10 +--------- Zotlabs/Module/Rpost.php | 2 +- 3 files changed, 3 insertions(+), 19 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index d0c6d83d8..47c5f31fb 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -126,21 +126,13 @@ function get($update = 0, $load = false) { if($perms['post_wall']) { - // I'm trying to make two points in this description text - warn about finality of wall - // post permissions, and try to clear up confusion that these permissions set who is - // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking - // the "Show" button on a group does not post it to the feed of people in that group, it - // mearly allows those people to view the post if they are viewing/following this channel. - $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); - $aclContextHelpCmd = 'acl_dialog_post'; - $x = array( 'is_owner' => $is_owner, 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), 'nickname' => \App::$profile['channel_address'], 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd) : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index e4b936dc2..2badd7280 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -155,14 +155,6 @@ class Network extends \Zotlabs\Web\Controller { nav_set_selected('network'); - // I'm trying to make two points in this description text - warn about finality of wall - // post permissions, and try to clear up confusion that these permissions set who is - // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking - // the "Show" button on a group does not post it to the feed of people in that group, it - // mearly allows those people to view the post if they are viewing/following this channel. - $aclDesc = t('Post permissions cannot be changed after a post is sent.
    These permissions set who is allowed to view the post.'); - $aclContextHelpCmd = 'acl_dialog_post'; - $channel_acl = array( 'allow_cid' => $channel['channel_allow_cid'], 'allow_gid' => $channel['channel_allow_gid'], @@ -178,7 +170,7 @@ class Network extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php index 195949e1c..41889c35c 100644 --- a/Zotlabs/Module/Rpost.php +++ b/Zotlabs/Module/Rpost.php @@ -115,7 +115,7 @@ class Rpost extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl,true,(($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')), + 'acl' => populate_acl($channel_acl,true,(($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => '', 'visitor' => true, 'profile_uid' => local_channel(), -- cgit v1.2.3 From 2e3da0cbbbb753c8910e96a907cd031e5d95f7c2 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 5 May 2016 18:15:07 -0700 Subject: - Setup: check php version (5.4 required) - Comanche: implement conditionals. Currently the only supported tests are true/false for system config settings and supports the following forms: [if $config.system.foo] [widget=widget1][/widget] [else] [widget=widget2][/widget] [/if] [if $config.system.foo] [widget=widget1][/widget] [/if] --- Zotlabs/Module/Setup.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index 3ac67e1c0..f8c14951b 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -407,6 +407,11 @@ class Setup extends \Zotlabs\Web\Controller { function check_php(&$phpath, &$checks) { $help = ''; + if(version_compare(PHP_VERSION, '5.4') < 0) { + $help .= t('PHP version 5.4 or greater is required.'); + $this->check_add($checks, t('PHP version'), false, false, $help); + } + if (strlen($phpath)) { $passed = file_exists($phpath); } else { -- cgit v1.2.3 From 7101bbedcb7ca7a04a11ddb4f42be037bd8e54a8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 5 May 2016 23:07:35 -0700 Subject: objectify comanche --- Zotlabs/Module/Page.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index 64b940b0f..8a8bc7a49 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -99,9 +99,9 @@ class Page extends \Zotlabs\Web\Controller { \App::$page['title'] = escape_tags($r[0]['title']); if($r[0]['item_type'] == ITEM_TYPE_PDL) { - require_once('include/comanche.php'); - comanche_parser(get_app(),$r[0]['body']); - \App::$pdl = $r[0]['body']; + \App::$comanche = new \Zotlabs\Render\Comanche(); + \App::$comanche->parse($r[0]['body']); + \App::$pdl = $r[0]['body']; } elseif($r[0]['layout_mid']) { $l = q("select body from item where mid = '%s' and uid = %d limit 1", @@ -110,8 +110,8 @@ class Page extends \Zotlabs\Web\Controller { ); if($l) { - require_once('include/comanche.php'); - comanche_parser(get_app(),$l[0]['body']); + \App::$comanche = new \Zotlabs\Render\Comanche(); + \App::$comanche->parse($l[0]['body']); \App::$pdl = $l[0]['body']; } } -- cgit v1.2.3 From 75128e8f68e829ad9e3670dac82f075d9632dba4 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 7 May 2016 23:05:48 +0200 Subject: make editblock use status_editor() --- Zotlabs/Module/Blocks.php | 8 ++-- Zotlabs/Module/Editblock.php | 100 +++++++++++++------------------------------ Zotlabs/Module/Editpost.php | 1 + 3 files changed, 33 insertions(+), 76 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php index 192a4aded..ed702befb 100644 --- a/Zotlabs/Module/Blocks.php +++ b/Zotlabs/Module/Blocks.php @@ -82,11 +82,7 @@ class Blocks extends \Zotlabs\Web\Controller { } $mimetype = (($_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype')); - - if(! $mimetype) { - $mimetype = 'choose'; - } - + $x = array( 'webpage' => ITEM_TYPE_BLOCK, 'is_owner' => true, @@ -96,6 +92,8 @@ class Blocks extends \Zotlabs\Web\Controller { 'showacl' => false, 'visitor' => true, 'mimetype' => $mimetype, + 'mimeselect' => true, + 'hide_location' => true, 'ptlabel' => t('Block Name'), 'profile_uid' => intval($owner), 'expanded' => true, diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 0204d0994..a79962033 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -3,6 +3,7 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); +require_once('include/conversation.php'); class Editblock extends \Zotlabs\Web\Controller { @@ -95,81 +96,38 @@ class Editblock extends \Zotlabs\Web\Controller { return; } - $plaintext = true; - - $mimeselect = ''; $mimetype = $itm[0]['mimetype']; - if($mimetype != 'text/bbcode') - $plaintext = true; - - if(get_config('system','page_mimetype')) - $mimeselect = ''; - else - $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); - - \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( - '$baseurl' => z_root(), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$pretext' => '', - '$ispublic' => ' ', // t('Visible to everybody'), - '$geotag' => '', - '$nickname' => $channel['channel_address'], - '$confirmdelete' => t('Delete block?'), - '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : 'comanche-block') - )); - - $tpl = get_markup_template("jot.tpl"); - - $jotplugins = ''; - $jotnets = ''; - - call_hooks('jot_tool', $jotplugins); - call_hooks('jot_networks', $jotnets); - $rp = 'blocks/' . $channel['channel_address']; - $editor = replace_macros($tpl,array( - '$return_path' => $rp, - '$action' => 'item', - '$webpage' => ITEM_TYPE_BLOCK, - '$share' => t('Edit'), - '$bold' => t('Bold'), - '$italic' => t('Italic'), - '$underline' => t('Underline'), - '$quote' => t('Quote'), - '$code' => t('Code'), - '$writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), - '$attach' => t('Attach file'), - '$weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), - '$setloc' => false, - '$noloc' => false, - '$permset' => t('Permission settings'), - '$ptyp' => $itm[0]['type'], - '$mimeselect' => $mimeselect, - '$content' => undo_post_tagging($itm[0]['body']), - '$post_id' => $post_id, - '$baseurl' => z_root(), - '$defloc' => $channel['channel_location'], - '$visitor' => true, - '$public' => t('Public post'), - '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), - '$placeholdertitle' => t('Title (optional)'), - '$pagetitle' => $block_title, - '$category' => '', - '$placeholdercategory' => t('Categories (optional, comma-separated list)'), - '$emtitle' => t('Example: bob@example.com, mary@example.com'), - '$lockstate' => $lockstate, - '$acl' => '', - '$bang' => '', - '$profile_uid' => (intval($channel['channel_id'])), - '$preview' => t('Preview'), - '$jotplugins' => $jotplugins, - '$sourceapp' => $itm[0]['app'], - '$defexpire' => '', - '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) - )); + $x = array( + 'nickname' => $channel['channel_address'], + 'bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : 'comanche-block'), + 'return_path' => $rp, + 'webpage' => ITEM_TYPE_BLOCK, + 'ptlabel' => t('Block Name'), + 'button' => t('Edit'), + 'writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), + 'weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), + 'hide_voting' => true, + 'hide_future' => true, + 'hide_location' => true, + 'hide_expire' => true, + 'showacl' => false, + 'ptyp' => $itm[0]['type'], + 'mimeselect' => true, + 'mimetype' => $itm[0]['mimetype'], + 'body' => undo_post_tagging($itm[0]['body']), + 'post_id' => $post_id, + 'visitor' => true, + 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + 'placeholdertitle' => t('Title (optional)'), + 'pagetitle' => $block_title, + 'profile_uid' => (intval($channel['channel_id'])), + 'bbcode' => (($mimetype == 'text/bbcode') ? true : false) + ); + + $editor = status_editor($a, $x); $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Block'), diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 25ba1a39a..43edf2c00 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -85,6 +85,7 @@ class Editpost extends \Zotlabs\Web\Controller { 'hide_voting' => true, 'hide_future' => true, 'hide_location' => true, + 'mimetype' => $itm[0]['mimetype'], 'ptyp' => $itm[0]['obj_type'], 'body' => undo_post_tagging($itm[0]['body']), 'post_id' => $post_id, -- cgit v1.2.3 From 2b77c9a74bf4393dd3894420e602e7212c29ba42 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 7 May 2016 14:23:38 -0700 Subject: SDAV is already absolute --- Zotlabs/Module/Dav.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 42eb3d0c1..9af059974 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -91,10 +91,10 @@ class Dav extends \Zotlabs\Web\Controller { $rootDirectory = new \Zotlabs\Storage\Directory('/', $auth); // A SabreDAV server-object - $server = new \SDAV\Server($rootDirectory); + $server = new SDAV\Server($rootDirectory); // prevent overwriting changes each other with a lock backend - $lockBackend = new \SDAV\Locks\Backend\File('store/[data]/locks'); - $lockPlugin = new \SDAV\Locks\Plugin($lockBackend); + $lockBackend = new SDAV\Locks\Backend\File('store/[data]/locks'); + $lockPlugin = new SDAV\Locks\Plugin($lockBackend); $server->addPlugin($lockPlugin); -- cgit v1.2.3 From 0746794e8145eac0608eef26b9c6d3d0ae5319cc Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 7 May 2016 18:39:19 -0400 Subject: New plugin repo cloned using new GitRepo class. Readme and info displayed in wide modal dialog. --- Zotlabs/Module/Admin.php | 63 +++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index ddec02916..68508fdb0 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1,7 +1,7 @@ t('Download Plugin Repo') ) ); + $newRepoModalID = random_string(3); + $newRepoModal = replace_macros( + get_markup_template('generic_modal.tpl'), array( + '$id' => $newRepoModalID, + '$title' => t('Install new repo'), + '$ok' => t('OK'), + '$cancel' => t('Cancel') + ) + ); $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( @@ -1372,7 +1381,9 @@ class Admin extends \Zotlabs\Web\Controller { '$form_security_token' => get_form_security_token('admin_plugins'), '$addrepo' => t('Add Plugin Repo'), '$expandform' => false, - '$form' => $admin_plugins_add_repo_form + '$form' => $admin_plugins_add_repo_form, + '$newRepoModal' => $newRepoModal, + '$newRepoModalID' => $newRepoModalID )); } @@ -1669,57 +1680,23 @@ class Admin extends \Zotlabs\Web\Controller { function admin_page_plugins_post($action) { switch($action) { - case 'addrepo': - + case 'addrepo': require_once('library/markdown.php'); if(array_key_exists('repoURL',$_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies logger('Repo URL submitted: ' . $_REQUEST['repoURL']); $repoURL = $_REQUEST['repoURL']; - $urlpath = parse_url($repoURL, PHP_URL_PATH); - $lastslash = strrpos($urlpath, '/') + 1; - $gitext = strrpos($urlpath, '.'); - if ($gitext) { - $reponame = substr($urlpath, $lastslash, $gitext - $lastslash); - } else { - logger('invalid git repo URL'); - notice('Invalid git repo URL'); - break; - } - $storepath = realpath(__DIR__ . '/../../store/'); - //logger('storepath: ' . $storepath); - $repopath = $storepath . '/pluginrepos/' . $reponame; - $git = new Git(); - if (!file_exists($repopath)) { - //logger('repopath does not exist'); - if (mkdir($repopath, 0770, true)) { - $cloned = $git->clone($repoURL, $repopath); - if (!$cloned) { - logger('git clone failed'); - notice('Repo coule not be cloned. Filesystem path error.'); - json_return_and_die(array('message' => 'Repo could not be cloned. Filesystem path error.', 'success' => false)); - } - //json_return_and_die(array('repo'=> $repo, 'message' => 'Successfully cloned to: ' . $repopath , 'success' => true)); - } else { - logger('repopath could not be created'); - notice('Repo coule not be cloned. Filesystem path error.'); - json_return_and_die(array('message' => 'Repo could not be cloned. Filesystem path error', 'success' => false)); - } - } - $git->setRepository($repopath); - $repo = array(); - $repo['url'] = $repoURL; - $repo['branches'] = $git->branch(['all' => true]); - $repo['objects'] = array(); + $git = new GitRepo('sys', $repoURL, true); + + $repo = $git->probeRepo($git->path); $repo['readme'] = $repo['manifest'] = null; - foreach ($git->tree('master') as $object) { + foreach ($git->git->tree('master') as $object) { if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { - $repo['readme'] = Markdown($git->cat->blob($object['hash'])); + $repo['readme'] = Markdown($git->git->cat->blob($object['hash'])); } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { - $repo['manifest'] = $git->cat->blob($object['hash']); + $repo['manifest'] = $git->git->cat->blob($object['hash']); } } - //logger('repo: ' . json_encode($repo)); json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); } else { -- cgit v1.2.3 From f73a74967ec0d68756743cd17fae65a5b2245628 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 7 May 2016 22:12:12 -0400 Subject: Existing addon repos are listed on plugin page with controls for updating, removing, and switching branches. --- Zotlabs/Module/Admin.php | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 68508fdb0..b4c372f84 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1364,11 +1364,18 @@ class Admin extends \Zotlabs\Web\Controller { get_markup_template('generic_modal.tpl'), array( '$id' => $newRepoModalID, '$title' => t('Install new repo'), - '$ok' => t('OK'), + '$ok' => t('Install'), '$cancel' => t('Cancel') ) ); + $reponames = $this->listAddonRepos(); + $addonrepos = []; + foreach($reponames as $repo) { + $addonrepos[] = array('name' => $repo, 'description' => ''); + // TODO: Parse repo info to provide more information about repos + } + $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( '$title' => t('Administration'), @@ -1383,10 +1390,28 @@ class Admin extends \Zotlabs\Web\Controller { '$expandform' => false, '$form' => $admin_plugins_add_repo_form, '$newRepoModal' => $newRepoModal, - '$newRepoModalID' => $newRepoModalID + '$newRepoModalID' => $newRepoModalID, + '$addonrepos' => $addonrepos, + '$repoUpdateButton' => t('Update'), + '$repoBranchButton' => t('Switch branch'), + '$repoRemoveButton' => t('Remove') )); } - + + function listAddonRepos() { + $addonrepos = []; + $addonDir = __DIR__ . '/../../extend/addon/'; + if ($handle = opendir($addonDir)) { + while (false !== ($entry = readdir($handle))) { + if ($entry != "." && $entry != "..") { + $addonrepos[] = $entry; + } + } + closedir($handle); + } + return $addonrepos; + } + static public function plugin_sort($a,$b) { return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name']))); } -- cgit v1.2.3 From 09ef30feb0e6f38ee3de34a37270cf796850b3d4 Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 8 May 2016 21:27:52 +1000 Subject: Update some modules to use new ACL dialog feature --- Zotlabs/Module/Channel.php | 3 ++- Zotlabs/Module/Editwebpage.php | 3 ++- Zotlabs/Module/Events.php | 7 +++++-- Zotlabs/Module/Filestorage.php | 4 +++- Zotlabs/Module/Network.php | 3 ++- Zotlabs/Module/Photos.php | 5 +++-- Zotlabs/Module/Rpost.php | 3 ++- Zotlabs/Module/Settings.php | 4 +++- Zotlabs/Module/Webpages.php | 3 ++- 9 files changed, 24 insertions(+), 11 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 47c5f31fb..f55705442 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -9,6 +9,7 @@ require_once('include/security.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); require_once('include/permissions.php'); +require_once('include/PermissionDescription.php'); class Channel extends \Zotlabs\Web\Controller { @@ -132,7 +133,7 @@ function get($update = 0, $load = false) { 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), 'nickname' => \App::$profile['channel_address'], 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index d3b031db2..5bd75df4a 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -3,6 +3,7 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); +require_once('include/PermissionDescription.php'); class Editwebpage extends \Zotlabs\Web\Controller { @@ -195,7 +196,7 @@ class Editwebpage extends \Zotlabs\Web\Controller { '$baseurl' => z_root(), '$defloc' => $itm[0]['location'], '$visitor' => ($is_owner) ? true : false, - '$acl' => populate_acl($itm[0],false), + '$acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')), '$showacl' => ($is_owner) ? true : false, '$public' => t('Public post'), '$jotnets' => $jotnets, diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index a14e320b2..9519ca11b 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -6,6 +6,7 @@ require_once('include/bbcode.php'); require_once('include/datetime.php'); require_once('include/event.php'); require_once('include/items.php'); +require_once('include/PermissionDescription.php'); class Events extends \Zotlabs\Web\Controller { @@ -237,7 +238,7 @@ class Events extends \Zotlabs\Web\Controller { - function get() { + function get() { if(argc() > 2 && argv(1) == 'ical') { $event_id = argv(2); @@ -468,7 +469,9 @@ class Events extends \Zotlabs\Web\Controller { '$share' => array('share', t('Share this event'), $sh_checked, '', array(t('No'),t('Yes'))), '$preview' => t('Preview'), '$permissions' => t('Permission settings'), - '$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults),false)), + // populating the acl dialog was a permission description from view_stream because Cal.php, which + // displays events, says "since we don't currently have an event permission - use the stream permission" + '$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \PermissionDescription::fromGlobalPermission('view_stream'))), '$submit' => t('Submit'), '$advanced' => t('Advanced Options') diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php index 934a1e6a4..2861f31be 100644 --- a/Zotlabs/Module/Filestorage.php +++ b/Zotlabs/Module/Filestorage.php @@ -6,6 +6,8 @@ namespace Zotlabs\Module; */ require_once('include/attach.php'); +require_once('include/PermissionDescription.php'); + /** * @@ -132,7 +134,7 @@ class Filestorage extends \Zotlabs\Web\Controller { $cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : ''); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']); - $aclselect_e = populate_acl($f, false); + $aclselect_e = populate_acl($f, false, \PermissionDescription::fromGlobalPermission('view_storage')); $is_a_dir = (intval($f['is_dir']) ? true : false); $lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock'); diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 2badd7280..fdfa99c12 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -6,6 +6,7 @@ require_once('include/group.php'); require_once('include/contact_widgets.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); +require_once('include/PermissionDescription.php'); @@ -170,7 +171,7 @@ class Network extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 2b7f5525f..1659350a5 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -9,6 +9,7 @@ require_once('include/security.php'); require_once('include/Contact.php'); require_once('include/attach.php'); require_once('include/text.php'); +require_once('include/PermissionDescription.php'); @@ -632,7 +633,7 @@ class Photos extends \Zotlabs\Web\Controller { $lockstate = (($acl->is_private()) ? 'lock' : 'unlock'); } - $aclselect = (($_is_owner) ? populate_acl($channel_acl,false) : ''); + $aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_storage')) : ''); // this is wrong but is to work around an issue with js_upload wherein it chokes if these variables // don't exist. They really should be set to a parseable representation of the channel's default permissions @@ -1022,7 +1023,7 @@ class Photos extends \Zotlabs\Web\Controller { if($can_post) { $album_e = $ph[0]['album']; $caption_e = $ph[0]['description']; - $aclselect_e = (($_is_owner) ? populate_acl($ph[0]) : ''); + $aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \PermissionDescription::fromGlobalPermission('view_storage')) : ''); $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer'])); $_SESSION['album_return'] = bin2hex($ph[0]['album']); diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php index 41889c35c..1396f2a55 100644 --- a/Zotlabs/Module/Rpost.php +++ b/Zotlabs/Module/Rpost.php @@ -7,6 +7,7 @@ require_once('include/items.php'); require_once('include/taxonomy.php'); require_once('include/conversation.php'); require_once('include/zot.php'); +require_once('include/PermissionDescription.php'); /** * remote post @@ -115,7 +116,7 @@ class Rpost extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl,true,(($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl($channel_acl, true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => '', 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 413648c4d..8674ca5e7 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -2,6 +2,8 @@ namespace Zotlabs\Module; /** @file */ require_once('include/zot.php'); +require_once('include/PermissionDescription.php'); + class Settings extends \Zotlabs\Web\Controller { @@ -1064,7 +1066,7 @@ class Settings extends \Zotlabs\Web\Controller { '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), '$permissions' => t('Default Post Permissions'), '$permdesc' => t("\x28click to open/close\x29"), - '$aclselect' => populate_acl($perm_defaults,false), + '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of channel'))), '$suggestme' => $suggestme, '$group_select' => $group_select, '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()), diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index 84d58058e..18dd57473 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -4,6 +4,7 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); +require_once('include/PermissionDescription.php'); class Webpages extends \Zotlabs\Web\Controller { @@ -111,7 +112,7 @@ class Webpages extends \Zotlabs\Web\Controller { 'nickname' => \App::$profile['channel_address'], 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), 'bang' => '', - 'acl' => (($is_owner) ? populate_acl($channel_acl,false) : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''), 'showacl' => (($is_owner) ? true : false), 'visitor' => true, 'profile_uid' => intval($owner), -- cgit v1.2.3 From 174484a51cfc99e2194480a7e7513694028eecb3 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 8 May 2016 09:26:06 -0400 Subject: Custom addon repo name option added. --- Zotlabs/Module/Admin.php | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index b4c372f84..c068110a9 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1356,6 +1356,7 @@ class Admin extends \Zotlabs\Web\Controller { '$post' => 'admin/plugins/addrepo', '$desc' => t('Enter the public git repository URL of the plugin repo.'), '$repoURL' => array('repoURL', t('Plugin repo git URL'), '', ''), + '$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')), '$submit' => t('Download Plugin Repo') ) ); @@ -1708,12 +1709,37 @@ class Admin extends \Zotlabs\Web\Controller { case 'addrepo': require_once('library/markdown.php'); if(array_key_exists('repoURL',$_REQUEST)) { - require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies - logger('Repo URL submitted: ' . $_REQUEST['repoURL']); + require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; - $git = new GitRepo('sys', $repoURL, true); + $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $addonDir = $extendDir.'/addon'; + if(!file_exists($extendDir)) { + if(!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if(!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + $repoName = null; + if(array_key_exists('repoName',$_REQUEST)) { + $repoName = $_REQUEST['repoName']; + logger('repoName: ' . $repoName); + } else { + $repoName = GitRepo::getRepoNameFromURL($repoURL); + } + if(!$repoName) { + logger('Invalid git repo'); + json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); + } + $repoDir = $addonDir.'/'.$repoName; + // clone the repo if new automatically + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - $repo = $git->probeRepo($git->path); + $repo = $git->probeRepo(); $repo['readme'] = $repo['manifest'] = null; foreach ($git->git->tree('master') as $object) { if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { -- cgit v1.2.3 From d714cd76dd4f38f7a04c7f9fbded427d7b06d3a8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 8 May 2016 20:30:00 -0400 Subject: Addon repo is copied to /extend/addon/ when admin presses install. Addon repos can be removed via GUI. --- Zotlabs/Module/Admin.php | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index c068110a9..404585ccd 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -43,6 +43,14 @@ class Admin extends \Zotlabs\Web\Controller { $this->admin_page_plugins_post('addrepo'); break; } + if (argc() > 2 && argv(2) === 'installrepo') { + $this->admin_page_plugins_post('installrepo'); + break; + } + if (argc() > 2 && argv(2) === 'removerepo') { + $this->admin_page_plugins_post('removerepo'); + break; + } if (argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")){ @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); @@ -1706,6 +1714,57 @@ class Admin extends \Zotlabs\Web\Controller { function admin_page_plugins_post($action) { switch($action) { + case 'removerepo': + if(array_key_exists('repoName', $_REQUEST)) { + $repoName = $_REQUEST['repoName']; + } else { + json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); + } + $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/'.$repoName; + if(!is_dir($repoDir)) { + json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); + } + // TODO: remove directory and unlink /addon/files + if(rrmdir($repoDir)) { + json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); + } + case 'installrepo': + require_once('library/markdown.php'); + if(array_key_exists('repoURL',$_REQUEST)) { + require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies + $repoURL = $_REQUEST['repoURL']; + $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $addonDir = $extendDir.'/addon'; + if(!file_exists($extendDir)) { + if(!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if(!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } + $repoName = null; + if(array_key_exists('repoName',$_REQUEST)) { + $repoName = $_REQUEST['repoName']; + } else { + $repoName = GitRepo::getRepoNameFromURL($repoURL); + } + if(!$repoName) { + logger('Invalid git repo'); + json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); + } + $repoDir = $addonDir.'/'.$repoName; + $tempAddonDir = __DIR__ . '/../../store/git/sys/temp/' . $repoName; + rename($tempAddonDir, $repoDir); + $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); + $repo = $git->probeRepo(); + json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); + } case 'addrepo': require_once('library/markdown.php'); if(array_key_exists('repoURL',$_REQUEST)) { @@ -1713,6 +1772,7 @@ class Admin extends \Zotlabs\Web\Controller { $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/git/sys/extend'; $addonDir = $extendDir.'/addon'; + $tempAddonDir = __DIR__ . '/../../store/git/sys/temp'; if(!file_exists($extendDir)) { if(!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); @@ -1735,7 +1795,7 @@ class Admin extends \Zotlabs\Web\Controller { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); } - $repoDir = $addonDir.'/'.$repoName; + $repoDir = $tempAddonDir.'/'.$repoName; // clone the repo if new automatically $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); -- cgit v1.2.3 From 6f486a3393fe33db70ef2f1684dd3b79768d1137 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 9 May 2016 01:12:24 -0700 Subject: prevent recursion in the database driver when debugging is enabled and the system config is not yet loaded - caused by calling get_config and making db calls within the logger function; which we then attempt to log... --- Zotlabs/Module/Network.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index fdfa99c12..c88258a78 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -446,7 +446,7 @@ class Network extends \Zotlabs\Web\Controller { $ordering = "commented"; if($load) { - + // Fetch a page full of parent items for this page $r = q("SELECT distinct item.id AS item_id, $ordering FROM item @@ -469,7 +469,7 @@ class Network extends \Zotlabs\Web\Controller { ); $_SESSION['loadtime'] = datetime_convert(); } - + // Then fetch all the children of the parents that are on this page $parents_str = ''; $update_unseen = ''; -- cgit v1.2.3 From 24c1dc528dd981fc73baab8dc47840439e81f3b7 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Mon, 9 May 2016 11:56:42 +0200 Subject: make editwebpage use status_editor() and fix storing of layout on webpage creation --- Zotlabs/Module/Editwebpage.php | 182 +++++++++++++++-------------------------- Zotlabs/Module/Webpages.php | 31 ++++--- 2 files changed, 78 insertions(+), 135 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 5bd75df4a..c2346c53b 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -3,47 +3,47 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); +require_once('include/conversation.php'); require_once('include/PermissionDescription.php'); class Editwebpage extends \Zotlabs\Web\Controller { function init() { - + if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { \App::$is_sys = true; } } - + if(argc() > 1) $which = argv(1); else return; - + profile_load($a,$which); - + } - - - function get() { - + + function get() { + if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); \App::$error = 404; return; } - + $which = argv(1); - + $uid = local_channel(); $owner = 0; $channel = null; $observer = \App::get_observer(); - + $channel = \App::get_channel(); - + if(\App::$is_sys && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { @@ -52,7 +52,7 @@ class Editwebpage extends \Zotlabs\Web\Controller { $observer = $sys; } } - + if(! $owner) { // Figure out who the page owner is. $r = q("select channel_id from channel where channel_address = '%s'", @@ -62,51 +62,50 @@ class Editwebpage extends \Zotlabs\Web\Controller { $owner = intval($r[0]['channel_id']); } } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { notice( t('Permission denied.') . EOL); return; } - + $is_owner = (($uid && $uid == $owner) ? true : false); - + $o = ''; - + // Figure out which post we're editing $post_id = ((argc() > 2) ? intval(argv(2)) : 0); - if(! $post_id) { notice( t('Item not found') . EOL); return; } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + $perms = get_all_perms($owner,$ob_hash); - + if(! $perms['write_pages']) { notice( t('Permission denied.') . EOL); return; } - + // We've already figured out which item we want and whose copy we need, // so we don't need anything fancy here - + $sql_extra = item_permissions_sql($owner); - + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s $sql_extra LIMIT 1", intval($post_id), intval($owner) ); - + if(! $itm) { notice( t('Permission denied.') . EOL); return; } - + if(intval($itm[0]['item_obscured'])) { $key = get_config('system','prvkey'); if($itm[0]['title']) @@ -114,120 +113,67 @@ class Editwebpage extends \Zotlabs\Web\Controller { if($itm[0]['body']) $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); } - + $item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1", intval($itm[0]['id']) ); if($item_id) $page_title = $item_id[0]['sid']; - - $plaintext = true; - + $mimetype = $itm[0]['mimetype']; - + if($mimetype === 'application/x-php') { if((! $uid) || ($uid != $itm[0]['uid'])) { notice( t('Permission denied.') . EOL); return; } } - - $mimeselect = ''; - - if($mimetype != 'text/bbcode') - $plaintext = true; - - if(get_config('system','page_mimetype')) - $mimeselect = ''; - else - $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); - - $layout = get_config('system','page_layout'); - if($layout) - $layoutselect = ''; - else - $layoutselect = layout_select($itm[0]['uid'],$itm[0]['layout_mid']); - \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( - '$baseurl' => z_root(), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$pretext' => '', - '$ispublic' => ' ', // t('Visible to everybody'), - '$geotag' => $geotag, - '$nickname' => $channel['channel_address'], - '$confirmdelete' => t('Delete webpage?'), - '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : '') - )); + $layout = $itm[0]['layout_mid']; $tpl = get_markup_template("jot.tpl"); - - $jotplugins = ''; - $jotnets = ''; - - call_hooks('jot_tool', $jotplugins); - call_hooks('jot_networks', $jotnets); - - // FIXME A return path with $_SESSION doesn't always work for observer - it may WSoD - // instead of loading a sensible page. So, send folk to the webpage list. - + $rp = 'webpages/' . $which; - - $editor = replace_macros($tpl,array( - '$return_path' => $rp, - '$webpage' => ITEM_TYPE_WEBPAGE, - '$placeholdpagetitle' => t('Page link title'), - '$pagetitle' => $page_title, - '$writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), - '$action' => 'item', - '$share' => t('Edit'), - '$bold' => t('Bold'), - '$italic' => t('Italic'), - '$underline' => t('Underline'), - '$quote' => t('Quote'), - '$code' => t('Code'), - '$attach' => t('Attach file'), - '$weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), - '$setloc' => false, //t('Set your location'), - '$noloc' => false, //((get_pconfig($uid, 'system', 'use_browser_location')) ? t('Clear browser location') : ''), - '$permset' => t('Permission settings'), - '$ptyp' => $itm[0]['type'], - '$content' => undo_post_tagging($itm[0]['body']), - '$post_id' => $post_id, - '$baseurl' => z_root(), - '$defloc' => $itm[0]['location'], - '$visitor' => ($is_owner) ? true : false, - '$acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')), - '$showacl' => ($is_owner) ? true : false, - '$public' => t('Public post'), - '$jotnets' => $jotnets, - '$mimeselect' => $mimeselect, - '$layoutselect' => $layoutselect, - '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), - '$placeholdertitle' => t('Title (optional)'), - '$category' => '', - '$placeholdercategory' => t('Categories (optional, comma-separated list)'), - '$emtitle' => t('Example: bob@example.com, mary@example.com'), + + $x = array( + 'nickname' => $channel['channel_address'], + 'bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : ''), + 'return_path' => $rp, + 'webpage' => ITEM_TYPE_WEBPAGE, + 'ptlabel' => t('Page link'), + 'pagetitle' => $page_title, + 'writefiles' => (($mimetype == 'text/bbcode') ? perm_is_allowed($owner, get_observer_hash(), 'write_storage') : false), + 'button' => t('Edit'), + 'weblink' => (($mimetype == 'text/bbcode') ? t('Insert web link') : false), + 'hide_location' => true, + 'hide_voting' => true, + 'ptyp' => $itm[0]['type'], + 'body' => undo_post_tagging($itm[0]['body']), + 'post_id' => $post_id, + 'visitor' => ($is_owner) ? true : false, + 'acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')), + 'showacl' => ($is_owner) ? true : false, + 'mimetype' => $mimetype, + 'mimeselect' => true, + 'layout' => $layout, + 'layoutselect' => true, + 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), 'lockstate' => (((strlen($itm[0]['allow_cid'])) || (strlen($itm[0]['allow_gid'])) || (strlen($itm[0]['deny_cid'])) || (strlen($itm[0]['deny_gid']))) ? 'lock' : 'unlock'), - '$bang' => '', - '$profile_uid' => (intval($owner)), - '$preview' => t('Preview'), - '$jotplugins' => $jotplugins, - '$sourceapp' => \App::$sourcename, - '$defexpire' => '', - '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) - )); - + 'profile_uid' => (intval($owner)), + 'bbcode' => (($mimetype == 'text/bbcode') ? true : false) + ); + + $editor = status_editor($a, $x); + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Webpage'), '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), '$editor' => $editor, '$id' => $itm[0]['id'] )); - + return $o; - + } - - - + } diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index 18dd57473..d8adb55b2 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -77,13 +77,7 @@ class Webpages extends \Zotlabs\Web\Controller { $mimetype = (($_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype')); - if(! $mimetype) { - $mimetype = 'choose'; - } - $layout = (($_REQUEST['layout']) ? $_REQUEST['layout'] : get_pconfig($owner,'system','page_layout')); - if(! $layout) - $layout = 'choose'; // Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages // Nickname is set to the observers xchan, and profile_uid to the owner's. @@ -107,18 +101,21 @@ class Webpages extends \Zotlabs\Web\Controller { $o = profile_tabs($a, $is_owner, \App::$profile['channel_address']); $x = array( - 'webpage' => ITEM_TYPE_WEBPAGE, - 'is_owner' => true, - 'nickname' => \App::$profile['channel_address'], - 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'bang' => '', - 'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''), - 'showacl' => (($is_owner) ? true : false), - 'visitor' => true, + 'webpage' => ITEM_TYPE_WEBPAGE, + 'is_owner' => true, + 'nickname' => \App::$profile['channel_address'], + 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''), + 'showacl' => (($is_owner) ? true : false), + 'visitor' => true, + 'hide_location' => true, + 'hide_voting' => true, 'profile_uid' => intval($owner), - 'mimetype' => $mimetype, - 'layout' => $layout, - 'expanded' => true, + 'mimetype' => $mimetype, + 'mimeselect' => true, + 'layout' => $layout, + 'layoutselect' => true, + 'expanded' => true, 'novoting'=> true, 'bbco_autocomplete' => 'bbcode', 'bbcode' => true -- cgit v1.2.3 From ef97e5a0636c2563f696b8601619d963b363fe00 Mon Sep 17 00:00:00 2001 From: Treer Date: Tue, 10 May 2016 00:15:57 +1000 Subject: minor cleanup. No functional changes --- Zotlabs/Module/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 8674ca5e7..a6293e842 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -1066,7 +1066,7 @@ class Settings extends \Zotlabs\Web\Controller { '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), '$permissions' => t('Default Post Permissions'), '$permdesc' => t("\x28click to open/close\x29"), - '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of channel'))), + '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of post'))), '$suggestme' => $suggestme, '$group_select' => $group_select, '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()), -- cgit v1.2.3 From 180731c162b12f62a0065bc9ce8d537a95c98ed6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 9 May 2016 21:17:47 -0400 Subject: copy-paste error --- Zotlabs/Module/Admin.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 404585ccd..19b8a2e77 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -51,6 +51,10 @@ class Admin extends \Zotlabs\Web\Controller { $this->admin_page_plugins_post('removerepo'); break; } + if (argc() > 2 && argv(2) === 'updaterepo') { + $this->admin_page_plugins_post('updaterepo'); + break; + } if (argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")){ @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); @@ -1714,6 +1718,22 @@ class Admin extends \Zotlabs\Web\Controller { function admin_page_plugins_post($action) { switch($action) { + case 'updaterepo': + if(array_key_exists('repoName', $_REQUEST)) { + $repoName = $_REQUEST['repoName']; + } else { + json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); + } + $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/'.$repoName; + if(!is_dir($repoDir)) { + json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); + } + $git = new GitRepo('sys', null, false, $repoName, $repoDir); + if($git->pull()) { + json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); + } case 'removerepo': if(array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; -- cgit v1.2.3 From 9c8cf7d43372aeea4d8a450e7cb17d7a24b64d5f Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 9 May 2016 21:59:27 -0400 Subject: Fixed some bugs with empty repo name and improved the interface a bit. --- Zotlabs/Module/Admin.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 19b8a2e77..63f3e77f0 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1729,9 +1729,13 @@ class Admin extends \Zotlabs\Web\Controller { json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } $git = new GitRepo('sys', null, false, $repoName, $repoDir); - if($git->pull()) { - json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); - } else { + try { + if($git->pull()) { + json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); + } + } catch(\PHPGit\Exception\GitException $e) { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } case 'removerepo': @@ -1769,7 +1773,7 @@ class Admin extends \Zotlabs\Web\Controller { } } $repoName = null; - if(array_key_exists('repoName',$_REQUEST)) { + if(array_key_exists('repoName',$_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); @@ -1805,15 +1809,14 @@ class Admin extends \Zotlabs\Web\Controller { } } $repoName = null; - if(array_key_exists('repoName',$_REQUEST)) { + if(array_key_exists('repoName',$_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; - logger('repoName: ' . $repoName); } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); } if(!$repoName) { logger('Invalid git repo'); - json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); + json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); } $repoDir = $tempAddonDir.'/'.$repoName; // clone the repo if new automatically -- cgit v1.2.3 From baa7020036f4b6112a58a99d04af2f5287a8c815 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 9 May 2016 22:28:54 -0700 Subject: revert shutdown function --- Zotlabs/Module/Manage.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Manage.php b/Zotlabs/Module/Manage.php index fee202263..5ae79dbb2 100644 --- a/Zotlabs/Module/Manage.php +++ b/Zotlabs/Module/Manage.php @@ -28,10 +28,12 @@ class Manage extends \Zotlabs\Web\Controller { } goaway(z_root() . '/manage'); } + if($change_channel) { + $r = change_channel($change_channel); - + if((argc() > 2) && !(argv(2) === 'default')) { goaway(z_root() . '/' . implode('/',array_slice(\App::$argv,2))); // Go to whatever is after /manage/, but with the new channel } -- cgit v1.2.3 From 8ab77078983470e9c5223edf9d1e7502207f7169 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 10 May 2016 10:02:27 +0200 Subject: allow delayed publishing of webpages --- Zotlabs/Module/Page.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index 8a8bc7a49..14273614c 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -66,7 +66,7 @@ class Page extends \Zotlabs\Web\Controller { $sql_options = item_permissions_sql($u[0]['channel_id']); $r = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and (( service = 'WEBPAGE' and item_type = %d ) + where item.uid = %d and sid = '%s' and item.item_delayed = 0 and (( service = 'WEBPAGE' and item_type = %d ) OR ( service = 'PDL' AND item_type = %d )) $sql_options $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), @@ -78,7 +78,7 @@ class Page extends \Zotlabs\Web\Controller { // Check again with no permissions clause to see if it is a permissions issue $x = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and service = 'WEBPAGE' and + where item.uid = %d and sid = '%s' and item.item_delayed = 0 and service = 'WEBPAGE' and item_type = %d $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), -- cgit v1.2.3 From 0c5434d5e35f13340df5bf5edd22c6d9e9e8379c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 10 May 2016 01:30:22 -0700 Subject: try again with shutdown handler, fix issue #373 (live-pubstream div wasn't present --- Zotlabs/Module/Pubstream.php | 4 ++-- Zotlabs/Module/Update_pubstream.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index d6cfe6e92..e48f8363c 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -28,7 +28,7 @@ class Pubstream extends \Zotlabs\Web\Controller { if(! $maxheight) $maxheight = 400; - $o .= '
    ' . "\r\n"; + $o .= '
    ' . "\r\n"; $o .= "\r\n"; @@ -161,7 +161,7 @@ class Pubstream extends \Zotlabs\Web\Controller { if(($items) && (! $update)) $o .= alt_pager($a,count($items)); - + return $o; } diff --git a/Zotlabs/Module/Update_pubstream.php b/Zotlabs/Module/Update_pubstream.php index 153db56ba..952b48df3 100644 --- a/Zotlabs/Module/Update_pubstream.php +++ b/Zotlabs/Module/Update_pubstream.php @@ -7,7 +7,7 @@ namespace Zotlabs\Module; class Update_pubstream extends \Zotlabs\Web\Controller { function get() { - + $profile_uid = ((intval($_GET['p'])) ? intval($_GET['p']) : (-1)); $load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0); header("Content-type: text/html"); -- cgit v1.2.3 From 45c19e365d8b73c8623f5d1c65b528cd628374a5 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 10 May 2016 10:40:36 +0200 Subject: another public -> pubstream --- Zotlabs/Module/Pubstream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index e48f8363c..adc16e6e6 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -35,7 +35,7 @@ class Pubstream extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( '$baseurl' => z_root(), - '$pgtype' => 'public', + '$pgtype' => 'pubstream', '$uid' => ((local_channel()) ? local_channel() : '0'), '$gid' => '0', '$cid' => '0', -- cgit v1.2.3 From 78b40e6363d422727bb716f5e72983291c75d217 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 10 May 2016 06:28:00 -0400 Subject: Delete existing repo if the new one has a different URL. Fixed bug that could cause repeated installation. --- Zotlabs/Module/Admin.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 63f3e77f0..1b98a2ced 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1822,6 +1822,15 @@ class Admin extends \Zotlabs\Web\Controller { // clone the repo if new automatically $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + $remotes = $git->git->remote(); + $fetchURL = $remotes['origin']['fetch']; + if($fetchURL !== $git->url) { + if(rrmdir($repoDir)) { + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + } else { + json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); + } + } $repo = $git->probeRepo(); $repo['readme'] = $repo['manifest'] = null; foreach ($git->git->tree('master') as $object) { -- cgit v1.2.3 From 0b02a6d123b2014705998c94ddf3d460948d3eac Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 10 May 2016 17:26:44 -0700 Subject: initial sabre upgrade (needs lots of work - to wit: authentication, redo the browser interface, and rework event export/import) --- Zotlabs/Module/Dav.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 9af059974..cc6ea4905 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -60,8 +60,16 @@ class Dav extends \Zotlabs\Web\Controller { if ($which) profile_load($a, $which, $profile); + + $auth = new \Zotlabs\Storage\BasicAuth(); - + + $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { + if(account_verify_password($userName,$password)) + return true; + return false; + }); + $ob_hash = get_observer_hash(); if ($ob_hash) { @@ -92,6 +100,12 @@ class Dav extends \Zotlabs\Web\Controller { // A SabreDAV server-object $server = new SDAV\Server($rootDirectory); + + + $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend); + $server->addPlugin($authPlugin); + + // prevent overwriting changes each other with a lock backend $lockBackend = new SDAV\Locks\Backend\File('store/[data]/locks'); $lockPlugin = new SDAV\Locks\Plugin($lockBackend); -- cgit v1.2.3 From 2882eef42fd7665d00c745276fb4315da29cadff Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 10 May 2016 21:00:10 -0400 Subject: Link plugins in the newly installed addon repo to /addon so they are accessible --- Zotlabs/Module/Admin.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 1b98a2ced..a9f06b7ef 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1785,6 +1785,25 @@ class Admin extends \Zotlabs\Web\Controller { $repoDir = $addonDir.'/'.$repoName; $tempAddonDir = __DIR__ . '/../../store/git/sys/temp/' . $repoName; rename($tempAddonDir, $repoDir); + + $files = array_diff(scandir($repoDir), array('.', '..')); + logger('files: ' . json_encode($files)); + foreach ($files as $file) + { + if(is_dir($repoDir.'/'.$file) && $file !== '.git') { + $source = realpath(__DIR__ . '/../../extend/addon/'.$repoName.'/'.$file.'/'); + $source = '../extend/addon/'.$repoName.'/'.$file; + $target = realpath(__DIR__ . '/../../addon/').'/'.$file; + logger('file: ' . json_encode($file)); + logger('source: ' . $source); + logger('target: ' . $target); + unlink($target); + if(!symlink($source, $target)) { + logger('Error linking addons to /addon'); + json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); + } + } + } $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); $repo = $git->probeRepo(); json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); -- cgit v1.2.3 From 40e3d37a723f28a8957f3a844f9470c274c330e9 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 10 May 2016 21:01:47 -0400 Subject: Remove debugging lines --- Zotlabs/Module/Admin.php | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index a9f06b7ef..0e3ee68c4 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1791,12 +1791,8 @@ class Admin extends \Zotlabs\Web\Controller { foreach ($files as $file) { if(is_dir($repoDir.'/'.$file) && $file !== '.git') { - $source = realpath(__DIR__ . '/../../extend/addon/'.$repoName.'/'.$file.'/'); $source = '../extend/addon/'.$repoName.'/'.$file; $target = realpath(__DIR__ . '/../../addon/').'/'.$file; - logger('file: ' . json_encode($file)); - logger('source: ' . $source); - logger('target: ' . $target); unlink($target); if(!symlink($source, $target)) { logger('Error linking addons to /addon'); -- cgit v1.2.3 From 915bd2ec7745110919a4d386ae2b433a2c22701a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 10 May 2016 19:40:15 -0700 Subject: sabre upgrade --- Zotlabs/Module/Cloud.php | 1 - Zotlabs/Module/Dav.php | 111 ++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 56 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 5f40f4af1..f3767e3f0 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -90,7 +90,6 @@ class Cloud extends \Zotlabs\Web\Controller { } } - // require_once('\Zotlabs/Storage/Browser.php'); // provide a directory view for the cloud in Hubzilla $browser = new \Zotlabs\Storage\Browser($auth); $auth->setBrowserPlugin($browser); diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index cc6ea4905..549c992cc 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -62,39 +62,40 @@ class Dav extends \Zotlabs\Web\Controller { + $auth = new \Zotlabs\Storage\BasicAuth(); - $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { - if(account_verify_password($userName,$password)) - return true; - return false; - }); - - $ob_hash = get_observer_hash(); - - if ($ob_hash) { - if (local_channel()) { - $channel = \App::get_channel(); - $auth->setCurrentUser($channel['channel_address']); - $auth->channel_id = $channel['channel_id']; - $auth->channel_hash = $channel['channel_hash']; - $auth->channel_account_id = $channel['channel_account_id']; - if($channel['channel_timezone']) - $auth->setTimezone($channel['channel_timezone']); - } - $auth->observer = $ob_hash; - } - - if ($_GET['davguest']) - $_SESSION['davguest'] = true; - - $_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']); +// $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { +// if(account_verify_password($userName,$password)) +// return true; +// return false; +// }); + +// $ob_hash = get_observer_hash(); + +// if ($ob_hash) { +// if (local_channel()) { +// $channel = \App::get_channel(); +// $auth->setCurrentUser($channel['channel_address']); +// $auth->channel_id = $channel['channel_id']; +// $auth->channel_hash = $channel['channel_hash']; +// $auth->channel_account_id = $channel['channel_account_id']; +// if($channel['channel_timezone']) +// $auth->setTimezone($channel['channel_timezone']); +// } +// $auth->observer = $ob_hash; +// } + +// if ($_GET['davguest']) +// $_SESSION['davguest'] = true; + +// $_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); @@ -102,7 +103,7 @@ class Dav extends \Zotlabs\Web\Controller { $server = new SDAV\Server($rootDirectory); - $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend); + $authPlugin = new \Sabre\DAV\Auth\Plugin($auth); $server->addPlugin($authPlugin); @@ -122,29 +123,29 @@ class Dav extends \Zotlabs\Web\Controller { // In order to avoid prompting for passwords for viewing a DIRECTORY, add // the URL query parameter 'davguest=1'. - $isapublic_file = false; - $davguest = ((x($_SESSION, 'davguest')) ? true : false); - - if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) { - try { - $x = RedFileData('/' . \App::$cmd, $auth); - if($x instanceof \Zotlabs\Storage\File) - $isapublic_file = true; - } - catch (Exception $e) { - $isapublic_file = false; - } - } - - if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) { - try { - $auth->Authenticate($server, t('$Projectname channel')); - } - catch (Exception $e) { - logger('mod_cloud: auth exception' . $e->getMessage()); - http_status_exit($e->getHTTPCode(), $e->getMessage()); - } - } +// $isapublic_file = false; +// $davguest = ((x($_SESSION, 'davguest')) ? true : false); + +// if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) { +// try { +// $x = RedFileData('/' . \App::$cmd, $auth); +// if($x instanceof \Zotlabs\Storage\File) +// $isapublic_file = true; +// } +// catch (Exception $e) { +// $isapublic_file = false; +// } +// } + +// if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) { +// try { +// $auth->Authenticate($server, t('$Projectname channel')); +// } +// catch (Exception $e) { +// logger('mod_cloud: auth exception' . $e->getMessage()); +// http_status_exit($e->getHTTPCode(), $e->getMessage()); +// } +// } // require_once('Zotlabs/Storage/Browser.php'); // provide a directory view for the cloud in Hubzilla -- cgit v1.2.3 From 4dd3839c41e18d9724855e7955d8737b6f52dcd6 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 10 May 2016 21:46:04 -0700 Subject: provide repository versions on admin summary page and an upgrade message if you're behind master --- Zotlabs/Module/Admin.php | 21 +++++++++++++++------ Zotlabs/Module/Siteinfo.php | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 0e3ee68c4..94482b39d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -107,7 +107,7 @@ class Admin extends \Zotlabs\Web\Controller { * @param App &$a * @return string */ - function get() { + function get() { logger('admin_content', LOGGER_DEBUG); @@ -229,18 +229,27 @@ class Admin extends \Zotlabs\Web\Controller { . '
    PHP 5.3 has reached its End of Life (EOL) in August 2014.' . ' A list about current PHP versions can be found here.'; } - + + $vmaster = get_repository_version('master'); + $vdev = get_repository_version('dev'); + + $upgrade = ((version_compare(STD_VERSION,$vmaster) < 0) ? t('Your software should be updated') : ''); + + $t = get_markup_template('admin_summary.tpl'); return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Summary'), '$adminalertmsg' => $alertmsg, - '$queues' => $queues, + '$queues' => $queues, '$accounts' => array( t('Registered accounts'), $accounts), - '$pending' => array( t('Pending registrations'), $pending), + '$pending' => array( t('Pending registrations'), $pending), '$channels' => array( t('Registered channels'), $channels), - '$plugins' => array( t('Active plugins'), $plugins ), - '$version' => array( t('Version'), STD_VERSION), + '$plugins' => array( t('Active plugins'), $plugins ), + '$version' => array( t('Version'), STD_VERSION), + '$vmaster' => array( t('Repository version (master)'), $vmaster), + '$vdev' => array( t('Repository version (dev)'), $vdev), + '$upgrade' => $upgrade, '$build' => get_config('system', 'db_version') )); } diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php index ccca6ab43..c65277004 100644 --- a/Zotlabs/Module/Siteinfo.php +++ b/Zotlabs/Module/Siteinfo.php @@ -13,7 +13,7 @@ class Siteinfo extends \Zotlabs\Web\Controller { - function get() { + function get() { if(! get_config('system','hidden_version_siteinfo')) { $version = sprintf( t('Version %s'), \Zotlabs\Project\System::get_project_version()); -- cgit v1.2.3 From c7698e4dc388b7d9a9db368672cb057c1d4d3a01 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 11 May 2016 05:53:23 -0400 Subject: Check if target directories are writable when adding, updating, or removing plugin repos --- Zotlabs/Module/Admin.php | 151 +++++++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 63 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 0e3ee68c4..4b697d0de 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1717,131 +1717,157 @@ class Admin extends \Zotlabs\Web\Controller { } function admin_page_plugins_post($action) { - switch($action) { + switch ($action) { case 'updaterepo': - if(array_key_exists('repoName', $_REQUEST)) { + if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } - $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/'.$repoName; - if(!is_dir($repoDir)) { + $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; + if (!is_dir($repoDir)) { + logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); - } + } + if (!is_writable($repoDir)) { + logger('Repo directory not writable to web server: ' . $repoDir); + json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); + } $git = new GitRepo('sys', null, false, $repoName, $repoDir); try { - if($git->pull()) { + if ($git->pull()) { json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } - } catch(\PHPGit\Exception\GitException $e) { + } catch (\PHPGit\Exception\GitException $e) { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } case 'removerepo': - if(array_key_exists('repoName', $_REQUEST)) { + if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } - $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/'.$repoName; - if(!is_dir($repoDir)) { + $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; + if (!is_dir($repoDir)) { + logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } + if (!is_writable($repoDir)) { + logger('Repo directory not writable to web server: ' . $repoDir); + json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); + } // TODO: remove directory and unlink /addon/files - if(rrmdir($repoDir)) { + if (rrmdir($repoDir)) { json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); } - case 'installrepo': + case 'installrepo': require_once('library/markdown.php'); - if(array_key_exists('repoURL',$_REQUEST)) { - require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies + if (array_key_exists('repoURL', $_REQUEST)) { + require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/git/sys/extend'; - $addonDir = $extendDir.'/addon'; - if(!file_exists($extendDir)) { - if(!mkdir($extendDir, 0770, true)) { + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { - if(!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } + if (!is_writable($extendDir)) { + logger('Directory not writable to web server: ' . $extendDir); + json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); + } $repoName = null; - if(array_key_exists('repoName',$_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; + if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { + $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if(!$repoName) { + } + if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); } - $repoDir = $addonDir.'/'.$repoName; - $tempAddonDir = __DIR__ . '/../../store/git/sys/temp/' . $repoName; + $repoDir = $addonDir . '/' . $repoName; + $tempRepoBaseDir = __DIR__ . '/../../store/git/sys/temp/'; + $tempAddonDir = $tempRepoBaseDir . $repoName; + + if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { + logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); + } rename($tempAddonDir, $repoDir); - + + if (!is_writable(realpath(__DIR__ . '/../../addon/'))) { + logger('/addon directory not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); + } $files = array_diff(scandir($repoDir), array('.', '..')); - logger('files: ' . json_encode($files)); - foreach ($files as $file) - { - if(is_dir($repoDir.'/'.$file) && $file !== '.git') { - $source = '../extend/addon/'.$repoName.'/'.$file; - $target = realpath(__DIR__ . '/../../addon/').'/'.$file; - unlink($target); - if(!symlink($source, $target)) { - logger('Error linking addons to /addon'); - json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); - } + foreach ($files as $file) { + if (is_dir($repoDir . '/' . $file) && $file !== '.git') { + $source = '../extend/addon/' . $repoName . '/' . $file; + $target = realpath(__DIR__ . '/../../addon/') . '/' . $file; + unlink($target); + if (!symlink($source, $target)) { + logger('Error linking addons to /addon'); + json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); } + } } - $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); + $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); $repo = $git->probeRepo(); - json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); + json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } - case 'addrepo': + case 'addrepo': require_once('library/markdown.php'); - if(array_key_exists('repoURL',$_REQUEST)) { - require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies + if (array_key_exists('repoURL', $_REQUEST)) { + require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/git/sys/extend'; - $addonDir = $extendDir.'/addon'; + $addonDir = $extendDir . '/addon'; $tempAddonDir = __DIR__ . '/../../store/git/sys/temp'; - if(!file_exists($extendDir)) { - if(!mkdir($extendDir, 0770, true)) { + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { - if(!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } $repoName = null; - if(array_key_exists('repoName',$_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; + if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { + $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if(!$repoName) { + } + if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); } - $repoDir = $tempAddonDir.'/'.$repoName; + $repoDir = $tempAddonDir . '/' . $repoName; + if (!is_writable($tempAddonDir)) { + logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); + } // clone the repo if new automatically - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + $remotes = $git->git->remote(); $fetchURL = $remotes['origin']['fetch']; - if($fetchURL !== $git->url) { - if(rrmdir($repoDir)) { - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); + if ($fetchURL !== $git->url) { + if (rrmdir($repoDir)) { + $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); } else { json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); } @@ -1849,14 +1875,13 @@ class Admin extends \Zotlabs\Web\Controller { $repo = $git->probeRepo(); $repo['readme'] = $repo['manifest'] = null; foreach ($git->git->tree('master') as $object) { - if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { - $repo['readme'] = Markdown($git->git->cat->blob($object['hash'])); - } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { - $repo['manifest'] = $git->git->cat->blob($object['hash']); - } + if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { + $repo['readme'] = Markdown($git->git->cat->blob($object['hash'])); + } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { + $repo['manifest'] = $git->git->cat->blob($object['hash']); + } } - json_return_and_die(array('repo'=> $repo, 'message' => '', 'success' => true)); - + json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } else { json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); } @@ -1865,7 +1890,7 @@ class Admin extends \Zotlabs\Web\Controller { break; } } - + function admin_page_profs_post(&$a) { if(array_key_exists('basic',$_REQUEST)) { -- cgit v1.2.3 From 70d413ab0412506755bab4878995ab6e99d8e029 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 12 May 2016 06:49:24 -0400 Subject: Create store/git/sys/extend/addon directory and link if it does not exist in all plugin repo GUI POST actions --- Zotlabs/Module/Admin.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index e77cf0fc7..9b54a4081 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1733,6 +1733,19 @@ class Admin extends \Zotlabs\Web\Controller { } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } + $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); @@ -1758,6 +1771,19 @@ class Admin extends \Zotlabs\Web\Controller { } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } + $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $addonDir = $extendDir . '/addon'; + if (!file_exists($extendDir)) { + if (!mkdir($extendDir, 0770, true)) { + logger('Error creating extend folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); + } else { + if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { + logger('Error creating symlink to addon folder: ' . $addonDir); + json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); + } + } + } $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); -- cgit v1.2.3 From d38851023ec5bac78ece9469c758851e97e01285 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 16:28:51 -0700 Subject: provide server role on pubsites page --- Zotlabs/Module/Pubsites.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index 9313a3c5a..a1d91f53d 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -28,10 +28,10 @@ class Pubsites extends \Zotlabs\Web\Controller { if($ret['success']) { $j = json_decode($ret['body'],true); if($j) { - $o .= ''; + $o .= '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Ratings') . '
    '; if($j['sites']) { foreach($j['sites'] as $jj) { - if($jj['project'] !== \Zotlabs\Project\System::get_platform_name()) + if(strpos($jj['project'],\Zotlabs\Project\System::get_platform_name()) === false) continue; $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); $rate_links = ((local_channel()) ? '' : ''); @@ -43,7 +43,7 @@ class Pubsites extends \Zotlabs\Web\Controller { $location = '
     '; } $urltext = str_replace(array('https://'), '', $jj['url']); - $o .= '' . $rate_links . ''; + $o .= '' . $rate_links . ''; } } -- cgit v1.2.3 From 166d63ff608c94152ce7213472fac6a2b61fa913 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 16:31:12 -0700 Subject: missing close tag --- Zotlabs/Module/Pubsites.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index a1d91f53d..55f2c0ad6 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -43,7 +43,7 @@ class Pubsites extends \Zotlabs\Web\Controller { $location = '
     '; } $urltext = str_replace(array('https://'), '', $jj['url']); - $o .= '
    ' . $rate_links . ''; + $o .= '' . $rate_links . ''; } } -- cgit v1.2.3 From 77eb9bcfa04faee0fbf20a1d9fae90bdf0dcbcc3 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 18 May 2016 21:32:23 -0400 Subject: Link new plugins when updating repos via admin/plugins --- Zotlabs/Module/Admin.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 9b54a4081..cb843e212 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1758,6 +1758,18 @@ class Admin extends \Zotlabs\Web\Controller { $git = new GitRepo('sys', null, false, $repoName, $repoDir); try { if ($git->pull()) { + $files = array_diff(scandir($repoDir), array('.', '..')); + foreach ($files as $file) { + if (is_dir($repoDir . '/' . $file) && $file !== '.git') { + $source = '../extend/addon/' . $repoName . '/' . $file; + $target = realpath(__DIR__ . '/../../addon/') . '/' . $file; + unlink($target); + if (!symlink($source, $target)) { + logger('Error linking addons to /addon'); + json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); + } + } + } json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); -- cgit v1.2.3 From 905432c7ae738ff69090bf8cc912c42d2cea5ab2 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 22:53:43 -0700 Subject: text clarifications --- Zotlabs/Module/Dav.php | 1 + Zotlabs/Module/Settings.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 549c992cc..d65ad3405 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -64,6 +64,7 @@ class Dav extends \Zotlabs\Web\Controller { $auth = new \Zotlabs\Storage\BasicAuth(); + $auth->setRealm(ucfirst(\Zotlabs\Project\System::get_platform_name()) . 'WebDAV'); // $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { // if(account_verify_password($userName,$password)) diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index a6293e842..1f5c55067 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -1062,11 +1062,11 @@ class Settings extends \Zotlabs\Web\Controller { '$lbl_p2macro' => t('Advanced Privacy Settings'), - '$expire' => array('expire',t('Expire other channel content after this many days'),$expire,sprintf( t('0 or blank to use the website limit. The website expires after %d days.'),intval($sys_expire))), + '$expire' => array('expire',t('Expire other channel content after this many days'),$expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf( t('This website expires after %d days.'),intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')), '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), '$permissions' => t('Default Post Permissions'), '$permdesc' => t("\x28click to open/close\x29"), - '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of post'))), + '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), '$suggestme' => $suggestme, '$group_select' => $group_select, '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()), -- cgit v1.2.3 From 93a7df5a1b9ac260657ba789760cb9e4c11544a7 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 22:57:23 -0700 Subject: one more text clarification --- Zotlabs/Module/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 1f5c55067..f588e2824 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -1064,7 +1064,7 @@ class Settings extends \Zotlabs\Web\Controller { '$expire' => array('expire',t('Expire other channel content after this many days'),$expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf( t('This website expires after %d days.'),intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')), '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), - '$permissions' => t('Default Post Permissions'), + '$permissions' => t('Default Post and Publish Permissions'), '$permdesc' => t("\x28click to open/close\x29"), '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), '$suggestme' => $suggestme, -- cgit v1.2.3 From 50d1d06b0324737ca6dc7dab43e42217ee9381b4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 00:56:51 -0700 Subject: issue #391 - htmlspecialchars_decode before firing up jot, which re-encodes --- Zotlabs/Module/Editpost.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 43edf2c00..da859de3e 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -87,11 +87,11 @@ class Editpost extends \Zotlabs\Web\Controller { 'hide_location' => true, 'mimetype' => $itm[0]['mimetype'], 'ptyp' => $itm[0]['obj_type'], - 'body' => undo_post_tagging($itm[0]['body']), + 'body' => htmlspecialchars_decode(undo_post_tagging($itm[0]['body']),ENT_COMPAT), 'post_id' => $post_id, 'defloc' => $channel['channel_location'], 'visitor' => true, - 'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), + 'title' => htmlspecialchars_decode($itm[0]['title'],ENT_COMPAT), 'category' => $category, 'showacl' => false, 'profile_uid' => $owner_uid, -- cgit v1.2.3 From d5ca889cf5d479135560b1f915fb5d3986b28c65 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 19 May 2016 07:09:13 -0400 Subject: Replace text strings for translation support --- Zotlabs/Module/Admin.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index cb843e212..4d052cdf8 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1408,7 +1408,9 @@ class Admin extends \Zotlabs\Web\Controller { '$plugins' => $plugins, '$disabled' => t('Disabled - version incompatibility'), '$form_security_token' => get_form_security_token('admin_plugins'), - '$addrepo' => t('Add Plugin Repo'), + '$managerepos' => t('Manage Repos'), + '$installedtitle' => t('Installed Plugin Repositories'), + '$addnewrepotitle' => t('Install a New Plugin Repository'), '$expandform' => false, '$form' => $admin_plugins_add_repo_form, '$newRepoModal' => $newRepoModal, -- cgit v1.2.3 From a2cec8899ad191b47d116f4ea124be6bd5b05472 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 22:26:37 -0700 Subject: daemon conversion continued... --- Zotlabs/Module/Admin.php | 4 ++-- Zotlabs/Module/Connect.php | 3 ++- Zotlabs/Module/Connedit.php | 10 +++++----- Zotlabs/Module/Events.php | 2 +- Zotlabs/Module/Follow.php | 5 ++--- Zotlabs/Module/Fsuggest.php | 2 +- Zotlabs/Module/Import.php | 4 ++-- Zotlabs/Module/Item.php | 4 ++-- Zotlabs/Module/Like.php | 4 ++-- Zotlabs/Module/Locs.php | 6 +++--- Zotlabs/Module/Mail.php | 2 +- Zotlabs/Module/Mood.php | 2 +- Zotlabs/Module/Prate.php | 2 +- Zotlabs/Module/Profile_photo.php | 4 ++-- Zotlabs/Module/Profiles.php | 2 +- Zotlabs/Module/Rate.php | 6 ++---- Zotlabs/Module/Settings.php | 2 +- Zotlabs/Module/Tagger.php | 2 +- 18 files changed, 32 insertions(+), 34 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 4d052cdf8..0a167b273 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1082,7 +1082,7 @@ class Admin extends \Zotlabs\Web\Controller { intval(PAGE_CENSORED), intval( $uid ) ); - proc_run('php','include/directory.php',$uid,'nopush'); + \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush')); } notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) ); } @@ -1141,7 +1141,7 @@ class Admin extends \Zotlabs\Web\Controller { intval($pflags), intval( $uid ) ); - proc_run('php','include/directory.php',$uid,'nopush'); + \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush')); notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL); }; break; diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php index 6ef3577d7..382abf370 100644 --- a/Zotlabs/Module/Connect.php +++ b/Zotlabs/Module/Connect.php @@ -47,7 +47,8 @@ class Connect extends \Zotlabs\Web\Controller { intval(PAGE_PREMIUM), intval(local_channel()) ); - proc_run('php','include/notifier.php','refresh_all',\App::$data['channel']['channel_id']); + + \Zotlabs\Daemon\Master::Summon(array('Notifier','refresh_all',\App::$data['channel']['channel_id'])); } set_pconfig(\App::$data['channel']['channel_id'],'system','selltext',$text); // reload the page completely to get fresh data diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index a1268510d..0820c76bf 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -176,7 +176,7 @@ class Connedit extends \Zotlabs\Web\Controller { $record = $z[0]['xlink_id']; } if($record) { - proc_run('php','include/ratenotif.php','rating',$record); + \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record)); } } @@ -230,7 +230,7 @@ class Connedit extends \Zotlabs\Web\Controller { if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms && (! intval(\App::$poi['abook_self']))) { - proc_run('php', 'include/notifier.php', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id); + \Zotlabs\Daemon\Master(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id)); } if($new_friend) { @@ -283,7 +283,7 @@ class Connedit extends \Zotlabs\Web\Controller { // pull in a bit of content if there is any to pull in - proc_run('php','include/onepoll.php',$contact_id); + \Zotlabs\Daemon\Master::Summon(array('Onepoll',$contact_id)); } @@ -414,7 +414,7 @@ class Connedit extends \Zotlabs\Web\Controller { if($cmd === 'update') { // pull feed and consume it, which should subscribe to the hub. - proc_run('php',"include/poller.php","$contact_id"); + \Zotlabs\Daemon\Master::Summon(array('Poller',$contact_id)); goaway(z_root() . '/connedit/' . $contact_id); } @@ -427,7 +427,7 @@ class Connedit extends \Zotlabs\Web\Controller { else { // if you are on a different network we'll force a refresh of the connection basic info - proc_run('php','include/notifier.php','permission_update',$contact_id); + Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id)); } goaway(z_root() . '/connedit/' . $contact_id); } diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 9519ca11b..3440e0727 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -232,7 +232,7 @@ class Events extends \Zotlabs\Web\Controller { } if($share) - proc_run('php',"include/notifier.php","event","$item_id"); + \Zotlabs\Daemon\Master(array('Notifier','event',$item_id)); } diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index 1701328bf..1df382a89 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -53,14 +53,13 @@ class Follow extends \Zotlabs\Web\Controller { // If we can view their stream, pull in some posts if(($result['abook']['abook_their_perms'] & PERMS_R_STREAM) || ($result['abook']['xchan_network'] === 'rss')) - proc_run('php','include/onepoll.php',$result['abook']['abook_id']); + \Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id'])); goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); } - function get() { - + function get() { if(! local_channel()) { return login(); } diff --git a/Zotlabs/Module/Fsuggest.php b/Zotlabs/Module/Fsuggest.php index 143fd34e1..a371f9d21 100644 --- a/Zotlabs/Module/Fsuggest.php +++ b/Zotlabs/Module/Fsuggest.php @@ -61,7 +61,7 @@ class Fsuggest extends \Zotlabs\Web\Controller { intval($fsuggest_id), intval(local_channel()) ); - proc_run('php', 'include/notifier.php', 'suggest' , $fsuggest_id); + \Zotlabs\Daemon\Master::Summon(array('Notifier', 'suggest' , $fsuggest_id)); } info( t('Friend suggestion sent.') . EOL); diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index dadbf8ff1..4e99155fb 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -496,11 +496,11 @@ class Import extends \Zotlabs\Web\Controller { // send out refresh requests // notify old server that it may no longer be primary. - proc_run('php','include/notifier.php','location',$channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id'])); // This will indirectly perform a refresh_all *and* update the directory - proc_run('php', 'include/directory.php', $channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id'])); notice( t('Import completed.') . EOL); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 93570fdec..ff8510ade 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -901,7 +901,7 @@ class Item extends \Zotlabs\Web\Controller { } } if(! $nopush) - proc_run('php', "include/notifier.php", 'edit_post', $post_id); + \Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_post', $post_id)); if((x($_REQUEST,'return')) && strlen($return_path)) { logger('return: ' . $return_path); @@ -1008,7 +1008,7 @@ class Item extends \Zotlabs\Web\Controller { call_hooks('post_local_end', $datarray); if(! $nopush) - proc_run('php', 'include/notifier.php', $notify_type, $post_id); + \Zotlabs\Daemon\Master::Summon(array('Notifier', $notify_type, $post_id)); logger('post_complete'); diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index ac8791950..3ef67ddcc 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -346,7 +346,7 @@ class Like extends \Zotlabs\Web\Controller { // drop_item was not done interactively, so we need to invoke the notifier // in order to push the changes to connections - proc_run('php','include/notifier.php','drop',$rr['id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id'])); } @@ -531,7 +531,7 @@ class Like extends \Zotlabs\Web\Controller { } - proc_run('php',"include/notifier.php","like","$post_id"); + \Zotlabs\Daemon\Master::Summon(array('Notifier','like',$post_id)); if($interactive) { notice( t('Action completed.') . EOL); diff --git a/Zotlabs/Module/Locs.php b/Zotlabs/Module/Locs.php index 4b5d58df5..4b1e3ffe2 100644 --- a/Zotlabs/Module/Locs.php +++ b/Zotlabs/Module/Locs.php @@ -34,7 +34,7 @@ class Locs extends \Zotlabs\Web\Controller { dbesc($channel['channel_hash']) ); - proc_run('php','include/notifier.php','location',$channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id'])); return; } } @@ -72,7 +72,7 @@ class Locs extends \Zotlabs\Web\Controller { intval($hubloc_id), dbesc($channel['channel_hash']) ); - proc_run('php','include/notifier.php','location',$channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id'])); return; } } @@ -91,7 +91,7 @@ class Locs extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); if($_REQUEST['sync']) { - proc_run('php','include/notifier.php','location',$channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id'])); info( t('Syncing locations') . EOL); goaway(z_root() . '/locs'); } diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index 35cb3b9bf..e6487d681 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -173,7 +173,7 @@ class Mail extends \Zotlabs\Web\Controller { build_sync_packet(local_channel(),array('mail' => encode_mail($x[0],true))); } - proc_run('php','include/notifier.php','mail',intval(argv(3))); + \Zotlabs\Daemon\Master::Summon(array('Notifier','mail',intval(argv(3)))); if($r) { info( t('Message recalled.') . EOL ); diff --git a/Zotlabs/Module/Mood.php b/Zotlabs/Module/Mood.php index b1007fd06..d1bd44526 100644 --- a/Zotlabs/Module/Mood.php +++ b/Zotlabs/Module/Mood.php @@ -97,7 +97,7 @@ class Mood extends \Zotlabs\Web\Controller { $item_id = $post['item_id']; if($item_id) { - proc_run('php',"include/notifier.php","activity", $item_id); + \Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $item_id)); } call_hooks('post_local_end', $arr); diff --git a/Zotlabs/Module/Prate.php b/Zotlabs/Module/Prate.php index 65bbcca9a..2a8539ed0 100644 --- a/Zotlabs/Module/Prate.php +++ b/Zotlabs/Module/Prate.php @@ -85,7 +85,7 @@ class Prate extends \Zotlabs\Web\Controller { $record = $z[0]['xlink_id']; } if($record) { - proc_run('php','include/ratenotif.php','rating',$record); + \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record)); } json_return_and_die(array('result' => true));; diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 8f879503c..efcc7bece 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -179,7 +179,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); // Update directory in background - proc_run('php',"include/directory.php",$channel['channel_id']); + \Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id'])); // Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures' @@ -311,7 +311,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { ); profile_photo_set_profile_perms(); //Reset default photo permissions to public - proc_run('php','include/directory.php',local_channel()); + \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); goaway(z_root() . '/profiles'); } diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 72edf396f..3db089e53 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller { if($is_default) { // reload the info for the sidebar widget - why does this not work? profile_load($a,$channel['channel_address']); - proc_run('php','include/directory.php',local_channel()); + \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); } } } diff --git a/Zotlabs/Module/Rate.php b/Zotlabs/Module/Rate.php index e2c05b6d4..da23b840e 100644 --- a/Zotlabs/Module/Rate.php +++ b/Zotlabs/Module/Rate.php @@ -102,14 +102,12 @@ class Rate extends \Zotlabs\Web\Controller { } if($record) { - proc_run('php','include/ratenotif.php','rating',$record); + \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record)); } } - - - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL); diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index f588e2824..3d37faab6 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -543,7 +543,7 @@ class Settings extends \Zotlabs\Web\Controller { ); } - proc_run('php','include/directory.php',local_channel()); + \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); build_sync_packet(); diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index 879cf3dbb..26d1c58ea 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -131,7 +131,7 @@ class Tagger extends \Zotlabs\Web\Controller { $ret = post_activity_item($arr); if($ret['success']) - proc_run('php','include/notifier.php','tag',$ret['activity']['id']); + \Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id'])); killme(); -- cgit v1.2.3 From 019250eff879d86577157ad6136a3613b61cacb8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 22:13:20 -0700 Subject: consolidate include/*_selectors.php (not touching acl_selectors for the moment, as it will likely end up with a different disposition) --- Zotlabs/Module/Connections.php | 2 +- Zotlabs/Module/Connedit.php | 4 +--- Zotlabs/Module/Profiles.php | 3 ++- Zotlabs/Module/Thing.php | 2 +- Zotlabs/Module/Viewconnections.php | 3 ++- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php index 564f4e527..ebf8ff8e6 100644 --- a/Zotlabs/Module/Connections.php +++ b/Zotlabs/Module/Connections.php @@ -3,7 +3,7 @@ namespace Zotlabs\Module; require_once('include/Contact.php'); require_once('include/socgraph.php'); -require_once('include/contact_selectors.php'); +require_once('include/selectors.php'); require_once('include/group.php'); require_once('include/contact_widgets.php'); require_once('include/zot.php'); diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 0820c76bf..8bf4ac9b4 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -9,7 +9,7 @@ namespace Zotlabs\Module; require_once('include/Contact.php'); require_once('include/socgraph.php'); -require_once('include/contact_selectors.php'); +require_once('include/selectors.php'); require_once('include/group.php'); require_once('include/contact_widgets.php'); require_once('include/zot.php'); @@ -583,8 +583,6 @@ class Connedit extends \Zotlabs\Web\Controller { if(intval($contact['abook_self'])) $self = true; - require_once('include/contact_selectors.php'); - $tpl = get_markup_template("abook_edit.tpl"); if(feature_enabled(local_channel(),'affinity')) { diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 3db089e53..e738d0c96 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -2,6 +2,7 @@ namespace Zotlabs\Module; require_once('include/identity.php'); +require_once('include/selectors.php'); class Profiles extends \Zotlabs\Web\Controller { @@ -625,7 +626,7 @@ class Profiles extends \Zotlabs\Web\Controller { return; } - require_once('include/profile_selectors.php'); + require_once('include/selectors.php'); $editselect = 'none'; diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index e95ec53f6..6fc5219d8 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -7,7 +7,7 @@ namespace Zotlabs\Module; require_once('include/items.php'); require_once('include/security.php'); -require_once('include/contact_selectors.php'); +require_once('include/selectors.php'); require_once('include/acl_selectors.php'); diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php index 726ef043b..a9445cdeb 100644 --- a/Zotlabs/Module/Viewconnections.php +++ b/Zotlabs/Module/Viewconnections.php @@ -1,6 +1,7 @@ Date: Fri, 20 May 2016 22:16:57 -0700 Subject: remove redundant include --- Zotlabs/Module/Profiles.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index e738d0c96..e899abb3f 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -626,9 +626,6 @@ class Profiles extends \Zotlabs\Web\Controller { return; } - require_once('include/selectors.php'); - - $editselect = 'none'; // if(feature_enabled(local_channel(),'richtext')) // $editselect = 'textareas'; -- cgit v1.2.3 From d8ace38041ad3ef161cf9c727c94b6ce2a00ce75 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 22:52:47 -0700 Subject: rework the conversation object stuff at a high level - still needs a bit of refactoring --- Zotlabs/Module/Dav.php | 2 +- Zotlabs/Module/Help.php | 2 +- Zotlabs/Module/Linkinfo.php | 2 +- Zotlabs/Module/Pubsites.php | 2 +- Zotlabs/Module/Rsd_xml.php | 2 +- Zotlabs/Module/Settings.php | 2 +- Zotlabs/Module/Siteinfo.php | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index d65ad3405..2fddabe19 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -64,7 +64,7 @@ class Dav extends \Zotlabs\Web\Controller { $auth = new \Zotlabs\Storage\BasicAuth(); - $auth->setRealm(ucfirst(\Zotlabs\Project\System::get_platform_name()) . 'WebDAV'); + $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV'); // $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { // if(account_verify_password($userName,$password)) diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php index 4842c56c6..cc46c550b 100644 --- a/Zotlabs/Module/Help.php +++ b/Zotlabs/Module/Help.php @@ -37,7 +37,7 @@ class Help extends \Zotlabs\Web\Controller { $path = trim(substr($dirname,4),'/'); $o .= '
  • ' . ucwords(str_replace('_',' ',notags($fname))) . '
    ' . - str_replace('$Projectname',\Zotlabs\Project\System::get_platform_name(),substr($rr['text'],0,200)) . '...

  • '; + str_replace('$Projectname',\Zotlabs\Lib\System::get_platform_name(),substr($rr['text'],0,200)) . '...

    '; } $o .= ''; diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php index ef34bb465..e1a3a6abe 100644 --- a/Zotlabs/Module/Linkinfo.php +++ b/Zotlabs/Module/Linkinfo.php @@ -115,7 +115,7 @@ class Linkinfo extends \Zotlabs\Web\Controller { // If this is a Red site, use zrl rather than url so they get zids sent to them by default - if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Project\System::get_platform_name() . ' ') === 0)) + if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Lib\System::get_platform_name() . ' ') === 0)) $template = str_replace('url','zrl',$template); if($siteinfo["title"] == "") { diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index 55f2c0ad6..31bca5f30 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -31,7 +31,7 @@ class Pubsites extends \Zotlabs\Web\Controller { $o .= '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Software') . '' . t('Ratings') . '
    ' . t('Rate') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . ' ' . t('View') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . '' . ucwords($jj['project']) . ' ' . t('View') . '
    '; if($j['sites']) { foreach($j['sites'] as $jj) { - if(strpos($jj['project'],\Zotlabs\Project\System::get_platform_name()) === false) + if(strpos($jj['project'],\Zotlabs\Lib\System::get_platform_name()) === false) continue; $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); $rate_links = ((local_channel()) ? '' : ''); diff --git a/Zotlabs/Module/Rsd_xml.php b/Zotlabs/Module/Rsd_xml.php index 06af39ad1..e5059834b 100644 --- a/Zotlabs/Module/Rsd_xml.php +++ b/Zotlabs/Module/Rsd_xml.php @@ -6,7 +6,7 @@ class Rsd_xml extends \Zotlabs\Web\Controller { function init() { header ("Content-Type: text/xml"); echo replace_macros(get_markup_template('rsd.tpl'),array( - '$project' => \Zotlabs\Project\System::get_platform_name(), + '$project' => \Zotlabs\Lib\System::get_platform_name(), '$baseurl' => z_root(), '$apipath' => z_root() . '/api/' )); diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 3d37faab6..32ef89f68 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -1047,7 +1047,7 @@ class Settings extends \Zotlabs\Web\Controller { '$h_prv' => t('Security and Privacy Settings'), '$permissions_set' => $permissions_set, - '$server_role' => \Zotlabs\Project\System::get_server_role(), + '$server_role' => \Zotlabs\Lib\System::get_server_role(), '$perms_set_msg' => t('Your permissions are already configured. Click to view/adjust'), '$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online'), $yes_no), diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php index c65277004..41f6e9f0b 100644 --- a/Zotlabs/Module/Siteinfo.php +++ b/Zotlabs/Module/Siteinfo.php @@ -16,10 +16,10 @@ class Siteinfo extends \Zotlabs\Web\Controller { function get() { if(! get_config('system','hidden_version_siteinfo')) { - $version = sprintf( t('Version %s'), \Zotlabs\Project\System::get_project_version()); + $version = sprintf( t('Version %s'), \Zotlabs\Lib\System::get_project_version()); if(@is_dir('.git') && function_exists('shell_exec')) { $commit = @shell_exec('git log -1 --format="%h"'); - $tag = \Zotlabs\Project\System::get_std_version(); // @shell_exec('git describe --tags --abbrev=0'); + $tag = \Zotlabs\Lib\System::get_std_version(); // @shell_exec('git describe --tags --abbrev=0'); } if(! isset($commit) || strlen($commit) > 16) $commit = ''; -- cgit v1.2.3 From b66bacff9f7ea61004ab07f9d3a5c1a216de196d Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 21 May 2016 14:52:07 +0200 Subject: possible better fix for #385 --- Zotlabs/Module/Cloud.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index f3767e3f0..2784d2703 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -100,9 +100,13 @@ class Cloud extends \Zotlabs\Web\Controller { // require_once('\Zotlabs\Storage/QuotaPlugin.php'); // $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth)); + ob_start(); + // All we need to do now, is to fire up the server $server->exec(); - + + ob_end_flush(); + killme(); } -- cgit v1.2.3 From 4979a451207c7072785c114a09fdd394f2a97734 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sat, 21 May 2016 15:14:33 +0200 Subject: revert fix for #385 --- Zotlabs/Module/Cloud.php | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 2784d2703..d9b0c47d4 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -100,13 +100,9 @@ class Cloud extends \Zotlabs\Web\Controller { // require_once('\Zotlabs\Storage/QuotaPlugin.php'); // $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth)); - ob_start(); - // All we need to do now, is to fire up the server $server->exec(); - ob_end_flush(); - killme(); } -- cgit v1.2.3 From 598baa1b32b59b187fbdc7012d23831208d0ebbd Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 12:55:17 -0400 Subject: Moved git repository storage to store/[data]/git to avoid collision with a channel named git. Fixed bug where temp repo folder was never created. --- Zotlabs/Module/Admin.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 0a167b273..42a91107d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1735,7 +1735,7 @@ class Admin extends \Zotlabs\Web\Controller { } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } - $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { @@ -1748,7 +1748,7 @@ class Admin extends \Zotlabs\Web\Controller { } } } - $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; + $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); @@ -1785,7 +1785,7 @@ class Admin extends \Zotlabs\Web\Controller { } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } - $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { @@ -1798,7 +1798,7 @@ class Admin extends \Zotlabs\Web\Controller { } } } - $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; + $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); @@ -1818,7 +1818,7 @@ class Admin extends \Zotlabs\Web\Controller { if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; - $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { @@ -1846,7 +1846,7 @@ class Admin extends \Zotlabs\Web\Controller { json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); } $repoDir = $addonDir . '/' . $repoName; - $tempRepoBaseDir = __DIR__ . '/../../store/git/sys/temp/'; + $tempRepoBaseDir = __DIR__ . '/../../store/[data]/git/sys/temp/'; $tempAddonDir = $tempRepoBaseDir . $repoName; if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { @@ -1880,9 +1880,9 @@ class Admin extends \Zotlabs\Web\Controller { if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; - $extendDir = __DIR__ . '/../../store/git/sys/extend'; + $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; - $tempAddonDir = __DIR__ . '/../../store/git/sys/temp'; + $tempAddonDir = __DIR__ . '/../../store/[data]/git/sys/temp'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); @@ -1894,6 +1894,12 @@ class Admin extends \Zotlabs\Web\Controller { } } } + if (!is_dir($tempAddonDir)) { + if (!mkdir($tempAddonDir, 0770, true)) { + logger('Error creating temp plugin repo folder: ' . $extendDir); + json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $extendDir, 'success' => false)); + } + } $repoName = null; if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; -- cgit v1.2.3 From 7a526fa8a9934fb6f193a11815bcb03490acb2c6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 12:58:05 -0400 Subject: Temp repo folder error message correction --- Zotlabs/Module/Admin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 42a91107d..cd6e45e9f 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1896,8 +1896,8 @@ class Admin extends \Zotlabs\Web\Controller { } if (!is_dir($tempAddonDir)) { if (!mkdir($tempAddonDir, 0770, true)) { - logger('Error creating temp plugin repo folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $extendDir, 'success' => false)); + logger('Error creating temp plugin repo folder: ' . $tempAddonDir); + json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false)); } } $repoName = null; -- cgit v1.2.3 From c6aa42773a17d53b4572488967b99666ab97ef97 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 14:56:42 -0400 Subject: Trying to fix wiki branch starting fresh from dev --- Zotlabs/Module/Wiki.php | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Zotlabs/Module/Wiki.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php new file mode 100644 index 000000000..ca0dcff82 --- /dev/null +++ b/Zotlabs/Module/Wiki.php @@ -0,0 +1,113 @@ + 1) + $which = argv(1); // if the channel name is in the URL, use that + if(! $which) { // if no channel name was provided, assume the current logged in channel + if(local_channel()) { + $channel = \App::get_channel(); + if($channel && $channel['channel_address']) + $which = $channel['channel_address']; + goaway(z_root().'/wiki/'.$which); + } + } + if(! $which) { + notice( t('You must be logged in to see this page.') . EOL ); + return; + } + } + + function get() { + require_once('include/acl_selectors.php'); + if(local_channel()) { + $channel = \App::get_channel(); + } + + // TODO: check observer permissions + //$ob = \App::get_observer(); + //$observer = get_observer_hash(); + + // Obtain the default permission settings of the channel + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + // Initialize the ACL to the channel default permissions + $x = array( + 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'acl' => populate_acl($channel_acl), + 'bang' => '' + ); + $o .= replace_macros(get_markup_template('wiki.tpl'),array( + '$channel' => $channel['channel_address'], + '$lockstate' => $x['lockstate'], + '$acl' => $x['acl'], + '$bang' => $x['bang'], + '$content' => '# Start your wiki', + '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), + '$pageName' => array('pageName', t('Enter the name of the new page:'), '', '') + )); + head_add_js('library/ace/ace.js'); + return $o; + } + + function post() { + + // TODO: Implement wiki API + + // Render mardown-formatted text in HTML + if((argc() > 2) && (argv(2) === 'preview')) { + $content = $_POST['content']; + logger('preview content: ' . $content); + //require_once('library/parsedown/Parsedown.php'); + $parsedown = new Parsedown(); + $html = $parsedown->text($content); + json_return_and_die(array('html' => $html, 'success' => true)); + } + + // Create a new wiki + if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { + // Determine if observer has permission to create wiki + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $which = argv(1); + $channel = get_channel_by_nick($which); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), get_observer_hash()); + + if (!$perms['write_wiki']) { + notice(t('Permission denied.') . EOL); + json_return_and_die(array('success' => false)); + } + } + $name = escape_tags(urlencode($_REQUEST['name'])); //Get new wiki name + // Get ACL for permissions + $acl = new Zotlabs\Access\AccessList($channel); + $acl->set_from_array($_REQUEST); + + $r = wiki_create_wiki($channel, $name, $acl); + if ($r['success']) { + json_return_and_die(array('success' => true)); + } else { + json_return_and_die(array('success' => false)); + } + } + + + json_return_and_die(array('success' => false)); + + + + } +} -- cgit v1.2.3 From 049147a9d78b981482297c3daf48c67f31754259 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 19:02:23 -0400 Subject: Successful new wiki git repo and item table record --- Zotlabs/Module/Wiki.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index ca0dcff82..c4546e5ef 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -62,6 +62,7 @@ class Wiki extends \Zotlabs\Web\Controller { } function post() { + require_once('include/wiki.php'); // TODO: Implement wiki API @@ -77,37 +78,39 @@ class Wiki extends \Zotlabs\Web\Controller { // Create a new wiki if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { + $which = argv(1); // Determine if observer has permission to create wiki if (local_channel()) { $channel = \App::get_channel(); } else { - $which = argv(1); $channel = get_channel_by_nick($which); + $observer_hash = get_observer_hash(); // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), get_observer_hash()); + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); if (!$perms['write_wiki']) { notice(t('Permission denied.') . EOL); json_return_and_die(array('success' => false)); } } - $name = escape_tags(urlencode($_REQUEST['name'])); //Get new wiki name + $name = escape_tags(urlencode($_REQUEST['wikiName'])); //Get new wiki name + if($name === '') { + notice('Error creating wiki. Invalid name.'); + goaway('/wiki'); + } // Get ACL for permissions - $acl = new Zotlabs\Access\AccessList($channel); + $acl = new \Zotlabs\Access\AccessList($channel); $acl->set_from_array($_REQUEST); - - $r = wiki_create_wiki($channel, $name, $acl); + $r = wiki_create_wiki($channel, $observer_hash, $name, $acl); if ($r['success']) { - json_return_and_die(array('success' => true)); + goaway('/wiki/'.$which.'/'.$name); } else { - json_return_and_die(array('success' => false)); + notice('Error creating wiki'); + goaway('/wiki'); } } - json_return_and_die(array('success' => false)); - - } } -- cgit v1.2.3 From ed56b6e67b27900e2ff413a7781c9095aa8251a0 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 21 May 2016 18:02:14 -0700 Subject: first cut at zot-finger request signatures --- Zotlabs/Module/Probe.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php index 79abe9819..dda792131 100644 --- a/Zotlabs/Module/Probe.php +++ b/Zotlabs/Module/Probe.php @@ -20,17 +20,17 @@ class Probe extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); $addr = trim($_GET['addr']); $do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false); - $res = zot_finger($addr,$channel,false); + + $j = \Zotlabs\Zot\Finger::run($addr,$channel,false); + + // $res = zot_finger($addr,$channel,false); + $o .= '
    ';
    -			if($res['success'])
    -				$j = json_decode($res['body'],true);
    -			else {
    +			if(! $j['success']) {
     				$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
     				$o .= "https connection failed. Trying again with auto failover to http.\r\n\r\n";
    -				$res = zot_finger($addr,$channel,true);
    -				if($res['success'])
    -					$j = json_decode($res['body'],true);
    -				else
    +				$j = \Zotlabs\Zot\Finger::run($addr,$channel,true);
    +				if(! $j['success']) 
     					$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
     	
     			}
    -- 
    cgit v1.2.3
    
    
    From 1cb311cef9848178780e3fd52814bf3a64ed0556 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Sat, 21 May 2016 18:18:33 -0700
    Subject: finish updating zot_finger instances
    
    ---
     Zotlabs/Module/Chanview.php |  9 +++------
     Zotlabs/Module/Magic.php    |  8 +++-----
     Zotlabs/Module/Mail.php     |  7 +++----
     Zotlabs/Module/Regdir.php   | 13 +++++--------
     4 files changed, 14 insertions(+), 23 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php
    index f70444816..36fbbb864 100644
    --- a/Zotlabs/Module/Chanview.php
    +++ b/Zotlabs/Module/Chanview.php
    @@ -62,18 +62,15 @@ class Chanview extends \Zotlabs\Web\Controller {
     			}
     	
     			if($_REQUEST['address']) {
    -				$ret = zot_finger($_REQUEST['address'],null);
    -				if($ret['success']) {
    -					$j = json_decode($ret['body'],true);
    -					if($j)
    -						import_xchan($j);
    +				$j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
    +				if($j['success']) {
    +					import_xchan($j);
     					$r = q("select * from xchan where xchan_addr = '%s' limit 1",
     						dbesc($_REQUEST['address'])
     					);
     					if($r)
     						\App::$poi = $r[0];
     				}
    -	
     			}
     		}
     	
    diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php
    index 63db4a317..6798f72a9 100644
    --- a/Zotlabs/Module/Magic.php
    +++ b/Zotlabs/Module/Magic.php
    @@ -47,11 +47,9 @@ class Magic extends \Zotlabs\Web\Controller {
     			 *
     			 */
     	
    -			$ret = zot_finger((($addr) ? $addr : '[system]@' . $parsed['host']),null);
    -			if($ret['success']) {
    -				$j = json_decode($ret['body'],true);
    -				if($j)
    -					import_xchan($j);
    +			$j = \Zotlabs\Zot\Finger::run((($addr) ? $addr : '[system]@' . $parsed['host']),null);
    +			if($j['success']) {
    +				import_xchan($j);
     	
     				// Now try again
     	
    diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php
    index e6487d681..3dbfa8d71 100644
    --- a/Zotlabs/Module/Mail.php
    +++ b/Zotlabs/Module/Mail.php
    @@ -32,17 +32,16 @@ class Mail extends \Zotlabs\Web\Controller {
     		if(! $recipient) {
     			$channel = \App::get_channel();
     	
    -			$ret = zot_finger($rstr,$channel);
    +			$j = \Zotlabs\Zot\Finger::run($rstr,$channel);
     	
    -			if(! $ret['success']) {
    +			if(! $j['success']) {
     				notice( t('Unable to lookup recipient.') . EOL);
     				return;
     			} 
    -			$j = json_decode($ret['body'],true);
     	
     			logger('message_post: lookup: ' . $url . ' ' . print_r($j,true));
     	
    -			if(! ($j['success'] && $j['guid'])) {
    +			if(! $j['guid']) {
     				notice( t('Unable to communicate with requested channel.'));
     				return;
     			}
    diff --git a/Zotlabs/Module/Regdir.php b/Zotlabs/Module/Regdir.php
    index 65f8daf67..48a7cc16d 100644
    --- a/Zotlabs/Module/Regdir.php
    +++ b/Zotlabs/Module/Regdir.php
    @@ -60,14 +60,11 @@ class Regdir extends \Zotlabs\Web\Controller {
     				json_return_and_die($result);
     			}
     	
    -			$f = zot_finger('[system]@' . $m['host']);
    -			if($f['success']) {
    -				$j = json_decode($f['body'],true);
    -				if($j['success'] && $j['guid']) {
    -					$x = import_xchan($j);
    -					if($x['success']) {
    -						$result['success'] = true;
    -					}
    +			$j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']);
    +			if($j['success'] && $j['guid']) {
    +				$x = import_xchan($j);
    +				if($x['success']) {
    +					$result['success'] = true;
     				}
     			}
     	
    -- 
    cgit v1.2.3
    
    
    From a36bef7979aecd72751d319f85b7037991979e35 Mon Sep 17 00:00:00 2001
    From: Andrew Manning 
    Date: Sat, 21 May 2016 21:55:09 -0400
    Subject: List of wikis populates with links according to observer permissions.
    
    ---
     Zotlabs/Module/Wiki.php | 15 +++++++++++++++
     1 file changed, 15 insertions(+)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
    index c4546e5ef..53a3eb26b 100644
    --- a/Zotlabs/Module/Wiki.php
    +++ b/Zotlabs/Module/Wiki.php
    @@ -48,7 +48,22 @@ class Wiki extends \Zotlabs\Web\Controller {
             'acl' => populate_acl($channel_acl),
             'bang' => ''
         );
    +//		$wikiheader = t('Wiki Sandbox');
    +//		$hide_editor = false;
    +		if(argc()<3) {
    +			$wikiheader = t('Wiki Sandbox');
    +			$hide_editor = false;
    +		} elseif (argc()<4) {
    +			$wikiheader = 'Empty wiki: ' . rawurldecode(argv(2)); // show wiki name
    +			$hide_editor = true;
    +		} elseif (argc()<5) {
    +			$wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3));	// show wiki name and page
    +			$hide_editor = false;
    +		}
    +		
     		$o .= replace_macros(get_markup_template('wiki.tpl'),array(
    +			'$wikiheader' => $wikiheader,
    +			'$hideEditor' => $hide_editor,
     			'$channel' => $channel['channel_address'],
     			'$lockstate' => $x['lockstate'],
     			'$acl' => $x['acl'],
    -- 
    cgit v1.2.3
    
    
    From de006771c7fe92a889d759c2c75c1473c420ad47 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Sun, 22 May 2016 16:54:30 -0700
    Subject: renamed include files identity.php (channel.php) and Contact.php
     (connections.php)
    
    ---
     Zotlabs/Module/Admin.php           |  4 ----
     Zotlabs/Module/Blocks.php          |  2 +-
     Zotlabs/Module/Cal.php             |  2 --
     Zotlabs/Module/Chanview.php        |  2 --
     Zotlabs/Module/Connect.php         |  2 +-
     Zotlabs/Module/Connections.php     |  2 +-
     Zotlabs/Module/Connedit.php        |  3 +--
     Zotlabs/Module/Cover_photo.php     |  2 +-
     Zotlabs/Module/Display.php         |  4 ++--
     Zotlabs/Module/Editblock.php       |  2 +-
     Zotlabs/Module/Editlayout.php      |  2 +-
     Zotlabs/Module/Editwebpage.php     |  2 +-
     Zotlabs/Module/Getfile.php         |  1 -
     Zotlabs/Module/Import.php          |  4 ++--
     Zotlabs/Module/Item.php            |  2 +-
     Zotlabs/Module/Layouts.php         |  2 +-
     Zotlabs/Module/Mail.php            |  7 +------
     Zotlabs/Module/Menu.php            |  2 +-
     Zotlabs/Module/Message.php         |  2 --
     Zotlabs/Module/Network.php         |  2 +-
     Zotlabs/Module/New_channel.php     |  2 +-
     Zotlabs/Module/Oep.php             |  4 ++--
     Zotlabs/Module/Photos.php          |  2 +-
     Zotlabs/Module/Profile_photo.php   |  2 +-
     Zotlabs/Module/Profiles.php        |  4 ++--
     Zotlabs/Module/Profperm.php        |  2 +-
     Zotlabs/Module/Pubstream.php       |  2 +-
     Zotlabs/Module/Randprof.php        |  1 -
     Zotlabs/Module/Register.php        |  2 +-
     Zotlabs/Module/Removeaccount.php   | 11 +++--------
     Zotlabs/Module/Removeme.php        |  5 +----
     Zotlabs/Module/Search.php          |  2 +-
     Zotlabs/Module/Settings.php        |  2 +-
     Zotlabs/Module/Setup.php           |  2 +-
     Zotlabs/Module/Uexport.php         |  2 +-
     Zotlabs/Module/Viewconnections.php |  4 +---
     Zotlabs/Module/Wall_attach.php     |  2 +-
     Zotlabs/Module/Wall_upload.php     |  2 +-
     Zotlabs/Module/Webpages.php        |  2 +-
     39 files changed, 39 insertions(+), 67 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php
    index cd6e45e9f..172b109c8 100644
    --- a/Zotlabs/Module/Admin.php
    +++ b/Zotlabs/Module/Admin.php
    @@ -902,7 +902,6 @@ class Admin extends \Zotlabs\Web\Controller {
     		}
     		// account delete button was submitted
     		if (x($_POST, 'page_users_delete')) {
    -			require_once('include/Contact.php');
     			foreach ($users as $uid){
     				account_remove($uid, true, false);
     			}
    @@ -951,7 +950,6 @@ class Admin extends \Zotlabs\Web\Controller {
     			switch (argv(2)){
     				case 'delete':
     					// delete user
    -					require_once('include/Contact.php');
     					account_remove($uid,true,false);
     	
     					notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
    @@ -1096,7 +1094,6 @@ class Admin extends \Zotlabs\Web\Controller {
     			notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
     		}
     		if (x($_POST,'page_channels_delete')){
    -			require_once("include/Contact.php");
     			foreach($channels as $uid){
     				channel_remove($uid,true);
     			}
    @@ -1128,7 +1125,6 @@ class Admin extends \Zotlabs\Web\Controller {
     				case "delete":{
     					check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
     					// delete channel
    -					require_once("include/Contact.php");
     					channel_remove($uid,true);
     					
     					notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL);
    diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php
    index ed702befb..32650a090 100644
    --- a/Zotlabs/Module/Blocks.php
    +++ b/Zotlabs/Module/Blocks.php
    @@ -1,7 +1,7 @@
     disabled())) {
     				$r = null;
     	
    -				require_once('include/identity.php');
    +				require_once('include/channel.php');
     				$sys = get_sys_channel();
     				$sysid = $sys['channel_id'];
     	
    @@ -233,7 +233,7 @@ class Display extends \Zotlabs\Web\Controller {
     		elseif($update && !$load) {
     			$r = null;
     	
    -			require_once('include/identity.php');
    +			require_once('include/channel.php');
     			$sys = get_sys_channel();
     			$sysid = $sys['channel_id'];
     	
    diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php
    index a79962033..fb86557f2 100644
    --- a/Zotlabs/Module/Editblock.php
    +++ b/Zotlabs/Module/Editblock.php
    @@ -1,7 +1,7 @@
      1) {
     			$channel = \App::get_channel();
     	
    -			require_once('include/identity.php');
    +			require_once('include/channel.php');
     	
     			if(argc() > 1 && intval(argv(1)) > 1900) {
     				$year = intval(argv(1));
    diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php
    index a9445cdeb..d58c431e5 100644
    --- a/Zotlabs/Module/Viewconnections.php
    +++ b/Zotlabs/Module/Viewconnections.php
    @@ -2,8 +2,6 @@
     namespace Zotlabs\Module;
     
     require_once('include/selectors.php');
    -require_once('include/Contact.php');
    -
     
     class Viewconnections extends \Zotlabs\Web\Controller {
     
    @@ -16,7 +14,7 @@ class Viewconnections extends \Zotlabs\Web\Controller {
     			profile_load($a,argv(1));
     	}
     	
    -		function get() {
    +	function get() {
     	
     		if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
     			notice( t('Public access denied.') . EOL);
    diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php
    index 5bdecfa75..9a1019ddb 100644
    --- a/Zotlabs/Module/Wall_attach.php
    +++ b/Zotlabs/Module/Wall_attach.php
    @@ -2,7 +2,7 @@
     namespace Zotlabs\Module;
     
     require_once('include/attach.php');
    -require_once('include/identity.php');
    +require_once('include/channel.php');
     require_once('include/photos.php');
     
     
    diff --git a/Zotlabs/Module/Wall_upload.php b/Zotlabs/Module/Wall_upload.php
    index fff3ed03a..3868cb14e 100644
    --- a/Zotlabs/Module/Wall_upload.php
    +++ b/Zotlabs/Module/Wall_upload.php
    @@ -2,7 +2,7 @@
     namespace Zotlabs\Module;
     
     require_once('include/photo/photo_driver.php');
    -require_once('include/identity.php');
    +require_once('include/channel.php');
     require_once('include/photos.php');
     
     
    diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php
    index d8adb55b2..bb8d454c8 100644
    --- a/Zotlabs/Module/Webpages.php
    +++ b/Zotlabs/Module/Webpages.php
    @@ -1,7 +1,7 @@
     
    Date: Sun, 22 May 2016 17:52:30 -0700
    Subject: turn the oft-repeated block_public ... check into a function
     observer_prohibited()
    
    ---
     Zotlabs/Module/Acl.php             |   2 +-
     Zotlabs/Module/Cal.php             |   9 +-
     Zotlabs/Module/Channel.php         | 550 +++++++++++++++++++------------------
     Zotlabs/Module/Directory.php       |   4 +-
     Zotlabs/Module/Display.php         |   6 +-
     Zotlabs/Module/Feed.php            |   2 +-
     Zotlabs/Module/Photos.php          |   4 +-
     Zotlabs/Module/Profile.php         |   4 +-
     Zotlabs/Module/Pubstream.php       |   2 +-
     Zotlabs/Module/Ratings.php         |   6 +-
     Zotlabs/Module/Viewconnections.php |   4 +-
     Zotlabs/Module/Zotfeed.php         |   4 +-
     12 files changed, 296 insertions(+), 301 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
    index 5c14ab599..62ac29286 100644
    --- a/Zotlabs/Module/Acl.php
    +++ b/Zotlabs/Module/Acl.php
    @@ -260,7 +260,7 @@ class Acl extends \Zotlabs\Web\Controller {
     	
     	//	logger('navbar_complete');
     	
    -		if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
    +		if(observer_prohibited()) {
     			return;
     		}
     	
    diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php
    index 602a2b5ab..a1adb30e5 100644
    --- a/Zotlabs/Module/Cal.php
    +++ b/Zotlabs/Module/Cal.php
    @@ -11,7 +11,7 @@ require_once('include/items.php');
     class Cal extends \Zotlabs\Web\Controller {
     
     	function init() {
    -		if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
    +		if(observer_prohibited()) {
     			return;
     		}
     	
    @@ -45,13 +45,12 @@ class Cal extends \Zotlabs\Web\Controller {
     	
     	
     	
    -		function get() {
    +	function get() {
     	
    -		if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
    +		if(observer_prohibited()) {
     			return;
     		}
    -	
    -	
    +		
     		$channel = null;
     	
     		if(argc() > 1) {
    diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
    index f55705442..29bfcbc3c 100644
    --- a/Zotlabs/Module/Channel.php
    +++ b/Zotlabs/Module/Channel.php
    @@ -13,353 +13,355 @@ require_once('include/PermissionDescription.php');
     
     class Channel extends \Zotlabs\Web\Controller {
     
    -function init() {
    -
    -	$which = null;
    -	if(argc() > 1)
    -		$which = argv(1);
    -	if(! $which) {
    -		if(local_channel()) {
    -			$channel = \App::get_channel();
    -			if($channel && $channel['channel_address'])
    -			$which = $channel['channel_address'];
    +	function init() {
    +
    +		$which = null;
    +		if(argc() > 1)
    +			$which = argv(1);
    +		if(! $which) {
    +			if(local_channel()) {
    +				$channel = \App::get_channel();
    +				if($channel && $channel['channel_address'])
    +				$which = $channel['channel_address'];
    +			}
    +		}
    +		if(! $which) {
    +			notice( t('You must be logged in to see this page.') . EOL );
    +			return;
     		}
    -	}
    -	if(! $which) {
    -		notice( t('You must be logged in to see this page.') . EOL );
    -		return;
    -	}
     
    -	$profile = 0;
    -	$channel = \App::get_channel();
    +		$profile = 0;
    +		$channel = \App::get_channel();
     
    -	if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
    -		$which = $channel['channel_address'];
    -		$profile = argv(1);		
    -	}
    +		if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
    +			$which = $channel['channel_address'];
    +			$profile = argv(1);		
    +		}
     
    -	\App::$page['htmlhead'] .= '' . "\r\n" ;
    -	\App::$page['htmlhead'] .= '' . "\r\n" ;
    +		\App::$page['htmlhead'] .= '' . "\r\n" ;
    +		\App::$page['htmlhead'] .= '' . "\r\n" ;
     
    -// Not yet ready for prime time
    -//	\App::$page['htmlhead'] .= '' . "\r\n" ;
    -//	\App::$page['htmlhead'] .= '' . "\r\n" ;
    +		// Not yet ready for prime time
    +		//	\App::$page['htmlhead'] .= '' . "\r\n" ;
    +		//	\App::$page['htmlhead'] .= '' . "\r\n" ;
     
    -	// Run profile_load() here to make sure the theme is set before
    -	// we start loading content
    +		// Run profile_load() here to make sure the theme is set before
    +		// we start loading content
     
    -	profile_load($a,$which,$profile);
    +		profile_load($a,$which,$profile);
     
    -}
    +	}
     
    -function get($update = 0, $load = false) {
    +	function get($update = 0, $load = false) {
     
     
    -	if($load)
    -		$_SESSION['loadtime'] = datetime_convert();
    +		if($load)
    +			$_SESSION['loadtime'] = datetime_convert();
     
    -	$checkjs = new \Zotlabs\Web\CheckJS(1);
    +		$checkjs = new \Zotlabs\Web\CheckJS(1);
     
    -	$category = $datequery = $datequery2 = '';
    +		$category = $datequery = $datequery2 = '';
     
    -	$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
    +		$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
     
    -	$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
    -	$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
    +		$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
    +		$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
     
    -	if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
    +		if(observer_prohibited(true)) {			
     			return login();
    -	}
    +		}
     
    -	$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
    -	$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
    +		$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
    +		$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
     
    -	$groups = array();
    +		$groups = array();
     
    -	$o = '';
    +		$o = '';
     
    -	if($update) {
    -		// Ensure we've got a profile owner if updating.
    -		\App::$profile['profile_uid'] = \App::$profile_uid = $update;
    -	}
    -	else {
    -		if(\App::$profile['profile_uid'] == local_channel()) {
    -			nav_set_selected('home');
    +		if($update) {
    +			// Ensure we've got a profile owner if updating.
    +			\App::$profile['profile_uid'] = \App::$profile_uid = $update;
    +		}
    +		else {
    +			if(\App::$profile['profile_uid'] == local_channel()) {
    +				nav_set_selected('home');
    +			}
     		}
    -	}
     
    -	$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
    +		$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
     
    -	$channel = \App::get_channel();
    -	$observer = \App::get_observer();
    -	$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
    +		$channel = \App::get_channel();
    +		$observer = \App::get_observer();
    +		$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
     
    -	$perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
    +		$perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
     
    -	if(! $perms['view_stream']) {
    +		if(! $perms['view_stream']) {
     			// We may want to make the target of this redirect configurable
     			if($perms['view_profile']) {
     				notice( t('Insufficient permissions.  Request redirected to profile page.') . EOL);
     				goaway (z_root() . "/profile/" . \App::$profile['channel_address']);
     			}
    -		notice( t('Permission denied.') . EOL);
    -		return;
    -	}
    +			notice( t('Permission denied.') . EOL);
    +			return;
    +		}
     
     
    -	if(! $update) {
    +		if(! $update) {
     
    -		$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
    +			$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
     
    -		$o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
    +			$o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
     
    -		if($channel && $is_owner) {
    -			$channel_acl = array(
    -				'allow_cid' => $channel['channel_allow_cid'], 
    -				'allow_gid' => $channel['channel_allow_gid'], 
    -				'deny_cid' => $channel['channel_deny_cid'], 
    -				'deny_gid' => $channel['channel_deny_gid']
    -			);
    -		}
    -		else
    -			$channel_acl = array(); 
    -
    -
    -		if($perms['post_wall']) {
    -
    -			$x = array(
    -				'is_owner' => $is_owner,
    -				'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
    -				'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
    -				'nickname' => \App::$profile['channel_address'],
    -				'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
    -				'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
    -				'showacl' => (($is_owner) ? 'yes' : ''),
    -				'bang' => '',
    -				'visitor' => (($is_owner || $observer) ? true : false),
    -				'profile_uid' => \App::$profile['profile_uid'],
    -				'editor_autocomplete' => true,
    -				'bbco_autocomplete' => 'bbcode',
    -				'bbcode' => true
    -        	);
    -
    -        	$o .= status_editor($a,$x);
    -		}
    +			if($channel && $is_owner) {
    +				$channel_acl = array(
    +					'allow_cid' => $channel['channel_allow_cid'], 
    +					'allow_gid' => $channel['channel_allow_gid'], 
    +					'deny_cid' => $channel['channel_deny_cid'], 
    +					'deny_gid' => $channel['channel_deny_gid']
    +				);
    +			}
    +			else
    +				$channel_acl = array(); 
    +
    +
    +			if($perms['post_wall']) {
    +
    +				$x = array(
    +					'is_owner' => $is_owner,
    +					'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
    +					'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
    +					'nickname' => \App::$profile['channel_address'],
    +					'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
    +					'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
    +					'showacl' => (($is_owner) ? 'yes' : ''),
    +					'bang' => '',
    +					'visitor' => (($is_owner || $observer) ? true : false),
    +					'profile_uid' => \App::$profile['profile_uid'],
    +					'editor_autocomplete' => true,
    +					'bbco_autocomplete' => 'bbcode',
    +					'bbcode' => true
    +        		);
    +
    +        		$o .= status_editor($a,$x);
    +			}
     
    -	}
    +		}
     
     
    -	/**
    -	 * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
    -	 */
    +		/**
    +		 * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
    +		 */
     
    -	$item_normal = item_normal();
    -	$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
    +		$item_normal = item_normal();
    +		$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
     
    -	if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
    -		$page_mode = 'list';
    -	else
    -		$page_mode = 'client';
    +		if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
    +			$page_mode = 'list';
    +		else
    +			$page_mode = 'client';
     
    -	$abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
    +		$abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
     
    -	$simple_update = (($update) ? " AND item_unseen = 1 " : '');
    +		$simple_update = (($update) ? " AND item_unseen = 1 " : '');
     
    -	\App::$page['htmlhead'] .= "\r\n" . '' . "\r\n";
    +		\App::$page['htmlhead'] .= "\r\n" . '' . "\r\n";
     		
    -	if($update && $_SESSION['loadtime'])
    -		$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' )  OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
    -	if($load)
    -		$simple_update = '';
    -
    -	if(($update) && (! $load)) {
    -
    -		if ($mid) {
    -			$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
    -				AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
    -				dbesc($mid . '%'),
    -				intval(\App::$profile['profile_uid'])
    -			);
    -		} else {
    -			$r = q("SELECT distinct parent AS `item_id`, created from item
    -				left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
    -				WHERE uid = %d $item_normal
    -				AND item_wall = 1 $simple_update
    -				AND (abook.abook_blocked = 0 or abook.abook_flags is null)
    -				$sql_extra
    -				ORDER BY created DESC",
    -				intval(\App::$profile['profile_uid'])
    -			);
    -			$_SESSION['loadtime'] = datetime_convert();
    -		}
    -
    -	}
    -	else {
    -
    -		if(x($category)) {
    -		        $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
    -		}
    -		if(x($hashtags)) {
    -		        $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
    -		}
    -
    -		if($datequery) {
    -			$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
    -		}
    -		if($datequery2) {
    -			$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
    -		}
    +		if($update && $_SESSION['loadtime'])
    +			$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' )  OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
    +		if($load)
    +			$simple_update = '';
     
    -		$itemspage = get_pconfig(local_channel(),'system','itemspage');
    -		\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
    -		$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
    +		if(($update) && (! $load)) {
     
    -		if($load || ($checkjs->disabled())) {
    -			if ($mid) {
    -				$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
    -					AND item_wall = 1 $sql_extra limit 1",
    -					dbesc($mid),
    +			if($mid) {
    +				$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
    +					AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
    +					dbesc($mid . '%'),
     					intval(\App::$profile['profile_uid'])
     				);
    -				if (! $r) {
    -					notice( t('Permission denied.') . EOL);
    -				}
    -
    -			} else {
    -				$r = q("SELECT distinct id AS item_id, created FROM item 
    -					left join abook on item.author_xchan = abook.abook_xchan
    +			} 
    +			else {
    +				$r = q("SELECT distinct parent AS `item_id`, created from item
    +					left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
     					WHERE uid = %d $item_normal
    -					AND item_wall = 1 and item_thread_top = 1
    -					AND (abook_blocked = 0 or abook.abook_flags is null)
    -					$sql_extra $sql_extra2
    -					ORDER BY created DESC $pager_sql ",
    +					AND item_wall = 1 $simple_update
    +					AND (abook.abook_blocked = 0 or abook.abook_flags is null)
    +					$sql_extra
    +					ORDER BY created DESC",
     					intval(\App::$profile['profile_uid'])
     				);
    +				$_SESSION['loadtime'] = datetime_convert();
     			}
    +
     		}
     		else {
    -			$r = array();
    -		}
    -	}
     
    -	if($r) {
    +			if(x($category)) {
    +			        $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
    +			}
    +			if(x($hashtags)) {
    +			        $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
    +			}
     
    -		$parents_str = ids_to_querystr($r,'item_id');
    - 
    -		$items = q("SELECT `item`.*, `item`.`id` AS `item_id` 
    -			FROM `item`
    -			WHERE `item`.`uid` = %d $item_normal
    -			AND `item`.`parent` IN ( %s )
    -			$sql_extra ",
    -			intval(\App::$profile['profile_uid']),
    -			dbesc($parents_str)
    -		);
    -
    -		xchan_query($items);
    -		$items = fetch_post_tags($items, true);
    -		$items = conv_sort($items,'created');
    -
    -		if ($load && $mid && (! count($items))) {
    -			// This will happen if we don't have sufficient permissions
    -			// to view the parent item (or the item itself if it is toplevel)
    -			notice( t('Permission denied.') . EOL);
    +			if($datequery) {
    +				$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
    +			}
    +			if($datequery2) {
    +				$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
    +			}
    +
    +			$itemspage = get_pconfig(local_channel(),'system','itemspage');
    +			\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
    +			$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
    +
    +			if($load || ($checkjs->disabled())) {
    +				if($mid) {
    +					$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
    +						AND item_wall = 1 $sql_extra limit 1",
    +						dbesc($mid),
    +						intval(\App::$profile['profile_uid'])
    +					);
    +					if (! $r) {
    +						notice( t('Permission denied.') . EOL);
    +					}
    +
    +				} 
    +				else {
    +					$r = q("SELECT distinct id AS item_id, created FROM item 
    +						left join abook on item.author_xchan = abook.abook_xchan
    +						WHERE uid = %d $item_normal
    +						AND item_wall = 1 and item_thread_top = 1
    +						AND (abook_blocked = 0 or abook.abook_flags is null)
    +						$sql_extra $sql_extra2
    +						ORDER BY created DESC $pager_sql ",
    +						intval(\App::$profile['profile_uid'])
    +					);
    +				}
    +			}
    +			else {
    +				$r = array();
    +			}
     		}
     
    -	} else {
    -		$items = array();
    -	}
    +		if($r) {
     
    -	if((! $update) && (! $load)) {
    -
    -		// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
    -		// because browser prefetching might change it on us. We have to deliver it with the page.
    -
    -		$maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height');
    -		if(! $maxheight)
    -			$maxheight = 400;
    -
    -		$o .= '
    ' . "\r\n"; - $o .= "\r\n"; - - \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( - '$baseurl' => z_root(), - '$pgtype' => 'channel', - '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), - '$gid' => '0', - '$cid' => '0', - '$cmin' => '0', - '$cmax' => '0', - '$star' => '0', - '$liked' => '0', - '$conv' => '0', - '$spam' => '0', - '$nouveau' => '0', - '$wall' => '1', - '$fh' => '0', - '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), - '$search' => '', - '$order' => '', - '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), - '$file' => '', - '$cats' => (($category) ? $category : ''), - '$tags' => (($hashtags) ? $hashtags : ''), - '$mid' => $mid, - '$verb' => '', - '$dend' => $datequery, - '$dbegin' => $datequery2 - )); + $parents_str = ids_to_querystr($r,'item_id'); + + $items = q("SELECT `item`.*, `item`.`id` AS `item_id` + FROM `item` + WHERE `item`.`uid` = %d $item_normal + AND `item`.`parent` IN ( %s ) + $sql_extra ", + intval(\App::$profile['profile_uid']), + dbesc($parents_str) + ); + xchan_query($items); + $items = fetch_post_tags($items, true); + $items = conv_sort($items,'created'); - } + if($load && $mid && (! count($items))) { + // This will happen if we don't have sufficient permissions + // to view the parent item (or the item itself if it is toplevel) + notice( t('Permission denied.') . EOL); + } - $update_unseen = ''; + } + else { + $items = array(); + } - if($page_mode === 'list') { + if((! $update) && (! $load)) { + + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, + // because browser prefetching might change it on us. We have to deliver it with the page. + + $maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height'); + if(! $maxheight) + $maxheight = 400; + + $o .= '
    ' . "\r\n"; + $o .= "\r\n"; + + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'channel', + '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '0', + '$cmax' => '0', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$nouveau' => '0', + '$wall' => '1', + '$fh' => '0', + '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$search' => '', + '$order' => '', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$file' => '', + '$cats' => (($category) ? $category : ''), + '$tags' => (($hashtags) ? $hashtags : ''), + '$mid' => $mid, + '$verb' => '', + '$dend' => $datequery, + '$dbegin' => $datequery2 + )); - /** - * in "list mode", only mark the parent item and any like activities as "seen". - * We won't distinguish between comment likes and post likes. The important thing - * is that the number of unseen comments will be accurate. The SQL to separate the - * comment likes could also get somewhat hairy. - */ - if($parents_str) { - $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )"; - $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) "; - } - } - else { - if($parents_str) { - $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )"; } - } - if($is_owner && $update_unseen) { - $r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen", - intval(local_channel()) - ); - } + $update_unseen = ''; + if($page_mode === 'list') { - if($checkjs->disabled()) { - $o .= conversation($a,$items,'channel',$update,'traditional'); - } else { - $o .= conversation($a,$items,'channel',$update,$page_mode); - } + /** + * in "list mode", only mark the parent item and any like activities as "seen". + * We won't distinguish between comment likes and post likes. The important thing + * is that the number of unseen comments will be accurate. The SQL to separate the + * comment likes could also get somewhat hairy. + */ - if((! $update) || ($checkjs->disabled())) { - $o .= alt_pager($a,count($items)); - if ($mid && $items[0]['title']) - \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; - } + if($parents_str) { + $update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )"; + $update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) "; + } + } + else { + if($parents_str) { + $update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )"; + } + } + + if($is_owner && $update_unseen) { + $r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen", + intval(local_channel()) + ); + } - if($mid) - $o .= '
    '; - return $o; -} + if($checkjs->disabled()) { + $o .= conversation($a,$items,'channel',$update,'traditional'); + } + else { + $o .= conversation($a,$items,'channel',$update,$page_mode); + } + if((! $update) || ($checkjs->disabled())) { + $o .= alt_pager($a,count($items)); + if ($mid && $items[0]['title']) + \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; + } + if($mid) + $o .= '
    '; + + return $o; + } } \ No newline at end of file diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index b8bac53bb..560038ffc 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -57,9 +57,9 @@ class Directory extends \Zotlabs\Web\Controller { } } - function get() { + function get() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 6e880cbb4..c1a0d84bc 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -7,17 +7,13 @@ class Display extends \Zotlabs\Web\Controller { function get($update = 0, $load = false) { - // logger("mod-display: update = $update load = $load"); - - $checkjs = new \Zotlabs\Web\CheckJS(1); - if($load) $_SESSION['loadtime'] = datetime_convert(); - if(intval(get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } diff --git a/Zotlabs/Module/Feed.php b/Zotlabs/Module/Feed.php index 9d33ba2c3..47871eafb 100644 --- a/Zotlabs/Module/Feed.php +++ b/Zotlabs/Module/Feed.php @@ -31,7 +31,7 @@ class Feed extends \Zotlabs\Web\Controller { $channel = $r[0]; - if((intval(get_config('system','block_public'))) && (! get_account_id())) + if(observer_prohibited(true)) killme(); logger('mod_feed: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $channel['channel_address']); diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 266ac05e0..7186209ba 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -18,7 +18,7 @@ class Photos extends \Zotlabs\Web\Controller { function init() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { return; } @@ -518,7 +518,7 @@ class Photos extends \Zotlabs\Web\Controller { // photos/name/image/xxxxx - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php index 04a64fe76..8bf358bc8 100644 --- a/Zotlabs/Module/Profile.php +++ b/Zotlabs/Module/Profile.php @@ -55,8 +55,8 @@ class Profile extends \Zotlabs\Web\Controller { function get() { - if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { - return login(); + if(observer_prohibited(true)) { + return login(); } $groups = array(); diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index c25e04312..312be7718 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -12,7 +12,7 @@ class Pubstream extends \Zotlabs\Web\Controller { $_SESSION['loadtime'] = datetime_convert(); - if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { + if(observer_prohibited(true)) { return login(); } diff --git a/Zotlabs/Module/Ratings.php b/Zotlabs/Module/Ratings.php index 802bbfec2..969fb5015 100644 --- a/Zotlabs/Module/Ratings.php +++ b/Zotlabs/Module/Ratings.php @@ -8,7 +8,7 @@ class Ratings extends \Zotlabs\Web\Controller { function init() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { return; } @@ -80,9 +80,9 @@ class Ratings extends \Zotlabs\Web\Controller { - function get() { + function get() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php index d58c431e5..ea478f92a 100644 --- a/Zotlabs/Module/Viewconnections.php +++ b/Zotlabs/Module/Viewconnections.php @@ -7,7 +7,7 @@ class Viewconnections extends \Zotlabs\Web\Controller { function init() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { return; } if(argc() > 1) @@ -16,7 +16,7 @@ class Viewconnections extends \Zotlabs\Web\Controller { function get() { - if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 28040149f..6b505c890 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -15,7 +15,7 @@ class Zotfeed extends \Zotlabs\Web\Controller { if(! $mindate) $mindate = datetime_convert('UTC','UTC', 'now - 14 days'); - if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) { + if(observer_prohibited()) { $result['message'] = 'Public access denied'; json_return_and_die($result); } @@ -45,8 +45,6 @@ class Zotfeed extends \Zotlabs\Web\Controller { $result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate)); $result['success'] = true; json_return_and_die($result); - - } } -- cgit v1.2.3 From 2d06663490c5fd63b0ebbae141d0b2bbd5a4a8ca Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 19:25:27 -0700 Subject: move apps to zlib --- Zotlabs/Module/Appman.php | 17 +++++++++-------- Zotlabs/Module/Apps.php | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index ba2a64f35..a200e986a 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -2,8 +2,9 @@ namespace Zotlabs\Module; -require_once('include/apps.php'); +//require_once('include/apps.php'); +use \Zotlabs\Lib as Zlib; class Appman extends \Zotlabs\Web\Controller { @@ -30,16 +31,16 @@ class Appman extends \Zotlabs\Web\Controller { 'categories' => escape_tags($_REQUEST['categories']) ); - $_REQUEST['appid'] = app_install(local_channel(),$arr); + $_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr); - if(app_installed(local_channel(),$arr)) + if(Zlib\Apps::app_installed(local_channel(),$arr)) info( t('App installed.') . EOL); return; } - $papp = app_decode($_POST['papp']); + $papp = Zlib\Apps::app_decode($_POST['papp']); if(! is_array($papp)) { notice( t('Malformed app.') . EOL); @@ -47,13 +48,13 @@ class Appman extends \Zotlabs\Web\Controller { } if($_POST['install']) { - app_install(local_channel(),$papp); - if(app_installed(local_channel(),$papp)) + Zlib\Apps::app_install(local_channel(),$papp); + if(Zlib\Apps::app_installed(local_channel(),$papp)) info( t('App installed.') . EOL); } if($_POST['delete']) { - app_destroy(local_channel(),$papp); + Zlib\Apps::app_destroy(local_channel(),$papp); } if($_POST['edit']) { @@ -100,7 +101,7 @@ class Appman extends \Zotlabs\Web\Controller { } } - $embed = array('embed', t('Embed code'), app_encode($app,true),'', 'onclick="this.select();"'); + $embed = array('embed', t('Embed code'), Zlib\Apps::app_encode($app,true),'', 'onclick="this.select();"'); } diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index 33259b319..d3e8b1504 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -1,8 +1,9 @@ Date: Sun, 22 May 2016 20:54:52 -0700 Subject: move chatroom stuff to zlib --- Zotlabs/Module/Chat.php | 22 ++++++++++++---------- Zotlabs/Module/Chatsvc.php | 12 +++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php index 9508ed3de..d14c32b7d 100644 --- a/Zotlabs/Module/Chat.php +++ b/Zotlabs/Module/Chat.php @@ -1,9 +1,11 @@ - $room)); + Zlib\Chatroom::destroy($channel,array('cr_name' => $room)); goaway(z_root() . '/chat/' . $channel['channel_address']); } @@ -67,7 +69,7 @@ class Chat extends \Zotlabs\Web\Controller { if(intval($arr['expire']) < 0) $arr['expire'] = 0; - chatroom_create($channel,$arr); + Zlib\Chatroom::create($channel,$arr); $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1", dbesc($room), @@ -87,7 +89,7 @@ class Chat extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(local_channel()) $channel = \App::get_channel(); @@ -105,7 +107,7 @@ class Chat extends \Zotlabs\Web\Controller { } if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) { - chatroom_leave($observer,argv(2),$_SERVER['REMOTE_ADDR']); + Zlib\Chatroom::leave($observer,argv(2),$_SERVER['REMOTE_ADDR']); goaway(z_root() . '/channel/' . argv(1)); } @@ -158,7 +160,7 @@ class Chat extends \Zotlabs\Web\Controller { $room_id = intval(argv(2)); $bookmark_link = get_bookmark_link($ob); - $x = chatroom_enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']); + $x = Zlib\Chatroom::enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']); if(! $x) return; $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", @@ -238,7 +240,7 @@ class Chat extends \Zotlabs\Web\Controller { )); } - $rooms = chatroom_list(\App::$profile['profile_uid']); + $rooms = Zlib\Chatroom::roomlist(\App::$profile['profile_uid']); $o .= replace_macros(get_markup_template('chatrooms.tpl'), array( '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['name']), diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php index a9bc97301..6a28a7c4d 100644 --- a/Zotlabs/Module/Chatsvc.php +++ b/Zotlabs/Module/Chatsvc.php @@ -1,14 +1,16 @@ - false); @@ -27,7 +29,7 @@ class Chatsvc extends \Zotlabs\Web\Controller { } - function post() { + function post() { $ret = array('success' => false); @@ -65,7 +67,7 @@ class Chatsvc extends \Zotlabs\Web\Controller { json_return_and_die($ret); } - function get() { + function get() { $status = strip_tags($_REQUEST['status']); $room_id = intval(\App::$data['chat']['room_id']); -- cgit v1.2.3 From a1aa3d906159e4ad563779e5f220dddbfbd744c4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 22:08:01 -0700 Subject: Can't use "use x as y" aliases in callback function declarations --- Zotlabs/Module/Apps.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index d3e8b1504..4bdec4573 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -33,7 +33,7 @@ class Apps extends \Zotlabs\Web\Controller { else $syslist = Zlib\Apps::get_system_apps(true); - usort($syslist,'Zlib\\Apps::app_name_compare'); + usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare'); // logger('apps: ' . print_r($syslist,true)); -- cgit v1.2.3 From 80b422bdbe570e70adc2e55473f9e29a045722fe Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 23 May 2016 13:49:54 -0700 Subject: typo --- Zotlabs/Module/Connedit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index c9b20ae14..c5c38b96a 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -230,7 +230,7 @@ class Connedit extends \Zotlabs\Web\Controller { if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms && (! intval(\App::$poi['abook_self']))) { - \Zotlabs\Daemon\Master(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id)); + \Zotlabs\Daemon\Master::Summon(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id)); } if($new_friend) { -- cgit v1.2.3 From 29ba8918093166ac32ef9a727a9b71ba8e01a402 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 01:25:13 -0700 Subject: moved enotify --- Zotlabs/Module/Item.php | 6 +++--- Zotlabs/Module/Ping.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index b4f493e5b..041939ad8 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -17,10 +17,10 @@ namespace Zotlabs\Module; */ require_once('include/crypto.php'); -require_once('include/enotify.php'); require_once('include/items.php'); require_once('include/attach.php'); +use \Zotlabs\Lib as Zlib; class Item extends \Zotlabs\Web\Controller { @@ -925,7 +925,7 @@ class Item extends \Zotlabs\Web\Controller { // otherwise it will happen during delivery if(($datarray['owner_xchan'] != $datarray['author_xchan']) && (intval($parent_item['item_wall']))) { - notification(array( + Zlib\Enotify::submit(array( 'type' => NOTIFY_COMMENT, 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], @@ -943,7 +943,7 @@ class Item extends \Zotlabs\Web\Controller { $parent = $post_id; if(($datarray['owner_xchan'] != $datarray['author_xchan']) && ($datarray['item_type'] == ITEM_TYPE_POST)) { - notification(array( + Zlib\Enotify::submit(array( 'type' => NOTIFY_WALL, 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index bea4a08b7..f0caa4373 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -1,12 +1,13 @@ Date: Tue, 24 May 2016 06:15:42 -0400 Subject: Delete wiki (in progress) --- Zotlabs/Module/Wiki.php | 52 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 53a3eb26b..221068e0a 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -21,7 +21,7 @@ class Wiki extends \Zotlabs\Web\Controller { } if(! $which) { notice( t('You must be logged in to see this page.') . EOL ); - return; + goaway('/login'); } } @@ -91,6 +91,12 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('html' => $html, 'success' => true)); } + // Check if specified wiki exists and redirect if not + if((argc() > 2)) { + $wikiname = argv(2); + // TODO: Check if specified wiki exists and redirect if not + } + // Create a new wiki if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { $which = argv(1); @@ -102,20 +108,23 @@ class Wiki extends \Zotlabs\Web\Controller { $observer_hash = get_observer_hash(); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - - if (!$perms['write_wiki']) { + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { notice(t('Permission denied.') . EOL); - json_return_and_die(array('success' => false)); + goaway(argv(0).'/'.argv(1).'/'.argv(2)); } } - $name = escape_tags(urlencode($_REQUEST['wikiName'])); //Get new wiki name + $name = escape_tags(urlencode($_POST['wikiName'])); //Get new wiki name if($name === '') { notice('Error creating wiki. Invalid name.'); goaway('/wiki'); } // Get ACL for permissions $acl = new \Zotlabs\Access\AccessList($channel); - $acl->set_from_array($_REQUEST); + logger('POST: ' . json_encode($_POST)); + $acl->set_from_array($_POST); + logger('acl: ' . json_encode($acl)); $r = wiki_create_wiki($channel, $observer_hash, $name, $acl); if ($r['success']) { goaway('/wiki/'.$which.'/'.$name); @@ -125,7 +134,36 @@ class Wiki extends \Zotlabs\Web\Controller { } } - json_return_and_die(array('success' => false)); + // Delete a wiki + if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) { + $which = argv(1); + // Determine if observer has permission to create wiki + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($which); + $observer_hash = get_observer_hash(); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + logger('Wiki delete permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $resource_id = $_POST['resource_id']; + $deleted = wiki_delete_wiki($resource_id); + if ($deleted['success']) { + json_return_and_die(array('success' => true)); + } else { + logger('Error deleting wiki: ' . $resource_id); + json_return_and_die(array('success' => false)); + } + } + + notice('You must be authenticated.'); + goaway('/wiki'); } } -- cgit v1.2.3 From 84ba6393ad32406a9875044aef2d031c7d0d7a46 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 16:36:55 -0700 Subject: relocate index and db --- Zotlabs/Module/Setup.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index 462ccced6..b913190b1 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -82,11 +82,11 @@ class Setup extends \Zotlabs\Web\Controller { $siteurl = rtrim($siteurl,'/'); require_once('include/dba/dba_driver.php'); - unset($db); - $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); + + $db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); - if(! $db->connected) { - echo 'Database Connect failed: ' . $db->error; + if(! \DBA::$dba->connected) { + echo 'Database Connect failed: ' . DBA::$dba->error; killme(); \App::$data['db_conn_failed']=true; } @@ -138,10 +138,12 @@ class Setup extends \Zotlabs\Web\Controller { } } - // connect to db - $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); - - if(! $db->connected) { + if(! \DBA::$dba->connected) { + // connect to db + $db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); + } + + if(! \DBA::$dba->connected) { echo 'CRITICAL: DB not connected.'; killme(); } @@ -228,7 +230,7 @@ class Setup extends \Zotlabs\Web\Controller { $txt .= "
    ".\App::$data['db_failed'] . "
    ". EOL ; $db_return_text .= $txt; } - if($db && $db->connected) { + if(\DBA::$dba && \DBA::$dba->connected) { $r = q("SELECT COUNT(*) as `total` FROM `account`"); if($r && count($r) && $r[0]['total']) { $tpl = get_markup_template('install.tpl'); @@ -598,7 +600,7 @@ class Setup extends \Zotlabs\Web\Controller { if(! is_writable(TEMPLATE_BUILD_PATH) ) { $status = false; $help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; - $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the Red top level folder.'), TEMPLATE_BUILD_PATH) . EOL; + $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the top level web folder.'), TEMPLATE_BUILD_PATH) . EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; $help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL; } @@ -698,12 +700,12 @@ class Setup extends \Zotlabs\Web\Controller { function load_database($db) { - $str = file_get_contents($db->get_install_script()); + $str = file_get_contents(\DBA::$dba->get_install_script()); $arr = explode(';',$str); $errors = false; foreach($arr as $a) { if(strlen(trim($a))) { - $r = @$db->q(trim($a)); + $r = dbq(trim($a)); if(! $r) { $errors .= t('Errors encountered creating database tables.') . $a . EOL; } -- cgit v1.2.3 From 516c43ba154dc43ec0ef6135fb0a9732d0185a6f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 17:54:45 -0700 Subject: more work associated with DBA and index.php shuffle --- Zotlabs/Module/Setup.php | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index b913190b1..447f46ed6 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -12,7 +12,6 @@ namespace Zotlabs\Module; /** * @brief Initialisation for the setup module. * - * @param[in,out] App &$a */ class Setup extends \Zotlabs\Web\Controller { @@ -54,16 +53,15 @@ class Setup extends \Zotlabs\Web\Controller { /** * @brief Handle the actions of the different setup steps. * - * @param[in,out] App &$a */ - function post() { - global $db; + + function post() { switch($this->install_wizard_pass) { case 1: case 2: return; - break; // just in case return don't return :) + // implied break; case 3: $urlpath = \App::get_path(); $dbhost = trim($_POST['dbhost']); @@ -88,33 +86,9 @@ class Setup extends \Zotlabs\Web\Controller { if(! \DBA::$dba->connected) { echo 'Database Connect failed: ' . DBA::$dba->error; killme(); - \App::$data['db_conn_failed']=true; } - /*if(get_db_errno()) { - unset($db); - $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, '', true); - - if(! get_db_errno()) { - $r = q("CREATE DATABASE '%s'", - dbesc($dbdata) - ); - if($r) { - unset($db); - $db = new dba($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true); - } else { - \App::$data['db_create_failed']=true; - } - } else { - \App::$data['db_conn_failed']=true; - return; - } - }*/ - //if(get_db_errno()) { - - //} - return; - break; + // implied break; case 4: $urlpath = \App::get_path(); $dbhost = notags(trim($_POST['dbhost'])); @@ -177,6 +151,8 @@ class Setup extends \Zotlabs\Web\Controller { \App::$data['db_installed'] = true; return; + // implied break; + default: break; } } @@ -193,11 +169,10 @@ class Setup extends \Zotlabs\Web\Controller { * * Depending on the state we are currently in it returns different content. * - * @param App &$a * @return string parsed HTML output */ - function get() { - global $db; + + function get() { $o = ''; $wizard_status = ''; -- cgit v1.2.3 From 929d33fb22754e8525f3054b321891335b522faa Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 25 May 2016 14:18:41 +0200 Subject: another try on #385 - replace sabres restrictive CSP with what we do in boot.php --- Zotlabs/Module/Cloud.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index d9b0c47d4..b691475ce 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -100,9 +100,12 @@ class Cloud extends \Zotlabs\Web\Controller { // require_once('\Zotlabs\Storage/QuotaPlugin.php'); // $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth)); + ob_start(); // All we need to do now, is to fire up the server $server->exec(); + ob_end_flush(); + killme(); } -- cgit v1.2.3 From 2f64684299784126bb3bc80fbe9978ec57d19a4c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 25 May 2016 20:06:21 -0700 Subject: some event fixes, also change jquery-textcomplete to un-minified since the minified version appears to require a mapping file and causes a lot of server fetch errors trying to load it. --- Zotlabs/Module/Events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 3440e0727..2b5e239f9 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -232,7 +232,7 @@ class Events extends \Zotlabs\Web\Controller { } if($share) - \Zotlabs\Daemon\Master(array('Notifier','event',$item_id)); + \Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id)); } -- cgit v1.2.3 From 9017dcd0fd904ecdf54b75ad39588db4f2e91ea6 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 26 May 2016 14:23:17 +0200 Subject: typo --- Zotlabs/Module/Ping.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index f0caa4373..32427b06f 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -286,7 +286,7 @@ class Ping extends \Zotlabs\Web\Controller { foreach($r as $item) { if((argv(1) === 'home') && (! intval($item['item_wall']))) continue; - $result[] = \Zotlbas\Lib\Enotify::format($item); + $result[] = \Zotlabs\Lib\Enotify::format($item); } } // logger('ping (network||home): ' . print_r($result, true), LOGGER_DATA); -- cgit v1.2.3 From 24360fd19182cad5ed29d10bb47c208bc195c232 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 26 May 2016 14:33:10 +0200 Subject: check if $addonDir is a dir to silence warning if it does not exist --- Zotlabs/Module/Admin.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 172b109c8..8f15035d1 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1421,13 +1421,15 @@ class Admin extends \Zotlabs\Web\Controller { function listAddonRepos() { $addonrepos = []; $addonDir = __DIR__ . '/../../extend/addon/'; - if ($handle = opendir($addonDir)) { - while (false !== ($entry = readdir($handle))) { - if ($entry != "." && $entry != "..") { - $addonrepos[] = $entry; + if(is_dir($addonDir)) { + if ($handle = opendir($addonDir)) { + while (false !== ($entry = readdir($handle))) { + if ($entry != "." && $entry != "..") { + $addonrepos[] = $entry; + } } + closedir($handle); } - closedir($handle); } return $addonrepos; } -- cgit v1.2.3 From 551cf8ee9413c5c57e7b71d6016466e598636900 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 26 May 2016 19:40:16 -0700 Subject: link to hubchart site for site detail on pubsites page --- Zotlabs/Module/Pubsites.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index 31bca5f30..0dda08e6d 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -28,9 +28,10 @@ class Pubsites extends \Zotlabs\Web\Controller { if($ret['success']) { $j = json_decode($ret['body'],true); if($j) { - $o .= '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Software') . '' . t('Ratings') . '
    ' . t('Rate') . '
    '; + $o .= '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Software') . '' . t('Ratings') . '
    '; if($j['sites']) { foreach($j['sites'] as $jj) { + $m = parse_url($jj['url']); if(strpos($jj['project'],\Zotlabs\Lib\System::get_platform_name()) === false) continue; $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); @@ -43,7 +44,7 @@ class Pubsites extends \Zotlabs\Web\Controller { $location = '
     '; } $urltext = str_replace(array('https://'), '', $jj['url']); - $o .= '' . $rate_links . ''; + $o .= '' . $rate_links . ''; } } -- cgit v1.2.3 From ca78ebce6d254f244b4c1fbe25eb3aca40b26952 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 27 May 2016 20:37:37 -0400 Subject: Check if wiki exists and redirect if it does not --- Zotlabs/Module/Wiki.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 221068e0a..290c2e005 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -26,6 +26,7 @@ class Wiki extends \Zotlabs\Web\Controller { } function get() { + require_once('include/wiki.php'); require_once('include/acl_selectors.php'); if(local_channel()) { $channel = \App::get_channel(); @@ -56,6 +57,10 @@ class Wiki extends \Zotlabs\Web\Controller { } elseif (argc()<4) { $wikiheader = 'Empty wiki: ' . rawurldecode(argv(2)); // show wiki name $hide_editor = true; + // Check if wiki exists andr redirect if it does not + if(!wiki_exists_by_name(argv(2))['id']) { + goaway('/'.argv(0).'/'.argv(1)); + } } elseif (argc()<5) { $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page $hide_editor = false; @@ -112,7 +117,7 @@ class Wiki extends \Zotlabs\Web\Controller { // then, use webpage permissions if (!$perms['write_pages']) { notice(t('Permission denied.') . EOL); - goaway(argv(0).'/'.argv(1).'/'.argv(2)); + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); } } $name = escape_tags(urlencode($_POST['wikiName'])); //Get new wiki name -- cgit v1.2.3 From 4691c3ec01eda972e7b4cae4ec940c8c24d51b5a Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 27 May 2016 22:19:05 -0400 Subject: Add new page to wiki and redirect to editor page. --- Zotlabs/Module/Wiki.php | 59 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 290c2e005..909b2c84d 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -49,18 +49,25 @@ class Wiki extends \Zotlabs\Web\Controller { 'acl' => populate_acl($channel_acl), 'bang' => '' ); -// $wikiheader = t('Wiki Sandbox'); -// $hide_editor = false; + + $resource_id = ''; + if(argc()>2) { + // Check if wiki exists andr redirect if it does not + $channel = get_channel_by_nick(argv(1)); + $w = wiki_exists_by_name($channel['channel_id'], argv(2)); + logger('wiki_Exists: ' . json_encode($w)); + if(!$w['id']) { + goaway('/'.argv(0).'/'.argv(1)); + } else { + $resource_id = $w['resource_id']; + } + } if(argc()<3) { $wikiheader = t('Wiki Sandbox'); $hide_editor = false; } elseif (argc()<4) { $wikiheader = 'Empty wiki: ' . rawurldecode(argv(2)); // show wiki name - $hide_editor = true; - // Check if wiki exists andr redirect if it does not - if(!wiki_exists_by_name(argv(2))['id']) { - goaway('/'.argv(0).'/'.argv(1)); - } + $hide_editor = true; } elseif (argc()<5) { $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page $hide_editor = false; @@ -70,6 +77,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$wikiheader' => $wikiheader, '$hideEditor' => $hide_editor, '$channel' => $channel['channel_address'], + '$resource_id' => $resource_id, '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], @@ -166,6 +174,43 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } + + // Create a page + if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) { + $which = argv(1); + $resource_id = $_POST['resource_id']; + // Determine if observer has permission to create wiki + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($which); + $observer_hash = get_observer_hash(); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + logger('Wiki editing permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['write']) { + logger('Wiki write permission denied. Read only.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $name = escape_tags(urlencode($_POST['name'])); //Get new wiki name + if($name === '') { + json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false)); + } + $page = wiki_create_page($name . '.md', $resource_id); + if ($page['success']) { + json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki'].'/'.$name, 'success' => true)); + } else { + logger('Error creating page'); + json_return_and_die(array('message' => 'Error creating page.', 'success' => false)); + } + } notice('You must be authenticated.'); goaway('/wiki'); -- cgit v1.2.3 From f884fa66782544cd6fc44a81b978a905d4755cea Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 07:17:42 -0400 Subject: Wiki page list is fetched and the page widget is updated --- Zotlabs/Module/Wiki.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 909b2c84d..9d905f561 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -92,8 +92,6 @@ class Wiki extends \Zotlabs\Web\Controller { function post() { require_once('include/wiki.php'); - // TODO: Implement wiki API - // Render mardown-formatted text in HTML if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; @@ -212,8 +210,22 @@ class Wiki extends \Zotlabs\Web\Controller { } } - notice('You must be authenticated.'); - goaway('/wiki'); + // Fetch page list for a wiki + if ((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) { + $resource_id = $_POST['resource_id']; // resource_id for wiki in db + $channel = get_channel_by_nick(argv(1)); + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['read']) { + logger('Wiki read permission denied.' . EOL); + json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false)); + } + $page_list_html = widget_wiki_pages(array('resource_id' => $resource_id)); + json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true)); + } + + //notice('You must be authenticated.'); + json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); } } -- cgit v1.2.3 From ae94e8a855d31125b96e158c0fb8c0d6f22631d6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 07:42:18 -0400 Subject: Wiki page list links work. File content is not yet loaded into the editor. Removed some logger calls. --- Zotlabs/Module/Wiki.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 9d905f561..54511fc91 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -55,7 +55,6 @@ class Wiki extends \Zotlabs\Web\Controller { // Check if wiki exists andr redirect if it does not $channel = get_channel_by_nick(argv(1)); $w = wiki_exists_by_name($channel['channel_id'], argv(2)); - logger('wiki_Exists: ' . json_encode($w)); if(!$w['id']) { goaway('/'.argv(0).'/'.argv(1)); } else { @@ -95,8 +94,6 @@ class Wiki extends \Zotlabs\Web\Controller { // Render mardown-formatted text in HTML if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; - logger('preview content: ' . $content); - //require_once('library/parsedown/Parsedown.php'); $parsedown = new Parsedown(); $html = $parsedown->text($content); json_return_and_die(array('html' => $html, 'success' => true)); @@ -133,9 +130,7 @@ class Wiki extends \Zotlabs\Web\Controller { } // Get ACL for permissions $acl = new \Zotlabs\Access\AccessList($channel); - logger('POST: ' . json_encode($_POST)); $acl->set_from_array($_POST); - logger('acl: ' . json_encode($acl)); $r = wiki_create_wiki($channel, $observer_hash, $name, $acl); if ($r['success']) { goaway('/wiki/'.$which.'/'.$name); @@ -220,7 +215,10 @@ class Wiki extends \Zotlabs\Web\Controller { logger('Wiki read permission denied.' . EOL); json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false)); } - $page_list_html = widget_wiki_pages(array('resource_id' => $resource_id)); + $page_list_html = widget_wiki_pages(array( + 'resource_id' => $resource_id, + 'refresh' => true, + 'channel' => argv(1))); json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true)); } -- cgit v1.2.3 From 7393dccde816bafca2e3efe534fae56339e2c536 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 12:33:07 -0400 Subject: Page content is loaded from the file on disk --- Zotlabs/Module/Wiki.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 54511fc91..76c07f2bc 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -63,12 +63,20 @@ class Wiki extends \Zotlabs\Web\Controller { } if(argc()<3) { $wikiheader = t('Wiki Sandbox'); + $content = '# Wiki Sandbox\nContent you **edit** and **preview** here *will not be saved*.'; $hide_editor = false; } elseif (argc()<4) { - $wikiheader = 'Empty wiki: ' . rawurldecode(argv(2)); // show wiki name + $wikiheader = rawurldecode(argv(2)); // show wiki name + $content = ''; $hide_editor = true; } elseif (argc()<5) { - $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page + $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page + $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => argv(3))); + if(!$p['success']) { + logger('Error getting page content'); + $content = 'Error retrieving page content. Try again.'; + } + $content = $p['content']; $hide_editor = false; } @@ -80,7 +88,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], - '$content' => '# Start your wiki', + '$content' => $content, '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', '') )); -- cgit v1.2.3 From 819683a073f85b05807d6c936a2b746296fc8de4 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 14:11:36 -0400 Subject: Show page content by default. Hide page controls where appropriate. Fix sandbox text format. --- Zotlabs/Module/Wiki.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 76c07f2bc..a53cb3f6a 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -63,12 +63,14 @@ class Wiki extends \Zotlabs\Web\Controller { } if(argc()<3) { $wikiheader = t('Wiki Sandbox'); - $content = '# Wiki Sandbox\nContent you **edit** and **preview** here *will not be saved*.'; + $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; $hide_editor = false; + $showPageControls = false; } elseif (argc()<4) { $wikiheader = rawurldecode(argv(2)); // show wiki name $content = ''; - $hide_editor = true; + $hide_editor = true; + $showPageControls = true; } elseif (argc()<5) { $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => argv(3))); @@ -78,17 +80,23 @@ class Wiki extends \Zotlabs\Web\Controller { } $content = $p['content']; $hide_editor = false; + $showPageControls = true; } + $parsedown = new Parsedown(); + $renderedContent = $parsedown->text(json_decode($content)); + $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheader' => $wikiheader, '$hideEditor' => $hide_editor, + '$showPageControls' => $showPageControls, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], '$content' => $content, + '$renderedContent' => $renderedContent, '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', '') )); -- cgit v1.2.3 From ab54bf514921ae3fe0fafcdf154364815ed6375f Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 15:11:19 -0400 Subject: Wiki pages can be saved. --- Zotlabs/Module/Wiki.php | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index a53cb3f6a..5d293e6f0 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -51,6 +51,7 @@ class Wiki extends \Zotlabs\Web\Controller { ); $resource_id = ''; + $pagename = ''; if(argc()>2) { // Check if wiki exists andr redirect if it does not $channel = get_channel_by_nick(argv(1)); @@ -68,12 +69,13 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = false; } elseif (argc()<4) { $wikiheader = rawurldecode(argv(2)); // show wiki name - $content = ''; + $content = '""'; $hide_editor = true; $showPageControls = true; } elseif (argc()<5) { - $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode(argv(3)); // show wiki name and page - $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => argv(3))); + $pagename = argv(3); + $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode($pagename); // show wiki name and page + $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => $pagename)); if(!$p['success']) { logger('Error getting page content'); $content = 'Error retrieving page content. Try again.'; @@ -82,7 +84,6 @@ class Wiki extends \Zotlabs\Web\Controller { $hide_editor = false; $showPageControls = true; } - $parsedown = new Parsedown(); $renderedContent = $parsedown->text(json_decode($content)); @@ -92,6 +93,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$showPageControls' => $showPageControls, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, + '$page' => $pagename, '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], @@ -238,6 +240,40 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true)); } + // Save a page + if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) { + $which = argv(1); + $resource_id = $_POST['resource_id']; + $pagename = escape_tags(urlencode($_POST['name'])); + $content = escape_tags($_POST['content']); //Get new content + // Determine if observer has permission to create wiki + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($which); + $observer_hash = get_observer_hash(); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + logger('Wiki editing permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['write']) { + logger('Wiki write permission denied. Read only.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $saved = wiki_save_page(array('resource_id' => $resource_id, 'name' => $pagename, 'content' => $content)); + if($saved['success']) { + json_return_and_die(array('success' => true)); + } else { + json_return_and_die(array('success' => false)); + } + } + //notice('You must be authenticated.'); json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); -- cgit v1.2.3 From 63a97ff6fc313372d9cb439a621f12fdecc2fac1 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 10:18:26 -0400 Subject: Git commit made for the page edits when the page is saved. --- Zotlabs/Module/Wiki.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 5d293e6f0..70d326faf 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -268,9 +268,20 @@ class Wiki extends \Zotlabs\Web\Controller { } $saved = wiki_save_page(array('resource_id' => $resource_id, 'name' => $pagename, 'content' => $content)); if($saved['success']) { - json_return_and_die(array('success' => true)); + $ob = \App::get_observer(); + $commit = wiki_git_commit(array( + 'commit_msg' => 'Updated ' . $pagename, + 'resource_id' => $resource_id, + 'observer' => $ob, + 'files' => array($pagename) + )); + if($commit['success']) { + json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error making git commit','success' => false)); + } } else { - json_return_and_die(array('success' => false)); + json_return_and_die(array('message' => 'Error saving page', 'success' => false)); } } -- cgit v1.2.3 From df7772e301be10fd31329f646db98361baa04857 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 13:33:52 -0400 Subject: Home page create with new wiki. URL redirects here when no page given. Fixed bug with author in wiki item table record. --- Zotlabs/Module/Wiki.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 70d326faf..51630bddc 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -52,7 +52,10 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = ''; $pagename = ''; - if(argc()>2) { + + // GET https://hubzilla.hub/argv(0)/argv(1)/argv(2)/argv(3)/argv(4)/... + if(argc() > 2) { + // GET /wiki/channel/wiki // Check if wiki exists andr redirect if it does not $channel = get_channel_by_nick(argv(1)); $w = wiki_exists_by_name($channel['channel_id'], argv(2)); @@ -62,17 +65,23 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = $w['resource_id']; } } + if(argc()<3) { + // GET /wiki/channel $wikiheader = t('Wiki Sandbox'); $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; $hide_editor = false; $showPageControls = false; } elseif (argc()<4) { + // GET /wiki/channel/wiki + // No page was specified, so redirect to Home.md + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home.md'); $wikiheader = rawurldecode(argv(2)); // show wiki name $content = '""'; $hide_editor = true; $showPageControls = true; } elseif (argc()<5) { + // GET /wiki/channel/wiki/page $pagename = argv(3); $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode($pagename); // show wiki name and page $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => $pagename)); @@ -127,11 +136,11 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { $which = argv(1); // Determine if observer has permission to create wiki + $observer_hash = get_observer_hash(); if (local_channel()) { $channel = \App::get_channel(); } else { $channel = get_channel_by_nick($which); - $observer_hash = get_observer_hash(); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); // TODO: Create a new permission setting for wiki analogous to webpages. Until @@ -151,7 +160,12 @@ class Wiki extends \Zotlabs\Web\Controller { $acl->set_from_array($_POST); $r = wiki_create_wiki($channel, $observer_hash, $name, $acl); if ($r['success']) { - goaway('/wiki/'.$which.'/'.$name); + $homePage = wiki_create_page('Home.md', $r['item']['resource_id']); + if(!$homePage['success']) { + notice('Wiki created, but error creating Home page.'); + goaway('/wiki/'.$which.'/'.$name); + } + goaway('/wiki/'.$which.'/'.$name.'/Home.md'); } else { notice('Error creating wiki'); goaway('/wiki'); -- cgit v1.2.3 From 3e6af5c87692b5dbefd59d7b2350670d4e1cb3a4 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 17:06:45 -0400 Subject: Hacked Parsedown and Markdown to add class inline-code to blocks for proper inline code rendering. Stopped using Parsedown even though Markdown is slower, hence extra delay when previewing pages. --- Zotlabs/Module/Wiki.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 51630bddc..efd4120ca 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -93,8 +93,10 @@ class Wiki extends \Zotlabs\Web\Controller { $hide_editor = false; $showPageControls = true; } - $parsedown = new Parsedown(); - $renderedContent = $parsedown->text(json_decode($content)); + //$parsedown = new Parsedown(); + //$renderedContent = $parsedown->text(json_decode($content)); + require_once('library/markdown.php'); + $renderedContent = Markdown(json_decode($content)); $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheader' => $wikiheader, @@ -121,8 +123,10 @@ class Wiki extends \Zotlabs\Web\Controller { // Render mardown-formatted text in HTML if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; - $parsedown = new Parsedown(); - $html = $parsedown->text($content); + //$parsedown = new Parsedown(); + //$html = $parsedown->text($content); + require_once('library/markdown.php'); + $html = Markdown($content); json_return_and_die(array('html' => $html, 'success' => true)); } @@ -230,7 +234,7 @@ class Wiki extends \Zotlabs\Web\Controller { } $page = wiki_create_page($name . '.md', $resource_id); if ($page['success']) { - json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki'].'/'.$name, 'success' => true)); + json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki'].'/'.$name.'.md', 'success' => true)); } else { logger('Error creating page'); json_return_and_die(array('message' => 'Error creating page.', 'success' => false)); -- cgit v1.2.3 From fad27fc1e791dbe77321d4b45eb6293f8ff97310 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 20:16:17 -0400 Subject: Hide page controls when not owner. Fixed some serious access control issues. --- Zotlabs/Module/Wiki.php | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index efd4120ca..b369221c8 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -28,14 +28,11 @@ class Wiki extends \Zotlabs\Web\Controller { function get() { require_once('include/wiki.php'); require_once('include/acl_selectors.php'); + $wiki_owner = false; if(local_channel()) { $channel = \App::get_channel(); } - // TODO: check observer permissions - //$ob = \App::get_observer(); - //$observer = get_observer_hash(); - // Obtain the default permission settings of the channel $channel_acl = array( 'allow_cid' => $channel['channel_allow_cid'], @@ -58,13 +55,26 @@ class Wiki extends \Zotlabs\Web\Controller { // GET /wiki/channel/wiki // Check if wiki exists andr redirect if it does not $channel = get_channel_by_nick(argv(1)); + if(local_channel() === intval($channel['channel_id'])) { + $wiki_owner = true; + } $w = wiki_exists_by_name($channel['channel_id'], argv(2)); - if(!$w['id']) { + if(!$w['resource_id']) { + notice('Wiki not found' . EOL); goaway('/'.argv(0).'/'.argv(1)); - } else { + } else { $resource_id = $w['resource_id']; } - } + if (!$wiki_owner) { + // Check for observer permissionswhich); + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['read']) { + notice('Permission denied.' . EOL); + goaway('/'.argv(0).'/'.argv(1)); + } + } + } if(argc()<3) { // GET /wiki/channel @@ -79,22 +89,23 @@ class Wiki extends \Zotlabs\Web\Controller { $wikiheader = rawurldecode(argv(2)); // show wiki name $content = '""'; $hide_editor = true; - $showPageControls = true; + // Until separate read and write permissions are implemented, only allow + // the wiki owner to see page controls + $showPageControls = $wiki_owner; } elseif (argc()<5) { // GET /wiki/channel/wiki/page $pagename = argv(3); $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode($pagename); // show wiki name and page $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => $pagename)); if(!$p['success']) { - logger('Error getting page content'); + logger('wiki_get_page_content: ' . $p['message']); $content = 'Error retrieving page content. Try again.'; } - $content = $p['content']; + logger('content: ' . $content); + $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); $hide_editor = false; - $showPageControls = true; + $showPageControls = $wiki_owner; } - //$parsedown = new Parsedown(); - //$renderedContent = $parsedown->text(json_decode($content)); require_once('library/markdown.php'); $renderedContent = Markdown(json_decode($content)); @@ -120,23 +131,17 @@ class Wiki extends \Zotlabs\Web\Controller { function post() { require_once('include/wiki.php'); - // Render mardown-formatted text in HTML + // /wiki/channel/preview + // Render mardown-formatted text in HTML for preview if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; - //$parsedown = new Parsedown(); - //$html = $parsedown->text($content); require_once('library/markdown.php'); $html = Markdown($content); json_return_and_die(array('html' => $html, 'success' => true)); } - // Check if specified wiki exists and redirect if not - if((argc() > 2)) { - $wikiname = argv(2); - // TODO: Check if specified wiki exists and redirect if not - } - // Create a new wiki + // /wiki/channel/create/wiki if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { $which = argv(1); // Determine if observer has permission to create wiki -- cgit v1.2.3 From 00d32f6b947d10b836cf1a4d59dbff3413517fd5 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 20:39:19 -0400 Subject: Only show wiki delete control if channel owner --- Zotlabs/Module/Wiki.php | 1 + 1 file changed, 1 insertion(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index b369221c8..3c1f14a9b 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -78,6 +78,7 @@ class Wiki extends \Zotlabs\Web\Controller { if(argc()<3) { // GET /wiki/channel + $channel = get_channel_by_nick(argv(1)); $wikiheader = t('Wiki Sandbox'); $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; $hide_editor = false; -- cgit v1.2.3 From a3dfdd9d3886451f5e97940387a56171c5810cf6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 20:44:28 -0400 Subject: Remove Parsedown library files and remove references. --- Zotlabs/Module/Wiki.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 3c1f14a9b..946529424 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -2,8 +2,6 @@ namespace Zotlabs\Module;/** @file */ -use \library\parsedown\Parsedown as Parsedown; - class Wiki extends \Zotlabs\Web\Controller { function init() { -- cgit v1.2.3 From 4b350b909025ba2102d5ad2c5ee32b3c4eecaa48 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 21:23:56 -0400 Subject: Fixed bug in access control. Hide new wiki/page buttons if not channel owner. --- Zotlabs/Module/Wiki.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 946529424..030e34cf6 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -97,10 +97,8 @@ class Wiki extends \Zotlabs\Web\Controller { $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode($pagename); // show wiki name and page $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => $pagename)); if(!$p['success']) { - logger('wiki_get_page_content: ' . $p['message']); $content = 'Error retrieving page content. Try again.'; } - logger('content: ' . $content); $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); $hide_editor = false; $showPageControls = $wiki_owner; -- cgit v1.2.3 From 3b2679db29077c33912edb085a24906708ad97ee Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 29 May 2016 18:38:24 -0700 Subject: fix remote_channel(), update php minversion requirement --- Zotlabs/Module/Setup.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index 447f46ed6..c4878e217 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -384,8 +384,8 @@ class Setup extends \Zotlabs\Web\Controller { function check_php(&$phpath, &$checks) { $help = ''; - if(version_compare(PHP_VERSION, '5.4') < 0) { - $help .= t('PHP version 5.4 or greater is required.'); + if(version_compare(PHP_VERSION, '5.5') < 0) { + $help .= t('PHP version 5.5 or greater is required.'); $this->check_add($checks, t('PHP version'), false, false, $help); } -- cgit v1.2.3 From f2ebe41a509d6e7f332fdc4cb43d14d555375bdf Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 29 May 2016 20:18:28 -0700 Subject: undefined function --- Zotlabs/Module/Cover_photo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index 2e53696ff..371713c8d 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -341,7 +341,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { } } - cover_photo_crop_ui_head($a, $ph, $hash, $smallest); + $this->cover_photo_crop_ui_head($a, $ph, $hash, $smallest); } -- cgit v1.2.3 From a52cdcb2410fc67823a3dab62b413d70ec57cdec Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 30 May 2016 14:59:33 -0400 Subject: Replaced wiki item record object field with ActivityStreams information. Wiki git repo path is stored in iconfig instead. --- Zotlabs/Module/Wiki.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 030e34cf6..d6acbf6b0 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -27,6 +27,7 @@ class Wiki extends \Zotlabs\Web\Controller { require_once('include/wiki.php'); require_once('include/acl_selectors.php'); $wiki_owner = false; + $showNewWikiButton = false; if(local_channel()) { $channel = \App::get_channel(); } @@ -47,15 +48,16 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = ''; $pagename = ''; - + if(argc() > 1) { + $channel = get_channel_by_nick(argv(1)); + if(local_channel() === intval($channel['channel_id'])) { + $wiki_owner = true; + } + } // GET https://hubzilla.hub/argv(0)/argv(1)/argv(2)/argv(3)/argv(4)/... if(argc() > 2) { // GET /wiki/channel/wiki // Check if wiki exists andr redirect if it does not - $channel = get_channel_by_nick(argv(1)); - if(local_channel() === intval($channel['channel_id'])) { - $wiki_owner = true; - } $w = wiki_exists_by_name($channel['channel_id'], argv(2)); if(!$w['resource_id']) { notice('Wiki not found' . EOL); @@ -81,6 +83,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; $hide_editor = false; $showPageControls = false; + $showNewWikiButton = $wiki_owner; } elseif (argc()<4) { // GET /wiki/channel/wiki // No page was specified, so redirect to Home.md @@ -90,7 +93,8 @@ class Wiki extends \Zotlabs\Web\Controller { $hide_editor = true; // Until separate read and write permissions are implemented, only allow // the wiki owner to see page controls - $showPageControls = $wiki_owner; + $showPageControls = $wiki_owner; + $showNewWikiButton = $wiki_owner; } elseif (argc()<5) { // GET /wiki/channel/wiki/page $pagename = argv(3); @@ -102,6 +106,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); $hide_editor = false; $showPageControls = $wiki_owner; + $showNewWikiButton = $wiki_owner; } require_once('library/markdown.php'); $renderedContent = Markdown(json_decode($content)); @@ -110,6 +115,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$wikiheader' => $wikiheader, '$hideEditor' => $hide_editor, '$showPageControls' => $showPageControls, + '$showNewWikiButton'=> $showNewWikiButton, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, '$page' => $pagename, -- cgit v1.2.3 From 8d284bab474c7e669ae9a639bdb22f7b28b95cc3 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 30 May 2016 20:59:54 -0400 Subject: Created page history widget to dynamically fetch and display the git commit history for wiki pages. --- Zotlabs/Module/Wiki.php | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index d6acbf6b0..0f8db9350 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -26,8 +26,11 @@ class Wiki extends \Zotlabs\Web\Controller { function get() { require_once('include/wiki.php'); require_once('include/acl_selectors.php'); + // TODO: Combine the interface configuration into a unified object + // Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...) $wiki_owner = false; $showNewWikiButton = false; + $pageHistory = array(); if(local_channel()) { $channel = \App::get_channel(); } @@ -107,6 +110,7 @@ class Wiki extends \Zotlabs\Web\Controller { $hide_editor = false; $showPageControls = $wiki_owner; $showNewWikiButton = $wiki_owner; + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); } require_once('library/markdown.php'); $renderedContent = Markdown(json_decode($content)); @@ -125,7 +129,8 @@ class Wiki extends \Zotlabs\Web\Controller { '$content' => $content, '$renderedContent' => $renderedContent, '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), - '$pageName' => array('pageName', t('Enter the name of the new page:'), '', '') + '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), + '$pageHistory' => $pageHistory['history'] )); head_add_js('library/ace/ace.js'); return $o; @@ -236,7 +241,7 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $name = escape_tags(urlencode($_POST['name'])); //Get new wiki name + $name = escape_tags(urlencode($_POST['name'])); //Get new page name if($name === '') { json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false)); } @@ -272,7 +277,7 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = $_POST['resource_id']; $pagename = escape_tags(urlencode($_POST['name'])); $content = escape_tags($_POST['content']); //Get new content - // Determine if observer has permission to create wiki + // Determine if observer has permission to save content if (local_channel()) { $channel = \App::get_channel(); } else { @@ -311,6 +316,31 @@ class Wiki extends \Zotlabs\Web\Controller { } } + // Update page history + // /wiki/channel/history/page + if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) { + $which = argv(1); + $resource_id = $_POST['resource_id']; + $pagename = escape_tags(urlencode($_POST['name'])); + // Determine if observer has permission to view content + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($which); + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if (!$perms['read']) { + logger('Wiki read permission denied.' . EOL); + json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false)); + } + } + $historyHTML = widget_wiki_page_history(array( + 'resource_id' => $resource_id, + 'page' => $pagename + )); + json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true)); + } + //notice('You must be authenticated.'); json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); -- cgit v1.2.3 From 6602ff83dd54d0e17c985a5f527654fc2ed83eea Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 30 May 2016 19:44:30 -0700 Subject: start removing reserved words from database column names (this run: addon and hook) --- Zotlabs/Module/Admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 8f15035d1..4cabd78ca 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1291,7 +1291,7 @@ class Admin extends \Zotlabs\Web\Controller { $admin_form = ''; - $r = q("select * from addon where plugin_admin = 1 and name = '%s' limit 1", + $r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1", dbesc($plugin) ); -- cgit v1.2.3 From ca78374f30bd1b3a98b8b82552741a54b131cbf8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 30 May 2016 22:41:45 -0700 Subject: remove unused tables --- Zotlabs/Module/Fsuggest.php | 117 -------------------------------------------- 1 file changed, 117 deletions(-) delete mode 100644 Zotlabs/Module/Fsuggest.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Fsuggest.php b/Zotlabs/Module/Fsuggest.php deleted file mode 100644 index a371f9d21..000000000 --- a/Zotlabs/Module/Fsuggest.php +++ /dev/null @@ -1,117 +0,0 @@ -' . t('Suggest Friends') . ''; - - $o .= '
    ' . sprintf( t('Suggest a friend for %s'), $contact['name']) . '
    '; - - $o .= '
    '; - - // FIXME contact_selector deprecated, removed - // $o .= contact_selector('suggest','suggest-select', false, - // array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true)); - - - $o .= '
    '; - $o .= ''; - - return $o; - } -} -- cgit v1.2.3 From dfb6255f59980835d364402b372dd39f2b41ee7c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 31 May 2016 17:50:47 -0700 Subject: more removal of reserved words from DB schemas --- Zotlabs/Module/Api.php | 2 +- Zotlabs/Module/Settings.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Api.php b/Zotlabs/Module/Api.php index 3e7f23b6c..e4744c29f 100644 --- a/Zotlabs/Module/Api.php +++ b/Zotlabs/Module/Api.php @@ -107,7 +107,7 @@ class Api extends \Zotlabs\Web\Controller { $r = q("SELECT `clients`.* FROM `clients`, `tokens` WHERE `clients`.`client_id`=`tokens`.`client_id` - AND `tokens`.`id`='%s' AND `tokens`.`scope`='request'", + AND `tokens`.`id`='%s' AND `tokens`.`auth_scope`='request'", dbesc($token)); if (!count($r)) diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 5687ce84b..43162a2b0 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -78,7 +78,7 @@ class Settings extends \Zotlabs\Web\Controller { $r = q("UPDATE clients SET client_id='%s', pw='%s', - name='%s', + clname='%s', redirect_uri='%s', icon='%s', uid=%d @@ -91,7 +91,7 @@ class Settings extends \Zotlabs\Web\Controller { intval(local_channel()), dbesc($key)); } else { - $r = q("INSERT INTO clients (client_id, pw, name, redirect_uri, icon, uid) + $r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid) VALUES ('%s','%s','%s','%s','%s',%d)", dbesc($key), dbesc($secret), @@ -615,7 +615,7 @@ class Settings extends \Zotlabs\Web\Controller { '$title' => t('Add application'), '$submit' => t('Update'), '$cancel' => t('Cancel'), - '$name' => array('name', t('Name'), $app['name'] , ''), + '$name' => array('name', t('Name'), $app['clname'] , ''), '$key' => array('key', t('Consumer Key'), $app['client_id'], ''), '$secret' => array('secret', t('Consumer Secret'), $app['pw'], ''), '$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], ''), -- cgit v1.2.3 From b1259876bf398880e7b0c1b44d90f94983243e72 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 31 May 2016 21:45:33 -0700 Subject: more db column renames --- Zotlabs/Module/Acl.php | 8 ++++---- Zotlabs/Module/Chat.php | 2 +- Zotlabs/Module/Contactgroup.php | 4 ++-- Zotlabs/Module/Events.php | 2 +- Zotlabs/Module/Filer.php | 2 +- Zotlabs/Module/Filerm.php | 2 +- Zotlabs/Module/Group.php | 14 +++++++------- Zotlabs/Module/Import.php | 6 +++++- Zotlabs/Module/Item.php | 8 ++++---- Zotlabs/Module/Lockview.php | 8 ++++---- Zotlabs/Module/Network.php | 2 +- Zotlabs/Module/Photos.php | 2 +- Zotlabs/Module/Profiles.php | 39 +++++++++++++++++---------------------- Zotlabs/Module/Search.php | 2 +- Zotlabs/Module/Search_ac.php | 2 +- Zotlabs/Module/Settings.php | 8 ++++---- Zotlabs/Module/Tagrm.php | 2 +- 17 files changed, 56 insertions(+), 57 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 62ac29286..7bc197a93 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -53,13 +53,13 @@ class Acl extends \Zotlabs\Web\Controller { if ($type=='' || $type=='g'){ - $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`name` + $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname` FROM `groups`,`group_member` WHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d AND `group_member`.`gid`=`groups`.`id` $sql_extra GROUP BY `groups`.`id` - ORDER BY `groups`.`name` + ORDER BY `groups`.`gname` LIMIT %d OFFSET %d", intval(local_channel()), intval($count), @@ -67,11 +67,11 @@ class Acl extends \Zotlabs\Web\Controller { ); foreach($r as $g){ - // logger('acl: group: ' . $g['name'] . ' members: ' . group_get_members_xchan($g['id'])); + // logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id'])); $groups[] = array( "type" => "g", "photo" => "images/twopeople.png", - "name" => $g['name'], + "name" => $g['gname'], "id" => $g['id'], "xid" => $g['hash'], "uids" => group_get_members_xchan($g['id']), diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php index d14c32b7d..026e8369a 100644 --- a/Zotlabs/Module/Chat.php +++ b/Zotlabs/Module/Chat.php @@ -243,7 +243,7 @@ class Chat extends \Zotlabs\Web\Controller { $rooms = Zlib\Chatroom::roomlist(\App::$profile['profile_uid']); $o .= replace_macros(get_markup_template('chatrooms.tpl'), array( - '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['name']), + '$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['fullname']), '$name' => t('Name'), '$baseurl' => z_root(), '$nickname' => \App::$profile['channel_address'], diff --git a/Zotlabs/Module/Contactgroup.php b/Zotlabs/Module/Contactgroup.php index 497442ff4..bbe56b4ad 100644 --- a/Zotlabs/Module/Contactgroup.php +++ b/Zotlabs/Module/Contactgroup.php @@ -41,10 +41,10 @@ class Contactgroup extends \Zotlabs\Web\Controller { if($change) { if(in_array($change,$preselected)) { - group_rmv_member(local_channel(),$group['name'],$change); + group_rmv_member(local_channel(),$group['gname'],$change); } else { - group_add_member(local_channel(),$group['name'],$change); + group_add_member(local_channel(),$group['gname'],$change); } } } diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 2b5e239f9..3996473b7 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -171,7 +171,7 @@ class Events extends \Zotlabs\Web\Controller { foreach($cats as $cat) { $post_tags[] = array( 'uid' => $profile_uid, - 'type' => TERM_CATEGORY, + 'ttype' => TERM_CATEGORY, 'otype' => TERM_OBJ_POST, 'term' => trim($cat), 'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)) diff --git a/Zotlabs/Module/Filer.php b/Zotlabs/Module/Filer.php index 607d088db..6a57cdb2a 100644 --- a/Zotlabs/Module/Filer.php +++ b/Zotlabs/Module/Filer.php @@ -39,7 +39,7 @@ class Filer extends \Zotlabs\Web\Controller { } else { $filetags = array(); - $r = q("select distinct(term) from term where uid = %d and type = %d order by term asc", + $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); diff --git a/Zotlabs/Module/Filerm.php b/Zotlabs/Module/Filerm.php index eb9a42c1e..cbf6a118d 100644 --- a/Zotlabs/Module/Filerm.php +++ b/Zotlabs/Module/Filerm.php @@ -22,7 +22,7 @@ class Filerm extends \Zotlabs\Web\Controller { logger('filerm: tag ' . $term . ' item ' . $item_id); if($item_id && strlen($term)) { - $r = q("delete from term where uid = %d and type = %d and oid = %d and term = '%s'", + $r = q("delete from term where uid = %d and ttype = %d and oid = %d and term = '%s'", intval(local_channel()), intval(($category) ? TERM_CATEGORY : TERM_FILE), intval($item_id), diff --git a/Zotlabs/Module/Group.php b/Zotlabs/Module/Group.php index 144797baf..254ee6ef2 100644 --- a/Zotlabs/Module/Group.php +++ b/Zotlabs/Module/Group.php @@ -47,8 +47,8 @@ class Group extends \Zotlabs\Web\Controller { $groupname = notags(trim($_POST['groupname'])); $public = intval($_POST['public']); - if((strlen($groupname)) && (($groupname != $group['name']) || ($public != $group['visible']))) { - $r = q("UPDATE `groups` SET `name` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d", + if((strlen($groupname)) && (($groupname != $group['gname']) || ($public != $group['visible']))) { + $r = q("UPDATE `groups` SET `gname` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d", dbesc($groupname), intval($public), intval(local_channel()), @@ -106,7 +106,7 @@ class Group extends \Zotlabs\Web\Controller { intval(local_channel()) ); if($r) - $result = group_rmv(local_channel(),$r[0]['name']); + $result = group_rmv(local_channel(),$r[0]['gname']); if($result) info( t('Privacy group removed.') . EOL); else @@ -156,10 +156,10 @@ class Group extends \Zotlabs\Web\Controller { if($change) { if(in_array($change,$preselected)) { - group_rmv_member(local_channel(),$group['name'],$change); + group_rmv_member(local_channel(),$group['gname'],$change); } else { - group_add_member(local_channel(),$group['name'],$change); + group_add_member(local_channel(),$group['gname'],$change); } $members = group_get_members($group['id']); @@ -181,7 +181,7 @@ class Group extends \Zotlabs\Web\Controller { $context = $context + array( '$title' => t('Privacy group editor'), - '$gname' => array('groupname',t('Privacy group name: '),$group['name'], ''), + '$gname' => array('groupname',t('Privacy group name: '),$group['gname'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, '$public' => array('public',t('Members are visible to other channels'), $group['visible'], ''), @@ -209,7 +209,7 @@ class Group extends \Zotlabs\Web\Controller { $groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); } else - group_rmv_member(local_channel(),$group['name'],$member['xchan_hash']); + group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']); } $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 57ced22a3..122e27e90 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -408,8 +408,12 @@ class Import extends \Zotlabs\Web\Controller { $saved = array(); foreach($groups as $group) { $saved[$group['hash']] = array('old' => $group['id']); + if(array_key_exists('name',$group)) { + $group['gname'] = $group['name']; + unset($group['name']); + } unset($group['id']); - $group['uid'] = $channel['channel_id']; + $group['uid'] = $channel['channel_id']; dbesc_array($group); $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 041939ad8..2601feb0a 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -581,7 +581,7 @@ class Item extends \Zotlabs\Web\Controller { if($success['replaced']) { $post_tags[] = array( 'uid' => $profile_uid, - 'type' => $success['termtype'], + 'ttype' => $success['termtype'], 'otype' => TERM_OBJ_POST, 'term' => $success['term'], 'url' => $success['url'] @@ -666,7 +666,7 @@ class Item extends \Zotlabs\Web\Controller { foreach($cats as $cat) { $post_tags[] = array( 'uid' => $profile_uid, - 'type' => TERM_CATEGORY, + 'ttype' => TERM_CATEGORY, 'otype' => TERM_OBJ_POST, 'term' => trim($cat), 'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)) @@ -676,7 +676,7 @@ class Item extends \Zotlabs\Web\Controller { if($orig_post) { // preserve original tags - $t = q("select * from term where oid = %d and otype = %d and uid = %d and type in ( %d, %d, %d )", + $t = q("select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )", intval($orig_post['id']), intval(TERM_OBJ_POST), intval($profile_uid), @@ -688,7 +688,7 @@ class Item extends \Zotlabs\Web\Controller { foreach($t as $t1) { $post_tags[] = array( 'uid' => $profile_uid, - 'type' => $t1['type'], + 'ttype' => $t1['type'], 'otype' => TERM_OBJ_POST, 'term' => $t1['term'], 'url' => $t1['url'], diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php index 0df0dd4da..4776e1c56 100644 --- a/Zotlabs/Module/Lockview.php +++ b/Zotlabs/Module/Lockview.php @@ -88,10 +88,10 @@ class Lockview extends \Zotlabs\Web\Controller { stringify_array_elms($deny_users,true); if(count($allowed_groups)) { - $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); + $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); if($r) foreach($r as $rr) - $l[] = '
  • ' . $rr['name'] . '
  • '; + $l[] = '
  • ' . $rr['gname'] . '
  • '; } if(count($allowed_users)) { $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )"); @@ -100,10 +100,10 @@ class Lockview extends \Zotlabs\Web\Controller { $l[] = '
  • ' . $rr['xchan_name'] . '
  • '; } if(count($deny_groups)) { - $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); + $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); if($r) foreach($r as $rr) - $l[] = '
  • ' . $rr['name'] . '
  • '; + $l[] = '
  • ' . $rr['gname'] . '
  • '; } if(count($deny_users)) { $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )"); diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 238df3593..87ed326e2 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -223,7 +223,7 @@ class Network extends \Zotlabs\Web\Controller { if($x) { $title = replace_macros(get_markup_template("section_title.tpl"),array( - '$title' => t('Privacy group: ') . $x['name'] + '$title' => t('Privacy group: ') . $x['gname'] )); } diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 7186209ba..ecf966032 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -440,7 +440,7 @@ class Photos extends \Zotlabs\Web\Controller { if($success['replaced']) { $post_tags[] = array( 'uid' => $profile_uid, - 'type' => $success['termtype'], + 'ttype' => $success['termtype'], 'otype' => TERM_OBJ_POST, 'term' => $success['term'], 'url' => $success['url'] diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 54780499b..06e5cfd7b 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -67,16 +67,16 @@ class Profiles extends \Zotlabs\Web\Controller { $name = t('Profile-') . ($num_profiles + 1); - $r1 = q("SELECT `name`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1", + $r1 = q("SELECT `fullname`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1", intval(local_channel())); - $r2 = q("INSERT INTO `profile` (`aid`, `uid` , `profile_guid`, `profile_name` , `name`, `photo`, `thumb`) + $r2 = q("INSERT INTO `profile` (`aid`, `uid` , `profile_guid`, `profile_name` , `fullname`, `photo`, `thumb`) VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s' )", intval(get_account_id()), intval(local_channel()), dbesc(random_string()), dbesc($name), - dbesc($r1[0]['name']), + dbesc($r1[0]['fullname']), dbesc($r1[0]['photo']), dbesc($r1[0]['thumb']) ); @@ -277,14 +277,14 @@ class Profiles extends \Zotlabs\Web\Controller { $name = escape_tags(trim($_POST['name'])); - if($orig[0]['name'] != $name) { + if($orig[0]['fullname'] != $name) { $namechanged = true; $v = validate_channelname($name); if($v) { notice($v); $namechanged = false; - $name = $orig[0]['name']; + $name = $orig[0]['fullname']; } } @@ -350,7 +350,7 @@ class Profiles extends \Zotlabs\Web\Controller { $withchanged = false; if(strlen($with)) { - if($with != strip_tags($orig[0]['with'])) { + if($with != strip_tags($orig[0]['partner'])) { $withchanged = true; $prf = ''; $lookup = $with; @@ -382,7 +382,7 @@ class Profiles extends \Zotlabs\Web\Controller { } } else - $with = $orig[0]['with']; + $with = $orig[0]['partner']; } $profile_fields_basic = get_profile_fields_basic(); @@ -439,7 +439,7 @@ class Profiles extends \Zotlabs\Web\Controller { $changes[] = t('Dislikes'); $value = $dislikes; } - if($work != $orig[0]['work']) { + if($work != $orig[0]['employment']) { $changes[] = t('Work/Employment'); } if($religion != $orig[0]['religion']) { @@ -486,7 +486,7 @@ class Profiles extends \Zotlabs\Web\Controller { $r = q("UPDATE `profile` SET `profile_name` = '%s', - `name` = '%s', + `fullname` = '%s', `pdesc` = '%s', `gender` = '%s', `dob` = '%s', @@ -496,7 +496,7 @@ class Profiles extends \Zotlabs\Web\Controller { `postal_code` = '%s', `country_name` = '%s', `marital` = '%s', - `with` = '%s', + `partner` = '%s', `howlong` = '%s', `sexual` = '%s', `homepage` = '%s', @@ -515,7 +515,7 @@ class Profiles extends \Zotlabs\Web\Controller { `tv` = '%s', `film` = '%s', `romance` = '%s', - `work` = '%s', + `employment` = '%s', `education` = '%s', `hide_friends` = %d WHERE `id` = %d AND `uid` = %d", @@ -591,7 +591,7 @@ class Profiles extends \Zotlabs\Web\Controller { } - function get() { + function get() { $o = ''; @@ -627,8 +627,6 @@ class Profiles extends \Zotlabs\Web\Controller { } $editselect = 'none'; - // if(feature_enabled(local_channel(),'richtext')) - // $editselect = 'textareas'; \App::$page['htmlhead'] .= replace_macros(get_markup_template('profed_head.tpl'), array( '$baseurl' => z_root(), @@ -712,7 +710,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$is_default' => $is_default, '$default' => t('This is your default profile.') . EOL . translate_scope(map_scope($channel['channel_r_profile'])), '$advanced' => $advanced, - '$name' => array('name', t('Your full name'), $r[0]['name'], t('Required'), '*'), + '$name' => array('name', t('Your full name'), $r[0]['fullname'], t('Required'), '*'), '$pdesc' => array('pdesc', t('Title/Description'), $r[0]['pdesc']), '$dob' => dob($r[0]['dob']), '$hide_friends' => $hide_friends, @@ -725,7 +723,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$gender_min' => gender_selector_min($r[0]['gender']), '$marital' => marital_selector($r[0]['marital']), '$marital_min' => marital_selector_min($r[0]['marital']), - '$with' => array('with', t("Who (if applicable)"), $r[0]['with'], t('Examples: cathy123, Cathy Williams, cathy@example.com')), + '$with' => array('with', t("Who (if applicable)"), $r[0]['partner'], t('Examples: cathy123, Cathy Williams, cathy@example.com')), '$howlong' => array('howlong', t('Since (date)'), ($r[0]['howlong'] === NULL_DATE ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong']))), '$sexual' => sexpref_selector($r[0]['sexual']), '$sexual_min' => sexpref_selector_min($r[0]['sexual']), @@ -743,7 +741,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$film' => array('film', t('Film/Dance/Culture/Entertainment'), $r[0]['film']), '$interest' => array('interest', t('Hobbies/Interests'), $r[0]['interest']), '$romance' => array('romance',t('Love/Romance'), $r[0]['romance']), - '$work' => array('work', t('Work/Employment'), $r[0]['work']), + '$work' => array('work', t('Work/Employment'), $r[0]['employment']), '$education' => array('education', t('School/Education'), $r[0]['education']), '$contact' => array('contact', t('Contact information and social networks'), $r[0]['contact']), '$channels' => array('channels', t('My other channels'), $r[0]['channels']), @@ -759,7 +757,7 @@ class Profiles extends \Zotlabs\Web\Controller { $r = q("SELECT * FROM `profile` WHERE `uid` = %d", local_channel()); - if(count($r)) { + if($r) { $tpl = get_markup_template('profile_entry.tpl'); foreach($r as $rr) { @@ -780,10 +778,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$cr_new' => t('Create New'), '$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new"), '$profiles' => $profiles - )); - - - + )); } return $o; diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index fcc2506fc..402a27d40 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -79,7 +79,7 @@ class Search extends \Zotlabs\Web\Controller { return $o; if($tag) { - $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and type in ( %d , %d) and term = '%s') ", + $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and ttype in ( %d , %d) and term = '%s') ", intval(TERM_OBJ_POST), intval(TERM_HASHTAG), intval(TERM_COMMUNITYTAG), diff --git a/Zotlabs/Module/Search_ac.php b/Zotlabs/Module/Search_ac.php index 78bcf374d..4e936d97b 100644 --- a/Zotlabs/Module/Search_ac.php +++ b/Zotlabs/Module/Search_ac.php @@ -46,7 +46,7 @@ class Search_ac extends \Zotlabs\Web\Controller { } } - $r = q("select distinct term, tid, url from term where type in ( %d, %d ) $tag_sql_extra group by term order by term asc", + $r = q("select distinct term, tid, url from term where ttype in ( %d, %d ) $tag_sql_extra group by term order by term asc", intval(TERM_HASHTAG), intval(TERM_COMMUNITYTAG) ); diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 43162a2b0..875004fae 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -337,7 +337,7 @@ class Settings extends \Zotlabs\Web\Controller { } $hide_presence = 1 - (intval($role_permissions['online'])); if($role_permissions['default_collection']) { - $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc( t('Friends') ) ); @@ -345,7 +345,7 @@ class Settings extends \Zotlabs\Web\Controller { require_once('include/group.php'); group_add(local_channel(), t('Friends')); group_add_member(local_channel(),t('Friends'),$channel['channel_hash']); - $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc( t('Friends') ) ); @@ -537,7 +537,7 @@ class Settings extends \Zotlabs\Web\Controller { dbesc(datetime_convert()), dbesc($channel['channel_hash']) ); - $r = q("update profile set name = '%s' where uid = %d and is_default = 1", + $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id']) ); @@ -562,7 +562,7 @@ class Settings extends \Zotlabs\Web\Controller { - function get() { + function get() { $o = ''; nav_set_selected('settings'); diff --git a/Zotlabs/Module/Tagrm.php b/Zotlabs/Module/Tagrm.php index 81ae30aa5..42aa6e90f 100644 --- a/Zotlabs/Module/Tagrm.php +++ b/Zotlabs/Module/Tagrm.php @@ -54,7 +54,7 @@ class Tagrm extends \Zotlabs\Web\Controller { - function get() { + function get() { if(! local_channel()) { goaway(z_root() . '/' . $_SESSION['photo_return']); -- cgit v1.2.3 From a9d7acda279ebb7f2b3cd61a91a5e1d8b590dcf2 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 1 Jun 2016 21:48:54 -0700 Subject: the rest of the schema updates - WARNING: some third party plugins may fail; e.g. embedphotos and chess. $item['object'] is now $item['obj'] and $photo['type'] is $photo['mimetype'], $photo['scale'] is $photo['imgscale'] and $photo['data'] is now $photo['content']. There are a number of other changes, but these are the ones noted to cause issues with third-party plugins. The project plugins have been updated. Please note any new issues as this effort touched a lot of code in a lot of files. --- Zotlabs/Module/Attach.php | 4 +-- Zotlabs/Module/Cal.php | 20 +++++------ Zotlabs/Module/Connedit.php | 2 +- Zotlabs/Module/Cover_photo.php | 44 ++++++++++++------------ Zotlabs/Module/Events.php | 42 +++++++++++------------ Zotlabs/Module/Fbrowser.php | 4 +-- Zotlabs/Module/Like.php | 2 +- Zotlabs/Module/Notifications.php | 6 ++-- Zotlabs/Module/Notify.php | 4 +-- Zotlabs/Module/Oep.php | 16 ++++----- Zotlabs/Module/Photo.php | 18 +++++----- Zotlabs/Module/Photos.php | 73 ++++++++++++++++++++-------------------- Zotlabs/Module/Ping.php | 38 ++++++++++----------- Zotlabs/Module/Poke.php | 2 +- Zotlabs/Module/Profile_photo.php | 44 ++++++++++++------------ Zotlabs/Module/Share.php | 2 +- Zotlabs/Module/Sharedwithme.php | 4 +-- Zotlabs/Module/Subthread.php | 2 +- Zotlabs/Module/Tagger.php | 2 +- Zotlabs/Module/Tasks.php | 20 ++++------- Zotlabs/Module/Thing.php | 2 +- 21 files changed, 172 insertions(+), 179 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php index 8948b66d7..de941d52c 100644 --- a/Zotlabs/Module/Attach.php +++ b/Zotlabs/Module/Attach.php @@ -40,7 +40,7 @@ class Attach extends \Zotlabs\Web\Controller { header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); if(intval($r['data']['os_storage'])) { - $fname = dbunescbin($r['data']['data']); + $fname = dbunescbin($r['data']['content']); if(strpos($fname,'store') !== false) $istream = fopen($fname,'rb'); else @@ -53,7 +53,7 @@ class Attach extends \Zotlabs\Web\Controller { } } else - echo dbunescbin($r['data']['data']); + echo dbunescbin($r['data']['content']); killme(); } diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php index a1adb30e5..1da42684d 100644 --- a/Zotlabs/Module/Cal.php +++ b/Zotlabs/Module/Cal.php @@ -91,7 +91,7 @@ class Cal extends \Zotlabs\Web\Controller { $mode = 'view'; $y = 0; $m = 0; - $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : ''); + $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); // logger('args: ' . print_r(\App::$argv,true)); @@ -146,7 +146,7 @@ class Cal extends \Zotlabs\Web\Controller { $ftext = datetime_convert('UTC',$tz,$fdt); $ftext = substr($ftext,0,14) . "00:00"; - $type = ((x($orig_event)) ? $orig_event['type'] : 'event'); + $type = ((x($orig_event)) ? $orig_event['etype'] : 'event'); $f = get_config('system','event_input_format'); if(! $f) @@ -157,7 +157,7 @@ class Cal extends \Zotlabs\Web\Controller { $show_bd = perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts'); if(! $show_bd) { - $sql_extra .= " and event.type != 'birthday' "; + $sql_extra .= " and event.etype != 'birthday' "; } @@ -225,8 +225,8 @@ class Cal extends \Zotlabs\Web\Controller { $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on event_hash = resource_id where resource_type = 'event' and event.uid = %d $ignored - AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' ) - OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) $sql_extra ", + AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) + OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ", intval($channel['channel_id']), dbesc($start), dbesc($finish), @@ -247,7 +247,7 @@ class Cal extends \Zotlabs\Web\Controller { if($r) { foreach($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); if(! x($links,$j)) $links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j; } @@ -262,15 +262,15 @@ class Cal extends \Zotlabs\Web\Controller { foreach($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); - $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt)); + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); + $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt)); $d = day_translate($d); - $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c')); + $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c')); if ($rr['nofinish']){ $end = null; } else { - $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c')); + $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c')); } diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index c5c38b96a..33deac4c8 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -270,7 +270,7 @@ class Connedit extends \Zotlabs\Web\Controller { array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l']) ), ); - $xarr['object'] = json_encode($obj); + $xarr['obj'] = json_encode($obj); $xarr['obj_type'] = ACTIVITY_OBJ_PERSON; $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]'; diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index 371713c8d..a72c3389f 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -80,7 +80,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { $profile = $r[0]; } - $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = 0 LIMIT 1", + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = 0 LIMIT 1", dbesc($image_id), intval(local_channel()) ); @@ -88,9 +88,9 @@ class Cover_photo extends \Zotlabs\Web\Controller { if($r) { $base_image = $r[0]; - $base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data'])); + $base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content'])); - $im = photo_factory($base_image['data'], $base_image['type']); + $im = photo_factory($base_image['content'], $base_image['mimetype']); if($im->is_valid()) { // We are scaling and cropping the relative pixel locations to the original photo instead of the @@ -99,7 +99,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { // First load the scaled photo to check its size. (Should probably pass this in the post form and save // a query.) - $g = q("select width, height from photo where resource_id = '%s' and uid = %d and scale = 3", + $g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3", dbesc($image_id), intval(local_channel()) ); @@ -133,26 +133,26 @@ class Cover_photo extends \Zotlabs\Web\Controller { $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], 'filename' => $base_image['filename'], 'album' => t('Cover Photos')); - $p['scale'] = 7; + $p['imgscale'] = 7; $p['photo_usage'] = PHOTO_COVER; $r1 = $im->save($p); $im->doScaleImage(850,310); - $p['scale'] = 8; + $p['imgscale'] = 8; $r2 = $im->save($p); $im->doScaleImage(425,160); - $p['scale'] = 9; + $p['imgscale'] = 9; $r3 = $im->save($p); if($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice( t('Image resize failed.') . EOL ); - $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 7 ", + $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ", dbesc($base_image['resource_id']), local_channel() ); @@ -183,7 +183,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { logger('attach_store: ' . print_r($res,true)); if($res && intval($res['data']['is_photo'])) { - $i = q("select * from photo where resource_id = '%s' and uid = %d and scale = 0", + $i = q("select * from photo where resource_id = '%s' and uid = %d and imgscale = 0", dbesc($hash), intval(local_channel()) ); @@ -195,10 +195,10 @@ class Cover_photo extends \Zotlabs\Web\Controller { $os_storage = false; foreach($i as $ii) { - $smallest = intval($ii['scale']); + $smallest = intval($ii['imgscale']); $os_storage = intval($ii['os_storage']); - $imagedata = $ii['data']; - $filetype = $ii['type']; + $imagedata = $ii['content']; + $filetype = $ii['mimetype']; } } @@ -224,10 +224,10 @@ class Cover_photo extends \Zotlabs\Web\Controller { $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; $arr['verb'] = ACTIVITY_UPDATE; - $arr['object'] = json_encode(array( + $arr['obj'] = json_encode(array( 'type' => $arr['obj_type'], 'id' => z_root() . '/photo/' . $photo['resource_id'] . '-7', - 'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7') + 'link' => array('rel' => 'photo', 'type' => $photo['mimetype'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7') )); if($profile && stripos($profile['gender'],t('female')) !== false) @@ -295,7 +295,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { $resource_id = argv(2); - $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC", + $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", intval(local_channel()), dbesc($resource_id) ); @@ -305,11 +305,11 @@ class Cover_photo extends \Zotlabs\Web\Controller { } $havescale = false; foreach($r as $rr) { - if($rr['scale'] == 7) + if($rr['imgscale'] == 7) $havescale = true; } - $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q("SELECT `content`, `mimetype`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel()) @@ -320,15 +320,15 @@ class Cover_photo extends \Zotlabs\Web\Controller { } if(intval($r[0]['os_storage'])) - $data = @file_get_contents($r[0]['data']); + $data = @file_get_contents($r[0]['content']); else - $data = dbunescbin($r[0]['data']); + $data = dbunescbin($r[0]['content']); - $ph = photo_factory($data, $r[0]['type']); + $ph = photo_factory($data, $r[0]['mimetype']); $smallest = 0; if($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d and scale = 0", + $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0", dbesc($r[0]['resource_id']), intval(local_channel()) ); @@ -336,7 +336,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { if($i) { $hash = $i[0]['resource_id']; foreach($i as $ii) { - $smallest = intval($ii['scale']); + $smallest = intval($ii['imgscale']); } } } diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 3996473b7..3f3f9fb4c 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -180,12 +180,12 @@ class Events extends \Zotlabs\Web\Controller { } $datarray = array(); - $datarray['start'] = $start; - $datarray['finish'] = $finish; + $datarray['dtstart'] = $start; + $datarray['dtend'] = $finish; $datarray['summary'] = $summary; $datarray['description'] = $desc; $datarray['location'] = $location; - $datarray['type'] = $type; + $datarray['etype'] = $type; $datarray['adjust'] = $adjust; $datarray['nofinish'] = $nofinish; $datarray['uid'] = local_channel(); @@ -269,14 +269,14 @@ class Events extends \Zotlabs\Web\Controller { nav_set_selected('all_events'); if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { - $r = q("update event set ignore = 1 where id = %d and uid = %d", + $r = q("update event set dismissed = 1 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { - $r = q("update event set ignore = 0 where id = %d and uid = %d", + $r = q("update event set dismissed = 0 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); @@ -301,7 +301,7 @@ class Events extends \Zotlabs\Web\Controller { $mode = 'view'; $y = 0; $m = 0; - $ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : ''); + $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); // logger('args: ' . print_r(\App::$argv,true)); @@ -358,9 +358,9 @@ class Events extends \Zotlabs\Web\Controller { if(x($_REQUEST,'summary')) $orig_event['summary'] = $_REQUEST['summary']; if(x($_REQUEST,'description')) $orig_event['description'] = $_REQUEST['description']; if(x($_REQUEST,'location')) $orig_event['location'] = $_REQUEST['location']; - if(x($_REQUEST,'start')) $orig_event['start'] = $_REQUEST['start']; - if(x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish']; - if(x($_REQUEST,'type')) $orig_event['type'] = $_REQUEST['type']; + if(x($_REQUEST,'start')) $orig_event['dtstart'] = $_REQUEST['start']; + if(x($_REQUEST,'finish')) $orig_event['dtend'] = $_REQUEST['finish']; + if(x($_REQUEST,'type')) $orig_event['etype'] = $_REQUEST['type']; */ $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); @@ -380,9 +380,9 @@ class Events extends \Zotlabs\Web\Controller { if($orig_event['event_xchan']) $sh_checked .= ' disabled="disabled" '; - $sdt = ((x($orig_event)) ? $orig_event['start'] : 'now'); + $sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now'); - $fdt = ((x($orig_event)) ? $orig_event['finish'] : '+1 hour'); + $fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour'); $tz = date_default_timezone_get(); if(x($orig_event)) @@ -406,7 +406,7 @@ class Events extends \Zotlabs\Web\Controller { $ftext = datetime_convert('UTC',$tz,$fdt); $ftext = substr($ftext,0,14) . "00:00"; - $type = ((x($orig_event)) ? $orig_event['type'] : 'event'); + $type = ((x($orig_event)) ? $orig_event['etype'] : 'event'); $f = get_config('system','event_input_format'); if(! $f) @@ -536,8 +536,8 @@ class Events extends \Zotlabs\Web\Controller { ); } elseif($export) { $r = q("SELECT * from event where uid = %d - AND (( `adjust` = 0 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' ) - OR ( `adjust` = 1 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )) ", + AND (( `adjust` = 0 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' ) + OR ( `adjust` = 1 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' )) ", intval(local_channel()), dbesc($start), dbesc($finish), @@ -554,8 +554,8 @@ class Events extends \Zotlabs\Web\Controller { $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan from event left join item on event_hash = resource_id where resource_type = 'event' and event.uid = %d $ignored - AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' ) - OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) ", + AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) + OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ", intval(local_channel()), dbesc($start), dbesc($finish), @@ -576,7 +576,7 @@ class Events extends \Zotlabs\Web\Controller { if($r) { foreach($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); if(! x($links,$j)) $links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j; } @@ -591,15 +591,15 @@ class Events extends \Zotlabs\Web\Controller { foreach($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); - $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt)); + $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); + $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt)); $d = day_translate($d); - $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c')); + $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c')); if ($rr['nofinish']){ $end = null; } else { - $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c')); + $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c')); } diff --git a/Zotlabs/Module/Fbrowser.php b/Zotlabs/Module/Fbrowser.php index eef3cb67d..c534e8f72 100644 --- a/Zotlabs/Module/Fbrowser.php +++ b/Zotlabs/Module/Fbrowser.php @@ -45,10 +45,10 @@ class Fbrowser extends \Zotlabs\Web\Controller { $album = hex2bin(\App::$argv[2]); $sql_extra = sprintf("AND `album` = '%s' ",dbesc($album)); $sql_extra2 = ""; - $path[]=array(z_root()."/fbrowser/image/".\App::$argv[2]."/", $album); + $path[]=array(z_root() . "/fbrowser/image/" . \App::$argv[2] . "/", $album); } - $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `description` + $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`imgscale`) AS `hiq`,max(`imgscale`) AS `loq`, `description` FROM `photo` WHERE `uid` = %d $sql_extra GROUP BY `resource_id` $sql_extra2", intval(local_channel()) diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 3ef67ddcc..1ca37d646 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -483,7 +483,7 @@ class Like extends \Zotlabs\Web\Controller { $arr['verb'] = $activity; $arr['obj_type'] = $objtype; - $arr['object'] = $object; + $arr['obj'] = $object; if($target) { $arr['tgt_type'] = $tgttype; diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php index d51d2861c..9da28a360 100644 --- a/Zotlabs/Module/Notifications.php +++ b/Zotlabs/Module/Notifications.php @@ -80,18 +80,18 @@ class Notifications extends \Zotlabs\Web\Controller { $not_tpl = get_markup_template('notify.tpl'); require_once('include/bbcode.php'); - $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc", + $r = q("SELECT * from notify where uid = %d and seen = 0 order by created desc", intval(local_channel()) ); - if (count($r) > 0) { + if ($r > 0) { $notifications_available =1; foreach ($r as $it) { $notif_content .= replace_macros($not_tpl,array( '$item_link' => z_root().'/notify/view/'. $it['id'], '$item_image' => $it['photo'], '$item_text' => strip_tags(bbcode($it['msg'])), - '$item_when' => relative_date($it['date']) + '$item_when' => relative_date($it['created']) )); } } else { diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php index 227491145..f592f6f37 100644 --- a/Zotlabs/Module/Notify.php +++ b/Zotlabs/Module/Notify.php @@ -39,7 +39,7 @@ class Notify extends \Zotlabs\Web\Controller { $not_tpl = get_markup_template('notify.tpl'); require_once('include/bbcode.php'); - $r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc", + $r = q("SELECT * from notify where uid = %d and seen = 0 order by created desc", intval(local_channel()) ); @@ -49,7 +49,7 @@ class Notify extends \Zotlabs\Web\Controller { '$item_link' => z_root().'/notify/view/'. $it['id'], '$item_image' => $it['photo'], '$item_text' => strip_tags(bbcode($it['msg'])), - '$item_when' => relative_date($it['date']) + '$item_when' => relative_date($it['created']) )); } } diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index 89824fc7e..dc0547a42 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -249,7 +249,7 @@ class Oep extends \Zotlabs\Web\Controller { $sql_extra = permissions_sql($c[0]['channel_id']); - $p = q("select resource_id from photo where album = '%s' and uid = %d and scale = 0 $sql_extra order by created desc limit 1", + $p = q("select resource_id from photo where album = '%s' and uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", dbesc($res), intval($c[0]['channel_id']) ); @@ -258,7 +258,7 @@ class Oep extends \Zotlabs\Web\Controller { $res = $p[0]['resource_id']; - $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -276,7 +276,7 @@ class Oep extends \Zotlabs\Web\Controller { if($foundres) { $ret['type'] = 'link'; - $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale']; $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } @@ -310,7 +310,7 @@ class Oep extends \Zotlabs\Web\Controller { $sql_extra = permissions_sql($c[0]['channel_id']); - $p = q("select resource_id from photo where uid = %d and scale = 0 $sql_extra order by created desc limit 1", + $p = q("select resource_id from photo where uid = %d and imgscale = 0 $sql_extra order by created desc limit 1", intval($c[0]['channel_id']) ); if(! $p) @@ -318,7 +318,7 @@ class Oep extends \Zotlabs\Web\Controller { $res = $p[0]['resource_id']; - $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -336,7 +336,7 @@ class Oep extends \Zotlabs\Web\Controller { if($foundres) { $ret['type'] = 'link'; - $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale']; $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } @@ -372,7 +372,7 @@ class Oep extends \Zotlabs\Web\Controller { $sql_extra = permissions_sql($c[0]['channel_id']); - $r = q("select height, width, scale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by scale asc", + $r = q("select height, width, imgscale, resource_id from photo where uid = %d and resource_id = '%s' $sql_extra order by imgscale asc", intval($c[0]['channel_id']), dbesc($res) ); @@ -390,7 +390,7 @@ class Oep extends \Zotlabs\Web\Controller { if($foundres) { $ret['type'] = 'link'; - $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['scale']; + $ret['thumbnail_url'] = z_root() . '/photo/' . '/' . $rr['resource_id'] . '-' . $rr['imgscale']; $ret['thumbnail_width'] = $rr['width']; $ret['thumbnail_height'] = $rr['height']; } diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 408688886..92c9ac3c0 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -57,14 +57,14 @@ class Photo extends \Zotlabs\Web\Controller { $uid = $person; - $r = q("SELECT * FROM photo WHERE scale = %d AND uid = %d AND photo_usage = %d LIMIT 1", + $r = q("SELECT * FROM photo WHERE imgscale = %d AND uid = %d AND photo_usage = %d LIMIT 1", intval($resolution), intval($uid), intval(PHOTO_PROFILE) ); if(count($r)) { - $data = dbunescbin($r[0]['data']); - $mimetype = $r[0]['type']; + $data = dbunescbin($r[0]['content']); + $mimetype = $r[0]['mimetype']; } if(intval($r[0]['os_storage'])) $data = file_get_contents($data); @@ -113,7 +113,7 @@ class Photo extends \Zotlabs\Web\Controller { // If using resolution 1, make sure it exists before proceeding: if ($resolution == 1) { - $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1", + $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1", dbesc($photo), intval($resolution) ); @@ -121,7 +121,7 @@ class Photo extends \Zotlabs\Web\Controller { $resolution = 2; } - $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND scale = %d LIMIT 1", + $r = q("SELECT uid FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1", dbesc($photo), intval($resolution) ); @@ -133,14 +133,14 @@ class Photo extends \Zotlabs\Web\Controller { // Now we'll see if we can access the photo - $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND scale = %d $sql_extra LIMIT 1", + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1", dbesc($photo), intval($resolution) ); if($r && $allowed) { - $data = dbunescbin($r[0]['data']); - $mimetype = $r[0]['type']; + $data = dbunescbin($r[0]['content']); + $mimetype = $r[0]['mimetype']; if(intval($r[0]['os_storage'])) $data = file_get_contents($data); } @@ -154,7 +154,7 @@ class Photo extends \Zotlabs\Web\Controller { // they won't have the photo link, so there's a reasonable chance that the person // might be able to obtain permission to view it. - $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `scale` = %d LIMIT 1", + $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `imgscale` = %d LIMIT 1", dbesc($photo), intval($resolution) ); diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index ecf966032..ada7b4ef1 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -255,13 +255,13 @@ class Photos extends \Zotlabs\Web\Controller { ( (intval($_POST['rotate']) == 1) || (intval($_POST['rotate']) == 2) )) { logger('rotate'); - $r = q("select * from photo where `resource_id` = '%s' and uid = %d and scale = 0 limit 1", + $r = q("select * from photo where `resource_id` = '%s' and uid = %d and imgscale = 0 limit 1", dbesc($resource_id), intval($page_owner_uid) ); if(count($r)) { - $d = (($r[0]['os_storage']) ? @file_get_contents($r[0]['data']) : dbunescbin($r[0]['data'])); - $ph = photo_factory($d, $r[0]['type']); + $d = (($r[0]['os_storage']) ? @file_get_contents($r[0]['content']) : dbunescbin($r[0]['content'])); + $ph = photo_factory($d, $r[0]['mimetype']); if($ph->is_valid()) { $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 ); $ph->rotate($rotate_deg); @@ -270,9 +270,9 @@ class Photos extends \Zotlabs\Web\Controller { $height = $ph->getHeight(); if(intval($r[0]['os_storage'])) { - @file_put_contents($r[0]['data'],$ph->imageString()); - $data = $r[0]['data']; - $fsize = @filesize($r[0]['data']); + @file_put_contents($r[0]['content'],$ph->imageString()); + $data = $r[0]['content']; + $fsize = @filesize($r[0]['content']); q("update attach set filesize = %d where hash = '%s' and uid = %d limit 1", intval($fsize), dbesc($resource_id), @@ -284,7 +284,7 @@ class Photos extends \Zotlabs\Web\Controller { $fsize = strlen($data); } - $x = q("update photo set data = '%s', `size` = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 0", + $x = q("update photo set content = '%s', filesize = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 0", dbescbin($data), intval($fsize), intval($height), @@ -299,7 +299,7 @@ class Photos extends \Zotlabs\Web\Controller { $width = $ph->getWidth(); $height = $ph->getHeight(); - $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 1", + $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 1", dbescbin($ph->imageString()), intval($height), intval($width), @@ -314,7 +314,7 @@ class Photos extends \Zotlabs\Web\Controller { $width = $ph->getWidth(); $height = $ph->getHeight(); - $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 2", + $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 2", dbescbin($ph->imageString()), intval($height), intval($width), @@ -329,7 +329,7 @@ class Photos extends \Zotlabs\Web\Controller { $width = $ph->getWidth(); $height = $ph->getHeight(); - $x = q("update photo set data = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and scale = 3", + $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 3", dbescbin($ph->imageString()), intval($height), intval($width), @@ -340,12 +340,12 @@ class Photos extends \Zotlabs\Web\Controller { } } - $p = q("SELECT type, is_nsfw, description, resource_id, scale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY scale DESC", + $p = q("SELECT mimetype, is_nsfw, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC", dbesc($resource_id), intval($page_owner_uid) ); if($p) { - $ext = $phototypes[$p[0]['type']]; + $ext = $phototypes[$p[0]['mimetype']]; $r = q("UPDATE `photo` SET `description` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d", dbesc($desc), @@ -611,7 +611,7 @@ class Photos extends \Zotlabs\Web\Controller { /* Show space usage */ - $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", + $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", intval(\App::$data['channel']['channel_account_id']) ); @@ -704,8 +704,8 @@ class Photos extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; - $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' - AND `scale` <= 4 and photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", + $r = q("SELECT `resource_id`, max(`imgscale`) AS `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`", intval($owner_uid), dbesc($album), intval(PHOTO_NORMAL), @@ -725,9 +725,9 @@ class Photos extends \Zotlabs\Web\Controller { $order = 'DESC'; - $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.scale, p.description, p.created FROM photo p INNER JOIN - (SELECT resource_id, max(scale) scale FROM photo WHERE uid = %d AND album = '%s' AND scale <= 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.scale = ph.scale) + $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 + ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale) ORDER BY created $order LIMIT %d OFFSET %d", intval($owner_uid), dbesc($album), @@ -777,7 +777,7 @@ class Photos extends \Zotlabs\Web\Controller { else $twist = 'rotright'; - $ext = $phototypes[$rr['type']]; + $ext = $phototypes[$rr['mimetype']]; $imgalt_e = $rr['filename']; $desc_e = $rr['description']; @@ -790,7 +790,7 @@ class Photos extends \Zotlabs\Web\Controller { 'twist' => ' ' . $twist . rand(2,4), 'link' => $imagelink, 'title' => t('View Photo'), - 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext, + 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext, 'alt' => $imgalt_e, 'desc'=> $desc_e, 'ext' => $ext, @@ -852,8 +852,8 @@ class Photos extends \Zotlabs\Web\Controller { // fetch image, item containing image, then comments - $ph = q("SELECT id,aid,uid,xchan,resource_id,created,edited,title,`description`,album,filename,`type`,height,width,`size`,scale,photo_usage,is_nsfw,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' - $sql_extra ORDER BY `scale` ASC ", + $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' + $sql_extra ORDER BY `imgscale` ASC ", intval($owner_uid), dbesc($datum) ); @@ -884,7 +884,7 @@ class Photos extends \Zotlabs\Web\Controller { $order = 'DESC'; - $prvnxt = q("SELECT `resource_id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0 + $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']), intval($owner_uid) @@ -911,7 +911,7 @@ class Photos extends \Zotlabs\Web\Controller { if(count($ph) == 1) $hires = $lores = $ph[0]; if(count($ph) > 1) { - if($ph[1]['scale'] == 2) { + if($ph[1]['imgscale'] == 2) { // original is 640 or less, we can display it directly $hires = $lores = $ph[0]; } @@ -949,9 +949,9 @@ class Photos extends \Zotlabs\Web\Controller { $prevlink = array($prevlink, t('Previous')); $photo = array( - 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], + 'href' => z_root() . '/photo/' . $hires['resource_id'] . '-' . $hires['imgscale'] . '.' . $phototypes[$hires['mimetype']], 'title'=> t('View Full Size'), - 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?f=&_u=' . datetime_convert('','','','ymdhis') + 'src' => z_root() . '/photo/' . $lores['resource_id'] . '-' . $lores['imgscale'] . '.' . $phototypes[$lores['mimetype']] . '?f=&_u=' . datetime_convert('','','','ymdhis') ); if($nextlink) @@ -1277,7 +1277,7 @@ class Photos extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; - $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' + $r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", intval(\App::$data['channel']['channel_id']), dbesc('Contact Photos'), @@ -1286,16 +1286,17 @@ class Photos extends \Zotlabs\Web\Controller { intval(PHOTO_PROFILE), intval($unsafe) ); - if(count($r)) { + if($r) { \App::set_pager_total(count($r)); \App::set_pager_itemspage(60); } - $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.album, p.scale, p.created FROM photo p INNER JOIN - (SELECT resource_id, max(scale) scale FROM photo - WHERE uid=%d AND album != '%s' AND album != '%s' - 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.scale = ph.scale) ORDER by p.created DESC LIMIT %d OFFSET %d", + $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo as p + INNER JOIN ( SELECT resource_id, max(imgscale) as imgscale FROM photo + WHERE uid = %d AND photo_usage IN ( %d, %d ) + AND is_nsfw = %d $sql_extra group by resource_id ) as ph + ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale) + ORDER by p.created DESC LIMIT %d OFFSET %d", intval(\App::$data['channel']['channel_id']), dbesc('Contact Photos'), dbesc( t('Contact Photos')), @@ -1309,14 +1310,14 @@ class Photos extends \Zotlabs\Web\Controller { $photos = array(); - if(count($r)) { + if($r) { $twist = 'rotright'; foreach($r as $rr) { if($twist == 'rotright') $twist = 'rotleft'; else $twist = 'rotright'; - $ext = $phototypes[$rr['type']]; + $ext = $phototypes[$rr['mimetype']]; if(\App::get_template_engine() === 'internal') { $alt_e = template_escape($rr['filename']); @@ -1332,7 +1333,7 @@ class Photos extends \Zotlabs\Web\Controller { 'twist' => ' ' . $twist . rand(2,4), 'link' => z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id'], 'title' => t('View Photo'), - 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . ((($rr['scale']) == 6) ? 4 : $rr['scale']) . '.' . $ext, + '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']), diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index 32427b06f..5cbf45daa 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -173,7 +173,7 @@ class Ping extends \Zotlabs\Web\Controller { ); break; case 'all_events': - $r = q("update event set `ignore` = 1 where `ignore` = 0 and uid = %d AND start < '%s' AND start > '%s' ", + $r = q("update event set `dimissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ", intval(local_channel()), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) @@ -209,17 +209,17 @@ class Ping extends \Zotlabs\Web\Controller { ); if($t && intval($t[0]['total']) > 49) { $z = q("select * from notify where uid = %d - and seen = 0 order by date desc limit 50", + and seen = 0 order by created desc limit 50", intval(local_channel()) ); } else { $z1 = q("select * from notify where uid = %d - and seen = 0 order by date desc limit 50", + and seen = 0 order by created desc limit 50", intval(local_channel()) ); $z2 = q("select * from notify where uid = %d - and seen = 1 order by date desc limit %d", + and seen = 1 order by created desc limit %d", intval(local_channel()), intval(50 - intval($t[0]['total'])) ); @@ -230,10 +230,10 @@ class Ping extends \Zotlabs\Web\Controller { foreach($z as $zz) { $notifs[] = array( 'notify_link' => z_root() . '/notify/view/' . $zz['id'], - 'name' => $zz['name'], + 'name' => $zz['xname'], 'url' => $zz['url'], 'photo' => $zz['photo'], - 'when' => relative_date($zz['date']), + 'when' => relative_date($zz['created']), 'hclass' => (($zz['seen']) ? 'notify-seen' : 'notify-unseen'), 'message' => strip_tags(bbcode($zz['msg'])) ); @@ -325,9 +325,9 @@ class Ping extends \Zotlabs\Web\Controller { $result = array(); $r = q("SELECT * FROM event left join xchan on event_xchan = xchan_hash - WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 - and type in ( 'event', 'birthday' ) - ORDER BY `start` DESC LIMIT 1000", + WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0 + and etype in ( 'event', 'birthday' ) + ORDER BY `dtstart` DESC LIMIT 1000", intval(local_channel()), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) @@ -336,14 +336,14 @@ class Ping extends \Zotlabs\Web\Controller { if($r) { foreach($r as $rr) { if($rr['adjust']) - $md = datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'Y/m'); + $md = datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'Y/m'); else - $md = datetime_convert('UTC', 'UTC', $rr['start'], 'Y/m'); + $md = datetime_convert('UTC', 'UTC', $rr['dtstart'], 'Y/m'); - $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start']); + $strt = datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart']); $today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false); - $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); + $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); $result[] = array( 'notify_link' => z_root() . '/events', // FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'], @@ -443,10 +443,10 @@ class Ping extends \Zotlabs\Web\Controller { $t5 = dba_timer(); if($vnotify & (VNOTIFY_EVENT|VNOTIFY_EVENTTODAY|VNOTIFY_BIRTHDAY)) { - $events = q("SELECT type, start, adjust FROM `event` - WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 - and type in ( 'event', 'birthday' ) - ORDER BY `start` ASC ", + $events = q("SELECT etype, dtstart, adjust FROM `event` + WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0 + and etype in ( 'event', 'birthday' ) + ORDER BY `dtstart` ASC ", intval(local_channel()), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) @@ -459,14 +459,14 @@ class Ping extends \Zotlabs\Web\Controller { $str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d'); foreach($events as $x) { $bd = false; - if($x['type'] === 'birthday') { + if($x['etype'] === 'birthday') { $result['birthdays'] ++; $bd = true; } else { $result['events'] ++; } - if(datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['start'], 'Y-m-d') === $str_now) { + if(datetime_convert('UTC', ((intval($x['adjust'])) ? date_default_timezone_get() : 'UTC'), $x['dtstart'], 'Y-m-d') === $str_now) { $result['all_events_today'] ++; if($bd) $result['birthdays_today'] ++; diff --git a/Zotlabs/Module/Poke.php b/Zotlabs/Module/Poke.php index 123ecbc7b..cf8d83023 100644 --- a/Zotlabs/Module/Poke.php +++ b/Zotlabs/Module/Poke.php @@ -115,7 +115,7 @@ class Poke extends \Zotlabs\Web\Controller { ), ); - $arr['object'] = json_encode($obj); + $arr['obj'] = json_encode($obj); $arr['item_origin'] = 1; $arr['item_wall'] = 1; diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index a8cf3cbee..6129a7492 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -93,7 +93,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { $srcW = $_POST['xfinal'] - $srcX; $srcH = $_POST['yfinal'] - $srcY; - $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = %d LIMIT 1", + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1", dbesc($image_id), dbesc(local_channel()), intval($scale)); @@ -101,9 +101,9 @@ class Profile_photo extends \Zotlabs\Web\Controller { if($r) { $base_image = $r[0]; - $base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data'])); + $base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content'])); - $im = photo_factory($base_image['data'], $base_image['type']); + $im = photo_factory($base_image['content'], $base_image['mimetype']); if($im->is_valid()) { $im->cropImage(300,$srcX,$srcY,$srcW,$srcH); @@ -113,25 +113,25 @@ class Profile_photo extends \Zotlabs\Web\Controller { $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], 'filename' => $base_image['filename'], 'album' => t('Profile Photos')); - $p['scale'] = 4; + $p['imgscale'] = 4; $p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL); $r1 = $im->save($p); $im->scaleImage(80); - $p['scale'] = 5; + $p['imgscale'] = 5; $r2 = $im->save($p); $im->scaleImage(48); - $p['scale'] = 6; + $p['imgscale'] = 6; $r3 = $im->save($p); if($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice( t('Image resize failed.') . EOL ); - $x = q("delete from photo where resource_id = '%s' and uid = %d and scale >= 4 ", + $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ", dbesc($base_image['resource_id']), local_channel() ); @@ -208,7 +208,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { logger('attach_store: ' . print_r($res,true)); if($res && intval($res['data']['is_photo'])) { - $i = q("select * from photo where resource_id = '%s' and uid = %d order by scale", + $i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($hash), intval(local_channel()) ); @@ -220,11 +220,11 @@ class Profile_photo extends \Zotlabs\Web\Controller { $os_storage = false; foreach($i as $ii) { - if(intval($ii['scale']) < 2) { - $smallest = intval($ii['scale']); + if(intval($ii['imgscale']) < 2) { + $smallest = intval($ii['imgscale']); $os_storage = intval($ii['os_storage']); - $imagedata = $ii['data']; - $filetype = $ii['type']; + $imagedata = $ii['content']; + $filetype = $ii['mimetype']; } } } @@ -250,7 +250,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { */ - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL ); @@ -275,7 +275,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { $resource_id = argv(2); - $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC", + $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", intval(local_channel()), dbesc($resource_id) ); @@ -285,7 +285,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { } $havescale = false; foreach($r as $rr) { - if($rr['scale'] == 5) + if($rr['imgscale'] == 5) $havescale = true; } @@ -315,7 +315,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { goaway(z_root() . '/profiles'); } - $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", + $r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel()) @@ -326,15 +326,15 @@ class Profile_photo extends \Zotlabs\Web\Controller { } if(intval($r[0]['os_storage'])) - $data = @file_get_contents($r[0]['data']); + $data = @file_get_contents($r[0]['content']); else - $data = dbunescbin($r[0]['data']); + $data = dbunescbin($r[0]['content']); - $ph = photo_factory($data, $r[0]['type']); + $ph = photo_factory($data, $r[0]['mimetype']); $smallest = 0; if($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop - $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale", + $i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale", dbesc($r[0]['resource_id']), intval(local_channel()) ); @@ -342,8 +342,8 @@ class Profile_photo extends \Zotlabs\Web\Controller { if($i) { $hash = $i[0]['resource_id']; foreach($i as $ii) { - if(intval($ii['scale']) < 2) { - $smallest = intval($ii['scale']); + if(intval($ii['imgscale']) < 2) { + $smallest = intval($ii['imgscale']); } } } diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php index 73db01657..fcc2486ba 100644 --- a/Zotlabs/Module/Share.php +++ b/Zotlabs/Module/Share.php @@ -48,7 +48,7 @@ class Share extends \Zotlabs\Web\Controller { $is_photo = (($r[0]['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false); if($is_photo) { - $object = json_decode($r[0]['object'],true); + $object = json_decode($r[0]['obj'],true); $photo_bb = $object['body']; } diff --git a/Zotlabs/Module/Sharedwithme.php b/Zotlabs/Module/Sharedwithme.php index 8eaa47dba..25bc7dba3 100644 --- a/Zotlabs/Module/Sharedwithme.php +++ b/Zotlabs/Module/Sharedwithme.php @@ -46,7 +46,7 @@ class Sharedwithme extends \Zotlabs\Web\Controller { } //list files - $r = q("SELECT id, uid, object, item_unseen FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'", + $r = q("SELECT id, uid, obj, item_unseen FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'", dbesc(ACTIVITY_POST), dbesc(ACTIVITY_OBJ_FILE), intval(local_channel()), @@ -59,7 +59,7 @@ class Sharedwithme extends \Zotlabs\Web\Controller { if($r) { foreach($r as $rr) { - $object = json_decode($rr['object'],true); + $object = json_decode($rr['obj'],true); $item = array(); $item['id'] = $rr['id']; diff --git a/Zotlabs/Module/Subthread.php b/Zotlabs/Module/Subthread.php index 16a011a40..0226664d7 100644 --- a/Zotlabs/Module/Subthread.php +++ b/Zotlabs/Module/Subthread.php @@ -144,7 +144,7 @@ class Subthread extends \Zotlabs\Web\Controller { $arr['verb'] = $activity; $arr['obj_type'] = $objtype; - $arr['object'] = $obj; + $arr['obj'] = $obj; $arr['allow_cid'] = $item['allow_cid']; $arr['allow_gid'] = $item['allow_gid']; diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index 26d1c58ea..0a46cf56d 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -124,7 +124,7 @@ class Tagger extends \Zotlabs\Web\Controller { $arr['tgt_type'] = $targettype; $arr['target'] = $target; $arr['obj_type'] = $objtype; - $arr['object'] = $obj; + $arr['obj'] = $obj; $arr['parent_mid'] = $item['mid']; store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); diff --git a/Zotlabs/Module/Tasks.php b/Zotlabs/Module/Tasks.php index ab05f8be9..6d0a92d91 100644 --- a/Zotlabs/Module/Tasks.php +++ b/Zotlabs/Module/Tasks.php @@ -45,7 +45,7 @@ class Tasks extends \Zotlabs\Web\Controller { if((argc() > 2) && (argv(1) === 'complete') && intval(argv(2))) { $ret = array('success' => false); - $r = q("select * from event where `type` = 'task' and uid = %d and id = %d limit 1", + $r = q("select * from event where `etype` = 'task' and uid = %d and id = %d limit 1", intval(local_channel()), intval(argv(2)) ); @@ -80,9 +80,9 @@ class Tasks extends \Zotlabs\Web\Controller { $event['account'] = $channel['channel_account_id']; $event['uid'] = $channel['channel_id']; $event['event_xchan'] = $channel['channel_hash']; - $event['type'] = 'task'; + $event['etype'] = 'task'; $event['nofinish'] = true; - $event['created'] = $event['edited'] = $event['start'] = datetime_convert(); + $event['created'] = $event['edited'] = $event['dtstart'] = datetime_convert(); $event['adjust'] = 1; $event['allow_cid'] = '<' . $channel['channel_hash'] . '>'; $event['summary'] = escape_tags($_REQUEST['summary']); @@ -92,21 +92,13 @@ class Tasks extends \Zotlabs\Web\Controller { else $x = array('success' => false); json_return_and_die($x); - } - - + } } - - - - - function get() { - + function get() { if(! local_channel()) return; - - + return ''; } } diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index 6fc5219d8..e23cce565 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -212,7 +212,7 @@ class Thing extends \Zotlabs\Web\Controller { $arr['verb'] = $verb; $arr['obj_type'] = $objtype; - $arr['object'] = $obj; + $arr['obj'] = $obj; if(! $profile['is_default']) { $arr['item_private'] = true; -- cgit v1.2.3 From b70c6809648bb3c78e5e26f9293727b3a7aa4025 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 2 Jun 2016 22:27:26 -0400 Subject: Major corrections to access control and page construction. --- Zotlabs/Module/Wiki.php | 211 +++++++++++++++++++++++++----------------------- 1 file changed, 109 insertions(+), 102 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 0f8db9350..ef7b4dfe1 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -6,19 +6,18 @@ class Wiki extends \Zotlabs\Web\Controller { function init() { // Determine which channel's wikis to display to the observer - $which = null; - if(argc() > 1) - $which = argv(1); // if the channel name is in the URL, use that - if(! $which) { // if no channel name was provided, assume the current logged in channel - if(local_channel()) { - $channel = \App::get_channel(); - if($channel && $channel['channel_address']) - $which = $channel['channel_address']; - goaway(z_root().'/wiki/'.$which); + $nick = null; + if (argc() > 1) + $nick = argv(1); // if the channel name is in the URL, use that + if (!$nick && local_channel()) { // if no channel name was provided, assume the current logged in channel + $channel = \App::get_channel(); + if ($channel && $channel['channel_address']) { + $nick = $channel['channel_address']; + goaway(z_root() . '/wiki/' . $nick); } } - if(! $which) { - notice( t('You must be logged in to see this page.') . EOL ); + if (!$nick) { + notice(t('You must be logged in to see this page.') . EOL); goaway('/login'); } } @@ -31,95 +30,103 @@ class Wiki extends \Zotlabs\Web\Controller { $wiki_owner = false; $showNewWikiButton = false; $pageHistory = array(); - if(local_channel()) { - $channel = \App::get_channel(); - } - - // Obtain the default permission settings of the channel - $channel_acl = array( - 'allow_cid' => $channel['channel_allow_cid'], - 'allow_gid' => $channel['channel_allow_gid'], - 'deny_cid' => $channel['channel_deny_cid'], - 'deny_gid' => $channel['channel_deny_gid'] - ); - // Initialize the ACL to the channel default permissions - $x = array( - 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl), - 'bang' => '' - ); - + $local_observer = null; $resource_id = ''; $pagename = ''; - if(argc() > 1) { - $channel = get_channel_by_nick(argv(1)); - if(local_channel() === intval($channel['channel_id'])) { - $wiki_owner = true; - } + + // init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1 + $nick = argv(1); + $channel = get_channel_by_nick($nick); // The channel who owns the wikis being viewed + if(! $channel) { + notice('Invalid channel' . EOL); + goaway('/' . argv(0)); } - // GET https://hubzilla.hub/argv(0)/argv(1)/argv(2)/argv(3)/argv(4)/... - if(argc() > 2) { - // GET /wiki/channel/wiki - // Check if wiki exists andr redirect if it does not - $w = wiki_exists_by_name($channel['channel_id'], argv(2)); - if(!$w['resource_id']) { - notice('Wiki not found' . EOL); - goaway('/'.argv(0).'/'.argv(1)); - } else { - $resource_id = $w['resource_id']; - } - if (!$wiki_owner) { - // Check for observer permissionswhich); - $observer_hash = get_observer_hash(); - $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); - if(!$perms['read']) { - notice('Permission denied.' . EOL); + // Determine if the observer is the channel owner so the ACL dialog can be populated + if (local_channel() === intval($channel['channel_id'])) { + $local_observer = \App::get_channel(); + $wiki_owner = true; + + // Obtain the default permission settings of the channel + $channel_acl = array( + 'allow_cid' => $local_observer['channel_allow_cid'], + 'allow_gid' => $local_observer['channel_allow_gid'], + 'deny_cid' => $local_observer['channel_deny_cid'], + 'deny_gid' => $local_observer['channel_deny_gid'] + ); + // Initialize the ACL to the channel default permissions + $x = array( + 'lockstate' => (( $local_observer['channel_allow_cid'] || + $local_observer['channel_allow_gid'] || + $local_observer['channel_deny_cid'] || + $local_observer['channel_deny_gid']) + ? 'lock' : 'unlock'), + 'acl' => populate_acl($channel_acl), + 'bang' => '' + ); + } else { + // Not the channel owner + $channel_acl = $x = array(); + } + + switch (argc()) { + case 2: + // Configure page template + $wikiheader = t('Wiki Sandbox'); + $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; + $hide_editor = false; + $showPageControls = false; + $showNewWikiButton = $wiki_owner; + $showNewPageButton = false; + break; + case 3: + // /wiki/channel/wiki -> No page was specified, so redirect to Home.md + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home.md'); + case 4: + // GET /wiki/channel/wiki/page + // Fetch the wiki info and determine observer permissions + $wikiname = argv(2); + $pagename = argv(3); + $w = wiki_exists_by_name($channel['channel_id'], $wikiname); + if(!$w['resource_id']) { + notice('Wiki not found' . EOL); goaway('/'.argv(0).'/'.argv(1)); + } + $resource_id = $w['resource_id']; + + if (!$wiki_owner) { + // Check for observer permissions + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['read']) { + notice('Permission denied.' . EOL); + goaway('/'.argv(0).'/'.argv(1)); + } } - } - } - - if(argc()<3) { - // GET /wiki/channel - $channel = get_channel_by_nick(argv(1)); - $wikiheader = t('Wiki Sandbox'); - $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; - $hide_editor = false; - $showPageControls = false; - $showNewWikiButton = $wiki_owner; - } elseif (argc()<4) { - // GET /wiki/channel/wiki - // No page was specified, so redirect to Home.md - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home.md'); - $wikiheader = rawurldecode(argv(2)); // show wiki name - $content = '""'; - $hide_editor = true; - // Until separate read and write permissions are implemented, only allow - // the wiki owner to see page controls - $showPageControls = $wiki_owner; - $showNewWikiButton = $wiki_owner; - } elseif (argc()<5) { - // GET /wiki/channel/wiki/page - $pagename = argv(3); - $wikiheader = rawurldecode(argv(2)) . ': ' . rawurldecode($pagename); // show wiki name and page - $p = wiki_get_page_content(array('wiki_resource_id' => $resource_id, 'page' => $pagename)); - if(!$p['success']) { - $content = 'Error retrieving page content. Try again.'; - } - $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); - $hide_editor = false; - $showPageControls = $wiki_owner; - $showNewWikiButton = $wiki_owner; - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + $wikiheader = rawurldecode($wikiname) . ': ' . rawurldecode($pagename); // show wiki name and page + $p = wiki_get_page_content(array('resource_id' => $resource_id, 'page' => $pagename)); + if(!$p['success']) { + notice('Error retrieving page content' . EOL); + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); + } + $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); + $hide_editor = false; + $showPageControls = $wiki_owner; + $showNewWikiButton = $wiki_owner; + $showNewPageButton = $wiki_owner; + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + break; + default: // Strip the extraneous URL components + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/'.argv(3)); } - require_once('library/markdown.php'); - $renderedContent = Markdown(json_decode($content)); + // Render the Markdown-formatted page content in HTML + require_once('library/markdown.php'); $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheader' => $wikiheader, '$hideEditor' => $hide_editor, '$showPageControls' => $showPageControls, '$showNewWikiButton'=> $showNewWikiButton, + '$showNewPageButton'=> $showNewPageButton, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, '$page' => $pagename, @@ -127,12 +134,12 @@ class Wiki extends \Zotlabs\Web\Controller { '$acl' => $x['acl'], '$bang' => $x['bang'], '$content' => $content, - '$renderedContent' => $renderedContent, + '$renderedContent' => Markdown(json_decode($content)), '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), '$pageHistory' => $pageHistory['history'] )); - head_add_js('library/ace/ace.js'); + head_add_js('library/ace/ace.js'); // Ace Code Editor return $o; } @@ -151,13 +158,13 @@ class Wiki extends \Zotlabs\Web\Controller { // Create a new wiki // /wiki/channel/create/wiki if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { - $which = argv(1); + $nick = argv(1); // Determine if observer has permission to create wiki $observer_hash = get_observer_hash(); if (local_channel()) { $channel = \App::get_channel(); } else { - $channel = get_channel_by_nick($which); + $channel = get_channel_by_nick($nick); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); // TODO: Create a new permission setting for wiki analogous to webpages. Until @@ -180,9 +187,9 @@ class Wiki extends \Zotlabs\Web\Controller { $homePage = wiki_create_page('Home.md', $r['item']['resource_id']); if(!$homePage['success']) { notice('Wiki created, but error creating Home page.'); - goaway('/wiki/'.$which.'/'.$name); + goaway('/wiki/'.$nick.'/'.$name); } - goaway('/wiki/'.$which.'/'.$name.'/Home.md'); + goaway('/wiki/'.$nick.'/'.$name.'/Home.md'); } else { notice('Error creating wiki'); goaway('/wiki'); @@ -191,12 +198,12 @@ class Wiki extends \Zotlabs\Web\Controller { // Delete a wiki if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) { - $which = argv(1); + $nick = argv(1); // Determine if observer has permission to create wiki if (local_channel()) { $channel = \App::get_channel(); } else { - $channel = get_channel_by_nick($which); + $channel = get_channel_by_nick($nick); $observer_hash = get_observer_hash(); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); @@ -219,13 +226,13 @@ class Wiki extends \Zotlabs\Web\Controller { // Create a page if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) { - $which = argv(1); + $nick = argv(1); $resource_id = $_POST['resource_id']; // Determine if observer has permission to create wiki if (local_channel()) { $channel = \App::get_channel(); } else { - $channel = get_channel_by_nick($which); + $channel = get_channel_by_nick($nick); $observer_hash = get_observer_hash(); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); @@ -273,7 +280,7 @@ class Wiki extends \Zotlabs\Web\Controller { // Save a page if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) { - $which = argv(1); + $nick = argv(1); $resource_id = $_POST['resource_id']; $pagename = escape_tags(urlencode($_POST['name'])); $content = escape_tags($_POST['content']); //Get new content @@ -281,7 +288,7 @@ class Wiki extends \Zotlabs\Web\Controller { if (local_channel()) { $channel = \App::get_channel(); } else { - $channel = get_channel_by_nick($which); + $channel = get_channel_by_nick($nick); $observer_hash = get_observer_hash(); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); @@ -319,14 +326,14 @@ class Wiki extends \Zotlabs\Web\Controller { // Update page history // /wiki/channel/history/page if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) { - $which = argv(1); + $nick = argv(1); $resource_id = $_POST['resource_id']; $pagename = escape_tags(urlencode($_POST['name'])); // Determine if observer has permission to view content if (local_channel()) { $channel = \App::get_channel(); } else { - $channel = get_channel_by_nick($which); + $channel = get_channel_by_nick($nick); $observer_hash = get_observer_hash(); $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); if (!$perms['read']) { -- cgit v1.2.3 From 390ce207db5b2e0a68e82cb80b6667431e07d31c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 2 Jun 2016 20:31:34 -0700 Subject: experimental emoji support --- Zotlabs/Module/React.php | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Zotlabs/Module/React.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php new file mode 100644 index 000000000..85a1e2350 --- /dev/null +++ b/Zotlabs/Module/React.php @@ -0,0 +1,50 @@ + Date: Fri, 3 Jun 2016 18:39:11 -0700 Subject: missed table rename in event query in mod_manage --- Zotlabs/Module/Manage.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Manage.php b/Zotlabs/Module/Manage.php index 5ae79dbb2..4ca044c4a 100644 --- a/Zotlabs/Module/Manage.php +++ b/Zotlabs/Module/Manage.php @@ -93,9 +93,9 @@ class Manage extends \Zotlabs\Web\Controller { $channels[$x]['mail'] = intval($mails[0]['total']); - $events = q("SELECT type, start, adjust FROM `event` - WHERE `event`.`uid` = %d AND start < '%s' AND start > '%s' and `ignore` = 0 - ORDER BY `start` ASC ", + $events = q("SELECT etype, dtstart, adjust FROM `event` + WHERE `event`.`uid` = %d AND dtstart < '%s' AND dtstart > '%s' and `dismissed` = 0 + ORDER BY `dtstart` ASC ", intval($channels[$x]['channel_id']), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + 7 days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) @@ -108,14 +108,14 @@ class Manage extends \Zotlabs\Web\Controller { $str_now = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d'); foreach($events as $e) { $bd = false; - if($e['type'] === 'birthday') { + if($e['etype'] === 'birthday') { $channels[$x]['birthdays'] ++; $bd = true; } else { $channels[$x]['events'] ++; } - if(datetime_convert('UTC', ((intval($e['adjust'])) ? date_default_timezone_get() : 'UTC'), $e['start'], 'Y-m-d') === $str_now) { + if(datetime_convert('UTC', ((intval($e['adjust'])) ? date_default_timezone_get() : 'UTC'), $e['dtstart'], 'Y-m-d') === $str_now) { $channels[$x]['all_events_today'] ++; if($bd) $channels[$x]['birthdays_today'] ++; -- cgit v1.2.3 From af4352adf28ed56187a53b739098e78f423cb920 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 3 Jun 2016 18:46:59 -0700 Subject: need to set item_origin on locally created reactions so they propagate properly --- Zotlabs/Module/React.php | 1 + 1 file changed, 1 insertion(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index 85a1e2350..28c7c239c 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -30,6 +30,7 @@ class React extends \Zotlabs\Web\Controller { $n = array(); $n['aid'] = $channel['channel_account_id']; $n['uid'] = $channel['channel_id']; + $n['item_origin'] = true; $n['parent'] = $postid; $n['parent_mid'] = $i[0]['mid']; $n['mid'] = item_message_id(); -- cgit v1.2.3 From b5d8443f59d96cece2357b6a791fe8ffe854dd95 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 06:26:41 -0400 Subject: Created three distinct names for wiki and page that are suitable for URL, HTML, and raw display. Implemented in new wiki POST activity only so far. --- Zotlabs/Module/Wiki.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index ef7b4dfe1..c74fc6c6f 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -174,22 +174,26 @@ class Wiki extends \Zotlabs\Web\Controller { goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); } } - $name = escape_tags(urlencode($_POST['wikiName'])); //Get new wiki name - if($name === '') { + $wiki = array(); + // Generate new wiki info from input name + $wiki['rawName'] = $_POST['wikiName']; + $wiki['htmlName'] = escape_tags($_POST['wikiName']); + $wiki['urlName'] = urlencode(escape_tags($_POST['wikiName'])); + if($wiki['urlName'] === '') { notice('Error creating wiki. Invalid name.'); goaway('/wiki'); } // Get ACL for permissions $acl = new \Zotlabs\Access\AccessList($channel); $acl->set_from_array($_POST); - $r = wiki_create_wiki($channel, $observer_hash, $name, $acl); + $r = wiki_create_wiki($channel, $observer_hash, $wiki, $acl); if ($r['success']) { - $homePage = wiki_create_page('Home.md', $r['item']['resource_id']); + $homePage = wiki_create_page('Home', $r['item']['resource_id']); if(!$homePage['success']) { notice('Wiki created, but error creating Home page.'); - goaway('/wiki/'.$nick.'/'.$name); + goaway('/wiki/'.$nick.'/'.$wiki['urlName']); } - goaway('/wiki/'.$nick.'/'.$name.'/Home.md'); + goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['urlName']); } else { notice('Error creating wiki'); goaway('/wiki'); -- cgit v1.2.3 From b84f7cd37fdad61e04878580645cab8c53c666f4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 03:32:03 -0700 Subject: class functions called incorrectly --- Zotlabs/Module/Admin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 4cabd78ca..b2c6baf1d 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1547,8 +1547,8 @@ class Admin extends \Zotlabs\Web\Controller { // Toggle theme status - toggle_theme($themes, $theme, $result); - $s = rebuild_theme_table($themes); + $this->toggle_theme($themes, $theme, $result); + $s = $this->rebuild_theme_table($themes); if($result) info( sprintf('Theme %s enabled.', $theme)); else @@ -1561,7 +1561,7 @@ class Admin extends \Zotlabs\Web\Controller { // display theme details require_once('library/markdown.php'); - if (theme_status($themes,$theme)) { + if ($this->theme_status($themes,$theme)) { $status="on"; $action= t("Disable"); } else { $status="off"; $action= t("Enable"); -- cgit v1.2.3 From 344c293424716cc53eed2fea9eb3a7512e725516 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 15:12:04 -0400 Subject: Wiki and page filenames are abstracted from their displayed names. Special characters do not seem to break things. --- Zotlabs/Module/Wiki.php | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index c74fc6c6f..ef42c85cf 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -80,13 +80,13 @@ class Wiki extends \Zotlabs\Web\Controller { break; case 3: // /wiki/channel/wiki -> No page was specified, so redirect to Home.md - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home.md'); + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home'); case 4: // GET /wiki/channel/wiki/page // Fetch the wiki info and determine observer permissions - $wikiname = argv(2); - $pagename = argv(3); - $w = wiki_exists_by_name($channel['channel_id'], $wikiname); + $wikiUrlName = urlencode(argv(2)); + $pageUrlName = urlencode(argv(3)); + $w = wiki_exists_by_name($channel['channel_id'], $wikiUrlName); if(!$w['resource_id']) { notice('Wiki not found' . EOL); goaway('/'.argv(0).'/'.argv(1)); @@ -102,8 +102,8 @@ class Wiki extends \Zotlabs\Web\Controller { goaway('/'.argv(0).'/'.argv(1)); } } - $wikiheader = rawurldecode($wikiname) . ': ' . rawurldecode($pagename); // show wiki name and page - $p = wiki_get_page_content(array('resource_id' => $resource_id, 'page' => $pagename)); + $wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page + $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if(!$p['success']) { notice('Error retrieving page content' . EOL); goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); @@ -113,7 +113,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = $wiki_owner; $showNewWikiButton = $wiki_owner; $showNewPageButton = $wiki_owner; - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; default: // Strip the extraneous URL components goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/'.argv(3)); @@ -129,7 +129,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$showNewPageButton'=> $showNewPageButton, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, - '$page' => $pagename, + '$page' => $pageUrlName, '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], @@ -178,7 +178,7 @@ class Wiki extends \Zotlabs\Web\Controller { // Generate new wiki info from input name $wiki['rawName'] = $_POST['wikiName']; $wiki['htmlName'] = escape_tags($_POST['wikiName']); - $wiki['urlName'] = urlencode(escape_tags($_POST['wikiName'])); + $wiki['urlName'] = urlencode($_POST['wikiName']); if($wiki['urlName'] === '') { notice('Error creating wiki. Invalid name.'); goaway('/wiki'); @@ -193,7 +193,7 @@ class Wiki extends \Zotlabs\Web\Controller { notice('Wiki created, but error creating Home page.'); goaway('/wiki/'.$nick.'/'.$wiki['urlName']); } - goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['urlName']); + goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']); } else { notice('Error creating wiki'); goaway('/wiki'); @@ -252,13 +252,13 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $name = escape_tags(urlencode($_POST['name'])); //Get new page name - if($name === '') { + $name = $_POST['name']; //Get new page name + if(urlencode(escape_tags($_POST['name'])) === '') { json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false)); } - $page = wiki_create_page($name . '.md', $resource_id); + $page = wiki_create_page($name, $resource_id); if ($page['success']) { - json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki'].'/'.$name.'.md', 'success' => true)); + json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']), 'success' => true)); } else { logger('Error creating page'); json_return_and_die(array('message' => 'Error creating page.', 'success' => false)); @@ -286,7 +286,9 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) { $nick = argv(1); $resource_id = $_POST['resource_id']; - $pagename = escape_tags(urlencode($_POST['name'])); + $pageUrlName = $_POST['name']; + logger('pageURLname: ' . $pageUrlName); + $pageHtmlName = escape_tags($_POST['name']); $content = escape_tags($_POST['content']); //Get new content // Determine if observer has permission to save content if (local_channel()) { @@ -308,14 +310,14 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $saved = wiki_save_page(array('resource_id' => $resource_id, 'name' => $pagename, 'content' => $content)); + $saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content)); if($saved['success']) { $ob = \App::get_observer(); $commit = wiki_git_commit(array( - 'commit_msg' => 'Updated ' . $pagename, + 'commit_msg' => 'Updated ' . $pageHtmlName, 'resource_id' => $resource_id, 'observer' => $ob, - 'files' => array($pagename) + 'files' => array($pageUrlName.'.md') )); if($commit['success']) { json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true)); @@ -332,7 +334,7 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) { $nick = argv(1); $resource_id = $_POST['resource_id']; - $pagename = escape_tags(urlencode($_POST['name'])); + $pageUrlName = $_POST['name']; // Determine if observer has permission to view content if (local_channel()) { $channel = \App::get_channel(); @@ -347,7 +349,7 @@ class Wiki extends \Zotlabs\Web\Controller { } $historyHTML = widget_wiki_page_history(array( 'resource_id' => $resource_id, - 'page' => $pagename + 'pageUrlName' => $pageUrlName )); json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true)); } -- cgit v1.2.3 From 4bc4fd5b7ebd7c5f25cfc9acfbda5b14a38dedb8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 18:00:32 -0400 Subject: Page deletion implemented. Hide the delete button and disallow for Home page. --- Zotlabs/Module/Wiki.php | 55 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index ef42c85cf..e335e8917 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -80,7 +80,8 @@ class Wiki extends \Zotlabs\Web\Controller { break; case 3: // /wiki/channel/wiki -> No page was specified, so redirect to Home.md - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home'); + $wikiUrlName = urlencode(argv(2)); + goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/Home'); case 4: // GET /wiki/channel/wiki/page // Fetch the wiki info and determine observer permissions @@ -106,7 +107,7 @@ class Wiki extends \Zotlabs\Web\Controller { $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if(!$p['success']) { notice('Error retrieving page content' . EOL); - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); + goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName); } $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); $hide_editor = false; @@ -116,7 +117,7 @@ class Wiki extends \Zotlabs\Web\Controller { $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; default: // Strip the extraneous URL components - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/'.argv(3)); + goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName); } // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); @@ -287,7 +288,6 @@ class Wiki extends \Zotlabs\Web\Controller { $nick = argv(1); $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; - logger('pageURLname: ' . $pageUrlName); $pageHtmlName = escape_tags($_POST['name']); $content = escape_tags($_POST['content']); //Get new content // Determine if observer has permission to save content @@ -354,6 +354,53 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true)); } + // Delete a page + if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) { + $nick = argv(1); + $resource_id = $_POST['resource_id']; + $pageUrlName = $_POST['name']; + if ($pageUrlName === 'Home') { + json_return_and_die(array('message' => 'Cannot delete Home','success' => false)); + } + // Determine if observer has permission to delete pages + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($nick); + $observer_hash = get_observer_hash(); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + logger('Wiki editing permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['write']) { + logger('Wiki write permission denied. Read only.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $deleted = wiki_delete_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); + if($deleted['success']) { + $ob = \App::get_observer(); + $commit = wiki_git_commit(array( + 'commit_msg' => 'Deleted ' . $pageHtmlName, + 'resource_id' => $resource_id, + 'observer' => $ob, + 'files' => null + )); + if($commit['success']) { + json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error making git commit','success' => false)); + } + } else { + json_return_and_die(array('message' => 'Error deleting page', 'success' => false)); + } + } + //notice('You must be authenticated.'); json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); -- cgit v1.2.3 From a0d339f208ce991ccc429e7d4ac1bbacce393b38 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 15:53:30 -0700 Subject: short-term solution to emoji size issue - make them 32px from the sender --- Zotlabs/Module/React.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index 28c7c239c..ed4f87e7e 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -35,7 +35,7 @@ class React extends \Zotlabs\Web\Controller { $n['parent_mid'] = $i[0]['mid']; $n['mid'] = item_message_id(); $n['verb'] = ACTIVITY_REACT . '#' . $emoji; - $n['body'] = "\n\n[zmg]" . z_root() . '/images/emoji/' . $emoji . '.png[/zmg]' . "\n\n"; + $n['body'] = "\n\n[zmg=32x32]" . z_root() . '/images/emoji/' . $emoji . '.png[/zmg]' . "\n\n"; $n['author_xchan'] = $channel['channel_hash']; $x = item_store($n); -- cgit v1.2.3 From 0a3fbdd128dd3b80868c93cb93901b501edf576c Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 16:32:03 -0400 Subject: Basic page reversion implemented. The revert button on the history view replaces the editor text but does not save the page. --- Zotlabs/Module/Wiki.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index e335e8917..5b5bfe87f 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -401,6 +401,41 @@ class Wiki extends \Zotlabs\Web\Controller { } } + // Revert a page + if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) { + $nick = argv(1); + $resource_id = $_POST['resource_id']; + $pageUrlName = $_POST['name']; + $commitHash = $_POST['commitHash']; + // Determine if observer has permission to revert pages + if (local_channel()) { + $channel = \App::get_channel(); + } else { + $channel = get_channel_by_nick($nick); + $observer_hash = get_observer_hash(); + // Figure out who the page owner is. + $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + logger('Wiki editing permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['write']) { + logger('Wiki write permission denied. Read only.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $reverted = wiki_revert_page(array('commitHash' => $commitHash, 'observer' => \App::get_observer(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); + if($reverted['success']) { + json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true)); + } else { + json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false)); + } + } + + //notice('You must be authenticated.'); json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); -- cgit v1.2.3 From b8b50bdb5abb5403f3f8a8662b7db0703b39073b Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 20:30:45 -0400 Subject: Custom commit message available. Improved history viewer and feedback from revert buttons. --- Zotlabs/Module/Wiki.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 5b5bfe87f..a1dc317ff 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -29,6 +29,7 @@ class Wiki extends \Zotlabs\Web\Controller { // Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...) $wiki_owner = false; $showNewWikiButton = false; + $showCommitMsg = false; $pageHistory = array(); $local_observer = null; $resource_id = ''; @@ -77,6 +78,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = false; $showNewWikiButton = $wiki_owner; $showNewPageButton = false; + $showCommitMsg = false; break; case 3: // /wiki/channel/wiki -> No page was specified, so redirect to Home.md @@ -114,6 +116,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = $wiki_owner; $showNewWikiButton = $wiki_owner; $showNewPageButton = $wiki_owner; + $showCommitMsg = true; $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; default: // Strip the extraneous URL components @@ -128,6 +131,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$showPageControls' => $showPageControls, '$showNewWikiButton'=> $showNewWikiButton, '$showNewPageButton'=> $showNewPageButton, + '$showCommitMsg' => $showCommitMsg, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, '$page' => $pageUrlName, @@ -138,6 +142,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$renderedContent' => Markdown(json_decode($content)), '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), + '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'), '$pageHistory' => $pageHistory['history'] )); head_add_js('library/ace/ace.js'); // Ace Code Editor @@ -290,6 +295,10 @@ class Wiki extends \Zotlabs\Web\Controller { $pageUrlName = $_POST['name']; $pageHtmlName = escape_tags($_POST['name']); $content = escape_tags($_POST['content']); //Get new content + $commitMsg = $_POST['commitMsg']; + if ($commitMsg === '') { + $commitMsg = 'Updated ' . $pageHtmlName; + } // Determine if observer has permission to save content if (local_channel()) { $channel = \App::get_channel(); @@ -314,7 +323,7 @@ class Wiki extends \Zotlabs\Web\Controller { if($saved['success']) { $ob = \App::get_observer(); $commit = wiki_git_commit(array( - 'commit_msg' => 'Updated ' . $pageHtmlName, + 'commit_msg' => $commitMsg, 'resource_id' => $resource_id, 'observer' => $ob, 'files' => array($pageUrlName.'.md') -- cgit v1.2.3 From 2af8105b460d300ba41928734c960f5f70613952 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 21:14:30 -0400 Subject: Hide page history viewer when viewing sandbox --- Zotlabs/Module/Wiki.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index a1dc317ff..0945ad919 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -30,10 +30,10 @@ class Wiki extends \Zotlabs\Web\Controller { $wiki_owner = false; $showNewWikiButton = false; $showCommitMsg = false; + $hidePageHistory = false; $pageHistory = array(); $local_observer = null; $resource_id = ''; - $pagename = ''; // init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1 $nick = argv(1); @@ -78,6 +78,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = false; $showNewWikiButton = $wiki_owner; $showNewPageButton = false; + $hidePageHistory = true; $showCommitMsg = false; break; case 3: @@ -116,6 +117,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = $wiki_owner; $showNewWikiButton = $wiki_owner; $showNewPageButton = $wiki_owner; + $hidePageHistory = false; $showCommitMsg = true; $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; @@ -131,6 +133,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$showPageControls' => $showPageControls, '$showNewWikiButton'=> $showNewWikiButton, '$showNewPageButton'=> $showNewPageButton, + '$hidePageHistory' => $hidePageHistory, '$showCommitMsg' => $showCommitMsg, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, -- cgit v1.2.3 From 037cd74e8e02f048892208bedef0d16faef16af4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 6 Jun 2016 19:44:22 -0700 Subject: rename admin/users to admin/accounts, provide sortable columns in account and channel summaries - issue #255 --- Zotlabs/Module/Admin.php | 106 ++++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 43 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index b2c6baf1d..21ab7f6a7 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -32,8 +32,8 @@ class Admin extends \Zotlabs\Web\Controller { case 'site': $this->admin_page_site_post($a); break; - case 'users': - $this->admin_page_users_post($a); + case 'accounts': + $this->admin_page_accounts_post($a); break; case 'channels': $this->admin_page_channels_post($a); @@ -127,8 +127,8 @@ class Admin extends \Zotlabs\Web\Controller { case 'site': $o = $this->admin_page_site($a); break; - case 'users': - $o = $this->admin_page_users($a); + case 'accounts': + $o = $this->admin_page_accounts($a); break; case 'channels': $o = $this->admin_page_channels($a); @@ -872,20 +872,20 @@ class Admin extends \Zotlabs\Web\Controller { } /** - * @brief Handle POST actions on users admin page. + * @brief Handle POST actions on accounts admin page. * * This function is called when on the admin user/account page the form was * submitted to handle multiple operations at once. If one of the icons next - * to an entry are pressed the function admin_page_users() will handle this. + * to an entry are pressed the function admin_page_accounts() will handle this. * * @param App $a */ - function admin_page_users_post($a) { + function admin_page_accounts_post($a) { $pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); $users = ( x($_POST, 'user') ? $_POST['user'] : array() ); $blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); - check_form_security_token_redirectOnErr('/admin/users', 'admin_users'); + check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts'); // change to switch structure? // account block/unblock button was submitted @@ -901,7 +901,7 @@ class Admin extends \Zotlabs\Web\Controller { notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) ); } // account delete button was submitted - if (x($_POST, 'page_users_delete')) { + if (x($_POST, 'page_accounts_delete')) { foreach ($users as $uid){ account_remove($uid, true, false); } @@ -920,20 +920,20 @@ class Admin extends \Zotlabs\Web\Controller { } } - goaway(z_root() . '/admin/users' ); + goaway(z_root() . '/admin/accounts' ); } /** - * @brief Generate users admin page and handle single item operations. + * @brief Generate accounts admin page and handle single item operations. * - * This function generates the users/account admin page and handles the actions + * This function generates the accounts/account admin page and handles the actions * if an icon next to an entry was clicked. If several items were selected and - * the form was submitted it is handled by the function admin_page_users_post(). + * the form was submitted it is handled by the function admin_page_accounts_post(). * * @param App &$a * @return string */ - function admin_page_users(&$a){ + function admin_page_accounts(&$a){ if (argc() > 2) { $uid = argv(3); $account = q("SELECT * FROM account WHERE account_id = %d", @@ -942,10 +942,10 @@ class Admin extends \Zotlabs\Web\Controller { if (! $account) { notice( t('Account not found') . EOL); - goaway(z_root() . '/admin/users' ); + goaway(z_root() . '/admin/accounts' ); } - check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't'); + check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't'); switch (argv(2)){ case 'delete': @@ -972,7 +972,7 @@ class Admin extends \Zotlabs\Web\Controller { break; } - goaway(z_root() . '/admin/users' ); + goaway(z_root() . '/admin/accounts' ); } /* get pending */ @@ -980,7 +980,7 @@ class Admin extends \Zotlabs\Web\Controller { intval(ACCOUNT_PENDING) ); - /* get users */ + /* get accounts */ $total = q("SELECT count(*) as total FROM account"); if (count($total)) { @@ -988,22 +988,20 @@ class Admin extends \Zotlabs\Web\Controller { \App::set_pager_itemspage(100); } - - // We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet. - // That's where we need to be doing last post/channel flags/etc, not here. - $serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : ''); + + $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id'); + $dir = 'asc'; + if(array_key_exists('dir',$_REQUEST)) + $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); + + $base = z_root() . '/admin/accounts?f='; + $odir = (($dir === 'asc') ? '0' : '1'); - $order = " order by account_email asc "; - if($_REQUEST['order'] === 'expires') - $order = " order by account_expires desc "; - if($_REQUEST['order'] === 'created') - $order = " order by account_created desc "; - - $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d )>0 as `blocked`, " . + $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " . "(SELECT %s FROM channel as ch " . "WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " . - "FROM account as ac where true $serviceclass $order limit %d offset %d ", + "FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ", intval(ACCOUNT_BLOCKED), db_concat('ch.channel_address', ' '), intval(\App::$pager['itemspage']), @@ -1026,14 +1024,14 @@ class Admin extends \Zotlabs\Web\Controller { // } // $users = array_map("_setup_users", $users); - $t = get_markup_template('admin_users.tpl'); + $t = get_markup_template('admin_accounts.tpl'); $o = replace_macros($t, array( // strings // '$title' => t('Administration'), - '$page' => t('Users'), + '$page' => t('Accounts'), '$submit' => t('Submit'), '$select_all' => t('select all'), - '$h_pending' => t('User registrations waiting for confirm'), + '$h_pending' => t('Registrations waiting for confirm'), '$th_pending' => array( t('Request date'), t('Email') ), '$no_pending' => t('No registrations.'), '$approve' => t('Approve'), @@ -1041,14 +1039,22 @@ class Admin extends \Zotlabs\Web\Controller { '$delete' => t('Delete'), '$block' => t('Block'), '$unblock' => t('Unblock'), - - '$h_users' => t('Users'), - '$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')), + '$odir' => $odir, + '$base' => $base, + '$h_users' => t('Accounts'), + '$th_users' => array( + [ t('ID'), 'account_id' ], + [ t('Email'), 'account_email' ], + [ t('All Channels'), 'channels' ], + [ t('Register date'), 'account_created' ], + [ t('Last login'), 'account_lastlog' ], + [ t('Expires'), 'account_expires' ], + [ t('Service Class'), 'account_service_class'] ), '$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'), '$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'), - '$form_security_token' => get_form_security_token("admin_users"), + '$form_security_token' => get_form_security_token("admin_accounts"), // values // '$baseurl' => z_root(), @@ -1158,6 +1164,17 @@ class Admin extends \Zotlabs\Web\Controller { } goaway(z_root() . '/admin/channels' ); } + + + $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); + $dir = 'asc'; + if(array_key_exists('dir',$_REQUEST)) + $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); + + $base = z_root() . '/admin/channels?f='; + $odir = (($dir === 'asc') ? '0' : '1'); + + /* get channels */ @@ -1166,14 +1183,12 @@ class Admin extends \Zotlabs\Web\Controller { \App::set_pager_total($total[0]['total']); \App::set_pager_itemspage(100); } - - $order = " order by channel_name asc "; - - $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ", + + $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']) ); - + if($channels) { for($x = 0; $x < count($channels); $x ++) { if($channels[$x]['channel_pageflags'] & PAGE_CENSORED) @@ -1201,7 +1216,12 @@ class Admin extends \Zotlabs\Web\Controller { '$code' => t('Allow Code'), '$uncode' => t('Disallow Code'), '$h_channels' => t('Channel'), - '$th_channels' => array( t('UID'), t('Name'), t('Address')), + '$base' => $base, + '$odir' => $odir, + '$th_channels' => array( + [ t('UID'), 'channel_id' ], + [ t('Name'), 'channel_name' ], + [ t('Address'), 'channel_address' ]), '$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'), '$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'), -- cgit v1.2.3 From a50e555515f9635610c28a5756875ae8629f4eb9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 7 Jun 2016 16:23:14 -0700 Subject: 'recent photos' query was buggered, also fix issue #163 by adding configurable sort order to the album widget - default is album name ascending --- Zotlabs/Module/Photos.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index ada7b4ef1..1bdc23897 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -510,7 +510,7 @@ class Photos extends \Zotlabs\Web\Controller { - function get() { + function get() { // URLs: // photos/name @@ -1277,11 +1277,9 @@ class Photos extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; - $r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' + $r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", intval(\App::$data['channel']['channel_id']), - dbesc('Contact Photos'), - dbesc( t('Contact Photos')), intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval($unsafe) @@ -1291,15 +1289,13 @@ class Photos extends \Zotlabs\Web\Controller { \App::set_pager_itemspage(60); } - $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo as p - INNER JOIN ( SELECT resource_id, max(imgscale) as imgscale FROM photo + $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p + INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND photo_usage IN ( %d, %d ) - AND is_nsfw = %d $sql_extra group by resource_id ) as ph + AND is_nsfw = %d $sql_extra group by resource_id ) ph ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale) ORDER by p.created DESC LIMIT %d OFFSET %d", intval(\App::$data['channel']['channel_id']), - dbesc('Contact Photos'), - dbesc( t('Contact Photos')), intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval($unsafe), -- cgit v1.2.3 From 9410b63bbc819955964706c876bc2f7ecea10adf Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 8 Jun 2016 06:26:27 -0400 Subject: Revised permissions checks across API and enabled collaborative editing using the write_pages per-channel permission. --- Zotlabs/Module/Wiki.php | 139 +++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 79 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 0945ad919..fbf751ddf 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -105,6 +105,13 @@ class Wiki extends \Zotlabs\Web\Controller { notice('Permission denied.' . EOL); goaway('/'.argv(0).'/'.argv(1)); } + if($perms['write']) { + $wiki_editor = true; + } else { + $wiki_editor = false; + } + } else { + $wiki_editor = true; } $wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); @@ -114,9 +121,9 @@ class Wiki extends \Zotlabs\Web\Controller { } $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); $hide_editor = false; - $showPageControls = $wiki_owner; + $showPageControls = $wiki_editor; $showNewWikiButton = $wiki_owner; - $showNewPageButton = $wiki_owner; + $showNewPageButton = $wiki_editor; $hidePageHistory = false; $showCommitMsg = true; $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); @@ -168,11 +175,15 @@ class Wiki extends \Zotlabs\Web\Controller { // /wiki/channel/create/wiki if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) { $nick = argv(1); + $channel = get_channel_by_nick($nick); // Determine if observer has permission to create wiki $observer_hash = get_observer_hash(); - if (local_channel()) { - $channel = \App::get_channel(); - } else { + // Only the channel owner can create a wiki, at least until we create a + // more detail permissions framework + if (local_channel() !== intval($channel['channel_id'])) { + goaway('/'.argv(0).'/'.$nick.'/'); + } else { + /* $channel = get_channel_by_nick($nick); // Figure out who the page owner is. $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); @@ -180,8 +191,9 @@ class Wiki extends \Zotlabs\Web\Controller { // then, use webpage permissions if (!$perms['write_pages']) { notice(t('Permission denied.') . EOL); - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); + goaway('/'.argv(0).'/'.argv(1).'/'); } + */ } $wiki = array(); // Generate new wiki info from input name @@ -212,10 +224,14 @@ class Wiki extends \Zotlabs\Web\Controller { // Delete a wiki if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) { $nick = argv(1); - // Determine if observer has permission to create wiki - if (local_channel()) { - $channel = \App::get_channel(); - } else { + $channel = get_channel_by_nick($nick); + // Only the channel owner can delete a wiki, at least until we create a + // more detail permissions framework + if (local_channel() !== intval($channel['channel_id'])) { + logger('Wiki delete permission denied.' . EOL); + json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false)); + } else { + /* $channel = get_channel_by_nick($nick); $observer_hash = get_observer_hash(); // Figure out who the page owner is. @@ -226,14 +242,15 @@ class Wiki extends \Zotlabs\Web\Controller { logger('Wiki delete permission denied.' . EOL); json_return_and_die(array('success' => false)); } + */ } $resource_id = $_POST['resource_id']; $deleted = wiki_delete_wiki($resource_id); if ($deleted['success']) { - json_return_and_die(array('success' => true)); + json_return_and_die(array('message' => '', 'success' => true)); } else { logger('Error deleting wiki: ' . $resource_id); - json_return_and_die(array('success' => false)); + json_return_and_die(array('message' => 'Error deleting wiki', 'success' => false)); } } @@ -241,23 +258,13 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) { $nick = argv(1); $resource_id = $_POST['resource_id']; - // Determine if observer has permission to create wiki - if (local_channel()) { - $channel = \App::get_channel(); - } else { - $channel = get_channel_by_nick($nick); + // Determine if observer has permission to create a page + $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { $observer_hash = get_observer_hash(); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - logger('Wiki editing permission denied.' . EOL); - json_return_and_die(array('success' => false)); - } $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); if(!$perms['write']) { - logger('Wiki write permission denied. Read only.' . EOL); + logger('Wiki write permission denied. ' . EOL); json_return_and_die(array('success' => false)); } } @@ -279,10 +286,12 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = $_POST['resource_id']; // resource_id for wiki in db $channel = get_channel_by_nick(argv(1)); $observer_hash = get_observer_hash(); - $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); - if(!$perms['read']) { - logger('Wiki read permission denied.' . EOL); - json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false)); + if (local_channel() !== intval($channel['channel_id'])) { + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['read']) { + logger('Wiki read permission denied.' . EOL); + json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false)); + } } $page_list_html = widget_wiki_pages(array( 'resource_id' => $resource_id, @@ -293,7 +302,7 @@ class Wiki extends \Zotlabs\Web\Controller { // Save a page if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) { - $nick = argv(1); + $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; $pageHtmlName = escape_tags($_POST['name']); @@ -302,26 +311,18 @@ class Wiki extends \Zotlabs\Web\Controller { if ($commitMsg === '') { $commitMsg = 'Updated ' . $pageHtmlName; } + $nick = argv(1); + $channel = get_channel_by_nick($nick); // Determine if observer has permission to save content - if (local_channel()) { - $channel = \App::get_channel(); - } else { - $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { $observer_hash = get_observer_hash(); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - logger('Wiki editing permission denied.' . EOL); - json_return_and_die(array('success' => false)); - } $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); if(!$perms['write']) { - logger('Wiki write permission denied. Read only.' . EOL); + logger('Wiki write permission denied. ' . EOL); json_return_and_die(array('success' => false)); } } + $saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content)); if($saved['success']) { $ob = \App::get_observer(); @@ -344,17 +345,17 @@ class Wiki extends \Zotlabs\Web\Controller { // Update page history // /wiki/channel/history/page if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) { - $nick = argv(1); + $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; - // Determine if observer has permission to view content - if (local_channel()) { - $channel = \App::get_channel(); - } else { - $channel = get_channel_by_nick($nick); + + $nick = argv(1); + $channel = get_channel_by_nick($nick); + // Determine if observer has permission to read content + if (local_channel() !== intval($channel['channel_id'])) { $observer_hash = get_observer_hash(); $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); - if (!$perms['read']) { + if(!$perms['read']) { logger('Wiki read permission denied.' . EOL); json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false)); } @@ -368,29 +369,19 @@ class Wiki extends \Zotlabs\Web\Controller { // Delete a page if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) { - $nick = argv(1); $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; if ($pageUrlName === 'Home') { json_return_and_die(array('message' => 'Cannot delete Home','success' => false)); } // Determine if observer has permission to delete pages - if (local_channel()) { - $channel = \App::get_channel(); - } else { - $channel = get_channel_by_nick($nick); + $nick = argv(1); + $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { $observer_hash = get_observer_hash(); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - logger('Wiki editing permission denied.' . EOL); - json_return_and_die(array('success' => false)); - } $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); if(!$perms['write']) { - logger('Wiki write permission denied. Read only.' . EOL); + logger('Wiki write permission denied. ' . EOL); json_return_and_die(array('success' => false)); } } @@ -415,27 +406,17 @@ class Wiki extends \Zotlabs\Web\Controller { // Revert a page if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) { - $nick = argv(1); $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; $commitHash = $_POST['commitHash']; // Determine if observer has permission to revert pages - if (local_channel()) { - $channel = \App::get_channel(); - } else { - $channel = get_channel_by_nick($nick); + $nick = argv(1); + $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { $observer_hash = get_observer_hash(); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - logger('Wiki editing permission denied.' . EOL); - json_return_and_die(array('success' => false)); - } $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); if(!$perms['write']) { - logger('Wiki write permission denied. Read only.' . EOL); + logger('Wiki write permission denied.' . EOL); json_return_and_die(array('success' => false)); } } -- cgit v1.2.3 From 0dcea87b9944c106bce3e9604c8facf58fa9225f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 9 Jun 2016 16:20:16 -0700 Subject: namespace issue with openid reverse auth --- Zotlabs/Module/Rmagic.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Rmagic.php b/Zotlabs/Module/Rmagic.php index bcdbf6c90..26b0c46a6 100644 --- a/Zotlabs/Module/Rmagic.php +++ b/Zotlabs/Module/Rmagic.php @@ -24,7 +24,7 @@ class Rmagic extends \Zotlabs\Web\Controller { } } - function post() { + function post() { $address = trim($_REQUEST['address']); @@ -34,13 +34,13 @@ class Rmagic extends \Zotlabs\Web\Controller { try { require_once('library/openid/openid.php'); - $openid = new LightOpenID(z_root()); + $openid = new \LightOpenID(z_root()); $openid->identity = $address; $openid->returnUrl = z_root() . '/openid'; $openid->required = array('namePerson/friendly', 'namePerson'); $openid->optional = array('namePerson/first','media/image/aspect11','media/image/default'); goaway($openid->authUrl()); - } catch (Exception $e) { + } catch (\Exception $e) { notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'

    '. t('The error message was:').' '.$e->getMessage()); } @@ -82,7 +82,7 @@ class Rmagic extends \Zotlabs\Web\Controller { } - function get() { + function get() { $o = replace_macros(get_markup_template('rmagic.tpl'),array( '$title' => t('Remote Authentication'), -- cgit v1.2.3 From bb3d56a0b2e3676e780b4b6dd4e1b31b211c7b5e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 9 Jun 2016 22:07:27 -0700 Subject: foreach: invalid argument --- Zotlabs/Module/Acl.php | 28 +++++++++++++++------------- Zotlabs/Module/Admin.php | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 7bc197a93..2bc4ba62d 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -65,18 +65,20 @@ class Acl extends \Zotlabs\Web\Controller { intval($count), intval($start) ); - - foreach($r as $g){ - // logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id'])); - $groups[] = array( - "type" => "g", - "photo" => "images/twopeople.png", - "name" => $g['gname'], - "id" => $g['id'], - "xid" => $g['hash'], - "uids" => group_get_members_xchan($g['id']), - "link" => '' - ); + + if($r) { + foreach($r as $g){ + // logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id'])); + $groups[] = array( + "type" => "g", + "photo" => "images/twopeople.png", + "name" => $g['gname'], + "id" => $g['id'], + "xid" => $g['hash'], + "uids" => group_get_members_xchan($g['id']), + "link" => '' + ); + } } } @@ -204,7 +206,7 @@ class Acl extends \Zotlabs\Web\Controller { else $r = array(); - if(count($r)) { + if($r) { foreach($r as $g){ // remove RSS feeds from ACLs - they are inaccessible diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 21ab7f6a7..085d13fd7 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -1738,7 +1738,7 @@ class Admin extends \Zotlabs\Web\Controller { // name, label, value, help string, extra data... '$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""), - '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")), + '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")), '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices), '$form_security_token' => get_form_security_token('admin_logs'), -- cgit v1.2.3 From 410f5389ae90e1c219b097b051aaa9922e73efd5 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 12 Jun 2016 07:17:23 -0400 Subject: Apply purify_html to page content before preview and save to prevent JavaScript code injection. --- Zotlabs/Module/Wiki.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index fbf751ddf..1e6446904 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -167,7 +167,7 @@ class Wiki extends \Zotlabs\Web\Controller { if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; require_once('library/markdown.php'); - $html = Markdown($content); + $html = purify_html(Markdown($content)); json_return_and_die(array('html' => $html, 'success' => true)); } @@ -182,19 +182,7 @@ class Wiki extends \Zotlabs\Web\Controller { // more detail permissions framework if (local_channel() !== intval($channel['channel_id'])) { goaway('/'.argv(0).'/'.$nick.'/'); - } else { - /* - $channel = get_channel_by_nick($nick); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - notice(t('Permission denied.') . EOL); - goaway('/'.argv(0).'/'.argv(1).'/'); - } - */ - } + } $wiki = array(); // Generate new wiki info from input name $wiki['rawName'] = $_POST['wikiName']; @@ -306,7 +294,7 @@ class Wiki extends \Zotlabs\Web\Controller { $resource_id = $_POST['resource_id']; $pageUrlName = $_POST['name']; $pageHtmlName = escape_tags($_POST['name']); - $content = escape_tags($_POST['content']); //Get new content + $content = $_POST['content']; //Get new content $commitMsg = $_POST['commitMsg']; if ($commitMsg === '') { $commitMsg = 'Updated ' . $pageHtmlName; -- cgit v1.2.3 From b5933e9d442619a6782dfd8136fa9edba466a4e8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 12 Jun 2016 19:41:37 -0400 Subject: Photo embed button with album browser works in new post editor. --- Zotlabs/Module/Embedphotos.php | 180 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 Zotlabs/Module/Embedphotos.php (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php new file mode 100644 index 000000000..2cd420664 --- /dev/null +++ b/Zotlabs/Module/Embedphotos.php @@ -0,0 +1,180 @@ + 1 && argv(1) === 'album') { + // API: /embedphotos/album + $name = (x($_POST,'name') ? $_POST['name'] : null ); + if (!$name) { + json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false)); + } + $album = $this->embedphotos_widget_album(array('channel' => \App::get_channel(), 'album' => $name)); + json_return_and_die(array('status' => true, 'content' => $album)); + + } + if (argc() > 1 && argv(1) === 'albumlist') { + // API: /embedphotos/albumlist + $album_list = $this->embedphotos_album_list($a); + json_return_and_die(array('status' => true, 'albumlist' => $album_list)); + + } + if (argc() > 1 && argv(1) === 'photolink') { + // API: /embedphotos/photolink + $href = (x($_POST,'href') ? $_POST['href'] : null ); + if (!$href) { + json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false)); + } + $resource_id = array_pop(explode("/", $href)); + $r = q("SELECT obj from item where resource_type = 'photo' and resource_id = '%s' limit 1", + dbesc($resource_id) + ); + if(!$r) { + json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); + } + $obj = json_decode($r[0]['obj'], true); + if(x($obj,'body')) { + $photolink = $obj['body']; + } elseif (x($obj,'bbcode')) { + $photolink = $obj['bbcode']; + } else { + json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); + } + json_return_and_die(array('status' => true, 'photolink' => $photolink)); + + } + } + + +/** + * Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from + * the input array as in widget_item() + * @param type $name + * @return string + */ +function embedphotos_widget_album($args) { + + $channel_id = 0; + if(array_key_exists('channel',$args)) + $channel = $args['channel']; + $channel_id = intval($channel['channel_id']); + if(! $channel_id) + $channel_id = \App::$profile_uid; + if(! $channel_id) + return ''; + $owner_uid = $channel_id; + require_once('include/security.php'); + $sql_extra = permissions_sql($channel_id); + + if(! perm_is_allowed($channel_id,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) + ); + + $photos = array(); + if(count($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::$data['channel']['channel_address'] . '/image/' . $rr['resource_id'] + . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '')); + + $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; +} + + +function embedphotos_album_list($a) { + $o = ''; + require_once('include/photos.php'); + $p = photos_albums_list(\App::get_channel(), \App::get_observer()); + if ($p['success']) { + return $p['albums']; + } else { + return null; + } +} + +} -- cgit v1.2.3 From 1e68d4fb75b9831ed763328b7982e44d1d4cdc5b Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 13 Jun 2016 19:58:24 -0700 Subject: deprecate the item_id table - replace with iconfig. A possibly useful function in the iconfig class would be a search which takes a service id and type and uid, matches against an item and returns the iid. That could save a bit of code duplication. --- Zotlabs/Module/Block.php | 8 ++++---- Zotlabs/Module/Blocks.php | 13 ++++++++----- Zotlabs/Module/Display.php | 5 +++-- Zotlabs/Module/Editblock.php | 4 ++-- Zotlabs/Module/Editlayout.php | 5 +++-- Zotlabs/Module/Editwebpage.php | 4 ++-- Zotlabs/Module/Impel.php | 26 +++++++++----------------- Zotlabs/Module/Item.php | 30 +++++++++++++++--------------- Zotlabs/Module/Layouts.php | 20 +++++++++++--------- Zotlabs/Module/Page.php | 20 +++++++++----------- Zotlabs/Module/Webpages.php | 18 +++++++++++++----- 11 files changed, 79 insertions(+), 74 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Block.php b/Zotlabs/Module/Block.php index 062befdb5..45e61e4ea 100644 --- a/Zotlabs/Module/Block.php +++ b/Zotlabs/Module/Block.php @@ -52,8 +52,8 @@ class Block extends \Zotlabs\Web\Controller { require_once('include/security.php'); $sql_options = item_permissions_sql($u[0]['channel_id']); - $r = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and + $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 = 'BUILDBLOCK' and item_type = %d $sql_options $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), @@ -64,8 +64,8 @@ class Block extends \Zotlabs\Web\Controller { // Check again with no permissions clause to see if it is a permissions issue - $x = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and + $x = 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 = 'BUILDBLOCK' and item_type = %d $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php index 32650a090..475cfa6b3 100644 --- a/Zotlabs/Module/Blocks.php +++ b/Zotlabs/Module/Blocks.php @@ -27,7 +27,7 @@ class Blocks extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); @@ -111,8 +111,11 @@ class Blocks extends \Zotlabs\Web\Controller { $editor = status_editor($a,$x); - $r = q("select iid, sid, mid, title, body, mimetype, created, edited from item_id left join item on item_id.iid = item.id - where item_id.uid = %d and service = 'BUILDBLOCK' and item_type = %d order by item.created desc", + + $r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig + left join item on iconfig.iid = item.id + where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' + and item_type = %d order by item.created desc", intval($owner), intval(ITEM_TYPE_BLOCK) ); @@ -129,12 +132,12 @@ class Blocks extends \Zotlabs\Web\Controller { 'created' => $rr['created'], 'edited' => $rr['edited'], 'mimetype' => $rr['mimetype'], - 'pagetitle' => $rr['sid'], + 'pagetitle' => $rr['v'], 'mid' => $rr['mid'] ); $pages[$rr['iid']][] = array( 'url' => $rr['iid'], - 'name' => $rr['sid'], + 'name' => $rr['v'], 'title' => $rr['title'], 'created' => $rr['created'], 'edited' => $rr['edited'], diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index c1a0d84bc..d1d4edc7d 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -106,12 +106,13 @@ class Display extends \Zotlabs\Web\Controller { $x = q("select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1", + $y = q("select * from iconfig left join item on iconfig.iid = item.id + where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['id']) ); if($x && $y) { - goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']); + goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']); } else { notice( t('Page not found.') . EOL); diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index fb86557f2..1d6ef7a0a 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -85,11 +85,11 @@ class Editblock extends \Zotlabs\Web\Controller { intval($owner) ); if($itm) { - $item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1", + $item_id = q("select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1", intval($itm[0]['id']) ); if($item_id) - $block_title = $item_id[0]['sid']; + $block_title = $item_id[0]['v']; } else { notice( t('Item not found') . EOL); diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index 5028882d2..fe794b5fd 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -96,11 +96,12 @@ class Editlayout extends \Zotlabs\Web\Controller { intval($owner) ); - $item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1", + $item_id = q("select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1", intval($itm[0]['id']) ); if($item_id) - $layout_title = $item_id[0]['sid']; + $layout_title = $item_id[0]['v']; + $rp = 'layouts/' . $which; diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 1b5c320a0..6d67c08e7 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -114,11 +114,11 @@ class Editwebpage extends \Zotlabs\Web\Controller { $itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key); } - $item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1", + $item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1", intval($itm[0]['id']) ); if($item_id) - $page_title = $item_id[0]['sid']; + $page_title = $item_id[0]['v']; $mimetype = $itm[0]['mimetype']; diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php index e326f7818..735c311d0 100644 --- a/Zotlabs/Module/Impel.php +++ b/Zotlabs/Module/Impel.php @@ -137,9 +137,7 @@ class Impel extends \Zotlabs\Web\Controller { require_once('library/urlify/URLify.php'); $pagetitle = strtolower(\URLify::transliterate($j['pagetitle'])); } - - - + // Verify ability to use html or php!!! $execflag = false; @@ -154,21 +152,14 @@ class Impel extends \Zotlabs\Web\Controller { } } - $remote_id = 0; - - $z = q("select * from item_id where sid = '%s' and service = '%s' and uid = %d limit 1", - dbesc($pagetitle), - dbesc($namespace), - intval(local_channel()) - ); - $i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1", dbesc($arr['mid']), intval(local_channel()) ); + + \Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($pagetitle) ? $pagetitle : substr($arr['mid'],0,16)),true); - if($z && $i) { - $remote_id = $z[0]['id']; + if($i) { $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if($arr['edited'] > $i[0]['edited']) @@ -182,12 +173,12 @@ class Impel extends \Zotlabs\Web\Controller { intval(local_channel()) ); } - $x = item_store($arr,$execflag); + else + $x = item_store($arr,$execflag); } - if($x['success']) { + if($x && $x['success']) { $item_id = $x['item_id']; - update_remote_id($channel,$item_id,$arr['item_type'],$pagetitle,$namespace,$remote_id,$arr['mid']); } } @@ -199,7 +190,8 @@ class Impel extends \Zotlabs\Web\Controller { notice( sprintf( t('%s element installation failed'), $installed_type)); } - //??? should perhaps return ret? + //??? should perhaps return ret? + json_return_and_die(true); } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 2601feb0a..272da7971 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -1,4 +1,5 @@ array(encode_item($sync_item[0],true)),'item_id' => $rid)); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)))); } } if(! $nopush) @@ -978,10 +984,7 @@ class Item extends \Zotlabs\Web\Controller { goaway(z_root() . "/" . $return_path ); // NOTREACHED } - - - update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); - + if(($parent) && ($parent != $post_id)) { // Store the comment signature information in case we need to relay to Diaspora //$ditem = $datarray; @@ -995,10 +998,7 @@ class Item extends \Zotlabs\Web\Controller { if($r) { xchan_query($r); $sync_item = fetch_post_tags($r); - $rid = q("select * from item_id where iid = %d", - intval($post_id) - ); - build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); + build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)))); } } diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php index 9b9fc22f3..a0b1c31cc 100644 --- a/Zotlabs/Module/Layouts.php +++ b/Zotlabs/Module/Layouts.php @@ -90,13 +90,14 @@ class Layouts extends \Zotlabs\Web\Controller { return; } - //This feature is not exposed in redbasic ui since it is not clear why one would want to - //download a json encoded pdl file - we dont have a possibility to import it. - //Use the buildin share/install feature instead. + // This feature is not exposed in redbasic ui since it is not clear why one would want to + // download a json encoded pdl file - we dont have a possibility to import it. + // Use the buildin share/install feature instead. + if((argc() > 3) && (argv(2) === 'share') && (argv(3))) { - $r = q("select sid, service, mimetype, title, body from item_id - left join item on item.id = item_id.iid - where item_id.uid = %d and item.mid = '%s' and service = 'PDL' order by sid asc", + $r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig + left join item on item.id = iconfig.iid + where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc", intval($owner), dbesc(argv(3)) ); @@ -141,8 +142,9 @@ class Layouts extends \Zotlabs\Web\Controller { $editor = status_editor($a,$x); - $r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id - where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc", + $r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig + left join item on iconfig.iid = item.id + where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc", intval($owner), intval(ITEM_TYPE_PDL) ); @@ -164,7 +166,7 @@ class Layouts extends \Zotlabs\Web\Controller { ); $pages[$rr['iid']][] = array( 'url' => $rr['iid'], - 'title' => $rr['sid'], + 'title' => $rr['v'], 'descr' => $rr['title'], 'mid' => $rr['mid'], 'created' => $rr['created'], diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index 14273614c..deb23da68 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -65,9 +65,10 @@ class Page extends \Zotlabs\Web\Controller { require_once('include/security.php'); $sql_options = item_permissions_sql($u[0]['channel_id']); - $r = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and item.item_delayed = 0 and (( service = 'WEBPAGE' and item_type = %d ) - OR ( service = 'PDL' AND item_type = %d )) $sql_options $revision limit 1", + $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 item.item_delayed = 0 + and (( iconfig.k = 'WEBPAGE' and item_type = %d ) + OR ( iconfig.k = 'PDL' AND item_type = %d )) $sql_options $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), intval(ITEM_TYPE_WEBPAGE), @@ -77,9 +78,9 @@ class Page extends \Zotlabs\Web\Controller { // Check again with no permissions clause to see if it is a permissions issue - $x = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and item.item_delayed = 0 and service = 'WEBPAGE' and - item_type = %d $revision limit 1", + $x = 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 item.item_delayed = 0 + and iconfig.k = 'WEBPAGE' and item_type = %d $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), intval(ITEM_TYPE_WEBPAGE) @@ -119,11 +120,8 @@ class Page extends \Zotlabs\Web\Controller { \App::$data['webpage'] = $r; } - - - - - function get() { + + function get() { $r = \App::$data['webpage']; if(! $r) diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index bb8d454c8..fc292be6f 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -28,7 +28,7 @@ class Webpages extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); @@ -138,11 +138,19 @@ class Webpages extends \Zotlabs\Web\Controller { $sql_extra = item_permissions_sql($owner); - $r = q("select * from item_id left join item on item_id.iid = item.id - where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc", + + $r = q("select * from iconfig left join item on iconfig.iid = item.id + where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d + $sql_extra order by item.created desc", intval($owner), intval(ITEM_TYPE_WEBPAGE) ); + +// $r = q("select * from item_id left join item on item_id.iid = item.id +// where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc", +// intval($owner), +// intval(ITEM_TYPE_WEBPAGE) +// ); $pages = null; @@ -160,13 +168,13 @@ class Webpages extends \Zotlabs\Web\Controller { 'created' => $rr['created'], 'edited' => $rr['edited'], 'mimetype' => $rr['mimetype'], - 'pagetitle' => $rr['sid'], + 'pagetitle' => $rr['v'], 'mid' => $rr['mid'], 'layout_mid' => $rr['layout_mid'] ); $pages[$rr['iid']][] = array( 'url' => $rr['iid'], - 'pagetitle' => $rr['sid'], + 'pagetitle' => $rr['v'], 'title' => $rr['title'], 'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']), 'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']), -- cgit v1.2.3 From 0ef2622621867fa197988974b47eff85f20a80e7 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 13 Jun 2016 22:09:22 -0700 Subject: some work to provide propagation and honouring of the item_notshown flag. --- Zotlabs/Module/Wiki.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 1e6446904..f1f7b87b2 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -1,6 +1,6 @@ - Date: Tue, 14 Jun 2016 17:04:29 -0700 Subject: readme for the module directory, also provide an undocumented way to reset the timestamp on connection photos to force a refresh without messing with the database directly. --- Zotlabs/Module/Connedit.php | 22 ++++++++----- Zotlabs/Module/README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 Zotlabs/Module/README.md (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 33deac4c8..3feba5370 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -16,14 +16,14 @@ require_once('include/zot.php'); require_once('include/widgets.php'); require_once('include/photos.php'); -/* @brief Initialize the connection-editor - * - * - */ - class Connedit extends \Zotlabs\Web\Controller { + /* @brief Initialize the connection-editor + * + * + */ + function init() { if(! local_channel()) @@ -51,7 +51,7 @@ class Connedit extends \Zotlabs\Web\Controller { * */ - function post() { + function post() { if(! local_channel()) return; @@ -357,7 +357,7 @@ class Connedit extends \Zotlabs\Web\Controller { * */ - function get() { + function get() { $sort_type = 0; $o = ''; @@ -418,7 +418,13 @@ class Connedit extends \Zotlabs\Web\Controller { goaway(z_root() . '/connedit/' . $contact_id); } - + if($cmd === 'resetphoto') { + q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s' limit 1", + dbesc($orig_record[0]['xchan_hash']) + ); + $cmd = 'refresh'; + } + if($cmd === 'refresh') { if($orig_record[0]['xchan_network'] === 'zot') { if(! zot_refresh($orig_record[0],\App::get_channel())) diff --git a/Zotlabs/Module/README.md b/Zotlabs/Module/README.md new file mode 100644 index 000000000..3b870dd7b --- /dev/null +++ b/Zotlabs/Module/README.md @@ -0,0 +1,80 @@ +Zotlabs/Module +============== + + +This directory contains controller modules for handling web requests. The +lowercase class name indicates the head of the URL path which this module +handles. There are other methods of attaching (routing) URL paths to +controllers, but this is the primary method used in this project. + +Module controllers MUST reside in this directory and namespace to be +autoloaded (unless other specific routing methods are employed). They +typically use and extend the class definition in Zotlabs/Web/Controller +as a template. + +Template: + + Date: Wed, 15 Jun 2016 06:25:31 -0400 Subject: Rename page feature added. Fixed bug in git commit function and other minor fixes. --- Zotlabs/Module/Wiki.php | 54 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index f1f7b87b2..9e7d151b5 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -72,7 +72,8 @@ class Wiki extends \Zotlabs\Web\Controller { switch (argc()) { case 2: // Configure page template - $wikiheader = t('Wiki Sandbox'); + $wikiheaderName = t('Wiki'); + $wikiheaderPage = t('Sandbox'); $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; $hide_editor = false; $showPageControls = false; @@ -113,7 +114,8 @@ class Wiki extends \Zotlabs\Web\Controller { } else { $wiki_editor = true; } - $wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page + $wikiheaderName = urldecode($wikiUrlName); + $wikiheaderPage = urldecode($pageUrlName); $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if(!$p['success']) { notice('Error retrieving page content' . EOL); @@ -135,7 +137,8 @@ class Wiki extends \Zotlabs\Web\Controller { require_once('library/markdown.php'); $o .= replace_macros(get_markup_template('wiki.tpl'),array( - '$wikiheader' => $wikiheader, + '$wikiheaderName' => $wikiheaderName, + '$wikiheaderPage' => $wikiheaderPage, '$hideEditor' => $hide_editor, '$showPageControls' => $showPageControls, '$showNewWikiButton'=> $showNewWikiButton, @@ -152,6 +155,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$renderedContent' => Markdown(json_decode($content)), '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), + '$pageRename' => array('pageRename', t('Enter the new name:'), '', ''), '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'), '$pageHistory' => $pageHistory['history'] )); @@ -377,7 +381,7 @@ class Wiki extends \Zotlabs\Web\Controller { if($deleted['success']) { $ob = \App::get_observer(); $commit = wiki_git_commit(array( - 'commit_msg' => 'Deleted ' . $pageHtmlName, + 'commit_msg' => 'Deleted ' . $pageUrlName, 'resource_id' => $resource_id, 'observer' => $ob, 'files' => null @@ -416,6 +420,48 @@ class Wiki extends \Zotlabs\Web\Controller { } } + // Rename a page + if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) { + $resource_id = $_POST['resource_id']; + $pageUrlName = $_POST['oldName']; + $pageNewName = $_POST['newName']; + if ($pageUrlName === 'Home') { + json_return_and_die(array('message' => 'Cannot rename Home','success' => false)); + } + if(urlencode(escape_tags($pageNewName)) === '') { + json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false)); + } + // Determine if observer has permission to rename pages + $nick = argv(1); + $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['write']) { + logger('Wiki write permission denied. ' . EOL); + json_return_and_die(array('success' => false)); + } + } + $renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName)); + logger('$renamed: ' . json_encode($renamed)); + if($renamed['success']) { + $ob = \App::get_observer(); + $commit = wiki_git_commit(array( + 'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'], + 'resource_id' => $resource_id, + 'observer' => $ob, + 'files' => array($pageUrlName . '.md', $renamed['page']['fileName']), + 'all' => true + )); + if($commit['success']) { + json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error making git commit','success' => false)); + } + } else { + json_return_and_die(array('message' => 'Error renaming page', 'success' => false)); + } + } //notice('You must be authenticated.'); json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false)); -- cgit v1.2.3 From 961539258be90f5b7c989299db0e8c551d0d6c72 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 17 Jun 2016 06:33:39 -0400 Subject: Wiki page revision comparison tool with diff displayed in modal dialog. Leverages Diff class from http://code.stephenmorley.org/php/diff-implementation with license CC0 1.0 universal http://creativecommons.org/publicdomain/zero/1.0/legalcode --- Zotlabs/Module/Wiki.php | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 9e7d151b5..83fa0e337 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -136,6 +136,16 @@ class Wiki extends \Zotlabs\Web\Controller { // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); + $wikiModalID = random_string(3); + $wikiModal = replace_macros( + get_markup_template('generic_modal.tpl'), array( + '$id' => $wikiModalID, + '$title' => t('Revision Comparison'), + '$ok' => t('Revert'), + '$cancel' => t('Cancel') + ) + ); + $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, @@ -157,7 +167,10 @@ class Wiki extends \Zotlabs\Web\Controller { '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), '$pageRename' => array('pageRename', t('Enter the new name:'), '', ''), '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'), - '$pageHistory' => $pageHistory['history'] + '$pageHistory' => $pageHistory['history'], + '$wikiModal' => $wikiModal, + '$wikiModalID' => $wikiModalID, + '$commit' => 'HEAD' )); head_add_js('library/ace/ace.js'); // Ace Code Editor return $o; @@ -412,7 +425,7 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $reverted = wiki_revert_page(array('commitHash' => $commitHash, 'observer' => \App::get_observer(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); + $reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if($reverted['success']) { json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true)); } else { @@ -420,6 +433,31 @@ class Wiki extends \Zotlabs\Web\Controller { } } + // Compare page revisions + if ((argc() === 4) && (argv(2) === 'compare') && (argv(3) === 'page')) { + $resource_id = $_POST['resource_id']; + $pageUrlName = $_POST['name']; + $compareCommit = $_POST['compareCommit']; + $currentCommit = $_POST['currentCommit']; + // Determine if observer has permission to revert pages + $nick = argv(1); + $channel = get_channel_by_nick($nick); + if (local_channel() !== intval($channel['channel_id'])) { + $observer_hash = get_observer_hash(); + $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash); + if(!$perms['read']) { + logger('Wiki read permission denied.' . EOL); + json_return_and_die(array('success' => false)); + } + } + $compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); + if($compare['success']) { + json_return_and_die(array('diff' => $compare['diff'], 'message' => '', 'success' => true)); + } else { + json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false)); + } + } + // Rename a page if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) { $resource_id = $_POST['resource_id']; -- cgit v1.2.3 From c81f6b9f6f1ab7f7dc61e5343e52d4ccedbff5a1 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 17 Jun 2016 16:28:36 -0700 Subject: "thing" always showing default url, not that supplied by the thing. --- Zotlabs/Module/Thing.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index e23cce565..65fc0588e 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -26,7 +26,7 @@ class Thing extends \Zotlabs\Web\Controller { $verb = escape_tags($_REQUEST['verb']); $activity = intval($_REQUEST['activity']); $profile_guid = escape_tags($_REQUEST['profile_assign']); - $url = $_REQUEST['link']; + $url = $_REQUEST['url']; $photo = $_REQUEST['img']; $hash = random_string(); @@ -235,7 +235,7 @@ class Thing extends \Zotlabs\Web\Controller { } - function get() { + function get() { // @FIXME one problem with things is we can't share them unless we provide the channel in the url // so we can definitively lookup the owner. -- cgit v1.2.3 From a3ec9f394068d7dccef44c8f27c085cb380e54d5 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 20 Jun 2016 13:27:05 -0400 Subject: Add formatted heading for revision comparison viewer --- Zotlabs/Module/Wiki.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 83fa0e337..bef831de8 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -452,7 +452,8 @@ class Wiki extends \Zotlabs\Web\Controller { } $compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if($compare['success']) { - json_return_and_die(array('diff' => $compare['diff'], 'message' => '', 'success' => true)); + $diffHTML = '
    ' . t('Hub URL') . '' . t('Access Type') . '' . t('Registration Policy') . '' . t('Stats') . '' . t('Software') . '' . t('Ratings') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . '' . ucwords($jj['project']) . ' ' . t('View') . '
    ' . $urltext . '' . $location . '' . $jj['access'] . '' . $jj['register'] . '' . '' . ucwords($jj['project']) . ' ' . t('View') . '
    Current RevisionSelected Revision
    ' . $compare['diff']; + json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true)); } else { json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false)); } -- cgit v1.2.3 From 01bfadaeaa6440586aba74cf098b38a9a134a510 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 20 Jun 2016 13:42:04 -0700 Subject: fix siteinfo plugin list --- Zotlabs/Module/Siteinfo.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php index 41f6e9f0b..f6b34d0c8 100644 --- a/Zotlabs/Module/Siteinfo.php +++ b/Zotlabs/Module/Siteinfo.php @@ -32,9 +32,8 @@ class Siteinfo extends \Zotlabs\Web\Controller { $r = q("select * from addon where hidden = 0"); if(count($r)) foreach($r as $rr) - $visible_plugins[] = $rr['name']; + $visible_plugins[] = $rr['aname']; } - $plugins_list = ''; if(count($visible_plugins)) { $plugins_text = t('Installed plugins/addons/apps:'); -- cgit v1.2.3 From ed166608670c5b5d237c43bd0d672502d5b624f5 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 20 Jun 2016 20:34:19 -0700 Subject: code optimisation --- Zotlabs/Module/Siteinfo.php | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php index f6b34d0c8..a15e2896d 100644 --- a/Zotlabs/Module/Siteinfo.php +++ b/Zotlabs/Module/Siteinfo.php @@ -27,27 +27,11 @@ class Siteinfo extends \Zotlabs\Web\Controller { else { $version = $commit = ''; } - $visible_plugins = array(); - if(is_array(\App::$plugins) && count(\App::$plugins)) { - $r = q("select * from addon where hidden = 0"); - if(count($r)) - foreach($r as $rr) - $visible_plugins[] = $rr['aname']; - } - $plugins_list = ''; - if(count($visible_plugins)) { - $plugins_text = t('Installed plugins/addons/apps:'); - $sorted = $visible_plugins; - $s = ''; - sort($sorted); - foreach($sorted as $p) { - if(strlen($p)) { - if(strlen($s)) $s .= ', '; - $s .= $p; - } - } - $plugins_list .= $s; - } + + $plugins_list = implode(', ',visible_plugin_list()); + + if($plugins_list) + $plugins_text = t('Installed plugins/addons/apps:'); else $plugins_text = t('No installed plugins/addons/apps'); -- cgit v1.2.3 From b593c3a9b90bc35e7bfa320acffb63b9b0f3de93 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 21 Jun 2016 18:18:06 -0700 Subject: 1. provide automatic relocation of important links in items that are imported or synced to clones 2. provide framework for custom curl request bodies using custom/non-standard request methods. This was a real nightmare because curl doesn't actually let you specify a string to send as the request body (except when doing POST). You have to treat it as a file upload using a custom file handler function which provides the actual content in chunks as if it were buffered I/O. 3. item_store and item_store_update now return the item that was stored --- Zotlabs/Module/Import.php | 6 ++++-- Zotlabs/Module/Import_items.php | 4 ++-- Zotlabs/Module/Item.php | 4 ++-- Zotlabs/Module/Uexport.php | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 122e27e90..4a559fe95 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -131,6 +131,8 @@ class Import extends \Zotlabs\Web\Controller { // import channel + $relocate = ((array_key_exists('relocate',$data)) ? $data['relocate'] : null); + if(array_key_exists('channel',$data)) { if($completed < 1) { @@ -475,7 +477,7 @@ class Import extends \Zotlabs\Web\Controller { import_events($channel,$data['event']); if(is_array($data['event_item'])) - import_items($channel,$data['event_item']); + import_items($channel,$data['event_item'],false,$relocate); if(is_array($data['menu'])) import_menus($channel,$data['menu']); @@ -486,7 +488,7 @@ class Import extends \Zotlabs\Web\Controller { $saved_notification_flags = notifications_off($channel['channel_id']); if($import_posts && array_key_exists('item',$data) && $data['item']) - import_items($channel,$data['item']); + import_items($channel,$data['item'],false,$relocate); notifications_on($channel['channel_id'],$saved_notification_flags); diff --git a/Zotlabs/Module/Import_items.php b/Zotlabs/Module/Import_items.php index a862836c5..07b1c620c 100644 --- a/Zotlabs/Module/Import_items.php +++ b/Zotlabs/Module/Import_items.php @@ -92,7 +92,7 @@ class Import_items extends \Zotlabs\Web\Controller { if(array_key_exists('item',$data) && $data['item']) { - import_items($channel,$data['item']); + import_items($channel,$data['item'],false,((array_key_exists('relocate',$data)) ? $data['relocate'] : null)); } if(array_key_exists('item_id',$data) && $data['item_id']) { @@ -106,7 +106,7 @@ class Import_items extends \Zotlabs\Web\Controller { - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied') . EOL); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 272da7971..369dd3948 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -894,8 +894,8 @@ class Item extends \Zotlabs\Web\Controller { if($orig_post) { $datarray['id'] = $post_id; - item_store_update($datarray,$execflag); - + $x = item_store_update($datarray,$execflag); + if(! $parent) { $r = q("select * from item where id = %d", intval($post_id) diff --git a/Zotlabs/Module/Uexport.php b/Zotlabs/Module/Uexport.php index d48f96d76..f36d77174 100644 --- a/Zotlabs/Module/Uexport.php +++ b/Zotlabs/Module/Uexport.php @@ -44,7 +44,7 @@ class Uexport extends \Zotlabs\Web\Controller { } } - function get() { + function get() { $y = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); -- cgit v1.2.3 From 1267d995ef031f6ecf4d1f1951a700dfdcbf6c8d Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 22 Jun 2016 19:08:59 -0700 Subject: db statement debugging --- Zotlabs/Module/Photo.php | 4 ++-- Zotlabs/Module/Profile_photo.php | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 92c9ac3c0..5148c4a94 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -62,7 +62,7 @@ class Photo extends \Zotlabs\Web\Controller { intval($uid), intval(PHOTO_PROFILE) ); - if(count($r)) { + if($r) { $data = dbunescbin($r[0]['content']); $mimetype = $r[0]['mimetype']; } @@ -79,7 +79,7 @@ class Photo extends \Zotlabs\Web\Controller { * Other photos */ - /* Check for a cookie to indicate display pixel density, in order to detect high-resolution + /* Check for a cookie to indicate display pixel density, in order to detect high-resolution displays. This procedure was derived from the "Retina Images" by Jeremey Worboys, used in accordance with the Creative Commons Attribution 3.0 Unported License. Project link: https://github.com/Retina-Images/Retina-Images diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 6129a7492..9480a2f7f 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -23,12 +23,11 @@ class Profile_photo extends \Zotlabs\Web\Controller { /* @brief Initalize the profile-photo edit view * - * @param $a Current application * @return void * */ - function init() { + function init() { if(! local_channel()) { return; @@ -46,7 +45,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { * */ - function post() { + function post() { if(! local_channel()) { return; -- cgit v1.2.3 From 515b054a6e6e5030b66753147cff424e0f37bab8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 22 Jun 2016 20:17:19 -0700 Subject: missing class selector when "use photo as profile photo" --- Zotlabs/Module/Profile_photo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 9480a2f7f..d1ce9f428 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -348,7 +348,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { } } - profile_photo_crop_ui_head($a, $ph, $hash, $smallest); + $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest); } $profiles = q("select id, profile_name as name, is_default from profile where uid = %d", -- cgit v1.2.3 From b8c5a91940f75e79b1cd7e7e2148e4acd0ff7d83 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 22 Jun 2016 20:46:44 -0700 Subject: set profile when "use existing photo" --- Zotlabs/Module/Profile_photo.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index d1ce9f428..c02821a3c 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -70,6 +70,8 @@ class Profile_photo extends \Zotlabs\Web\Controller { } } + +logger('profile: ' . $_REQUEST['profile']); // phase 2 - we have finished cropping @@ -268,11 +270,19 @@ class Profile_photo extends \Zotlabs\Web\Controller { notice( t('Permission denied.') . EOL ); return; }; - - // check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); - + $resource_id = argv(2); + // When using an existing photo, we don't have a dialogue to offer a choice of profiles, + // so it gets attached to the default + + $p = q("select id from profile where is_default = 1 and uid = %d", + intval(local_channel()) + ); + if($p) { + $_REQUEST['profile'] = $p[0]['id']; + } + $r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC", intval(local_channel()), @@ -309,7 +319,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { dbesc($channel['xchan_hash']) ); - profile_photo_set_profile_perms(); //Reset default photo permissions to public + profile_photo_set_profile_perms(); // Reset default photo permissions to public \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); goaway(z_root() . '/profiles'); } -- cgit v1.2.3 From acf26d5c63c8b3316d713ce08b397f35aae03460 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 23 Jun 2016 01:17:44 -0700 Subject: code cleanup for profile_photos --- Zotlabs/Module/Connedit.php | 2 +- Zotlabs/Module/Cover_photo.php | 4 +- Zotlabs/Module/Profile_photo.php | 101 ++++++++++++++++++++++----------------- Zotlabs/Module/Profperm.php | 2 +- 4 files changed, 62 insertions(+), 47 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 3feba5370..72b854079 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -219,7 +219,7 @@ class Connedit extends \Zotlabs\Web\Controller { //Update profile photo permissions logger('A new profile was assigned - updating profile photos'); - profile_photo_set_profile_perms($profile_id); + profile_photo_set_profile_perms(local_channel(),$profile_id); } diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index a72c3389f..5633976c8 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -40,7 +40,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { * */ - function post() { + function post() { if(! local_channel()) { return; @@ -271,7 +271,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { */ - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL ); diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index c02821a3c..72c92e721 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -53,8 +53,23 @@ class Profile_photo extends \Zotlabs\Web\Controller { check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); - if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) { + if((array_key_exists('postfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) { + // phase 2 - we have finished cropping + + if(argc() != 2) { + notice( t('Image uploaded but image cropping failed.') . EOL ); + return; + } + + $image_id = argv(1); + + if(substr($image_id,-2,1) == '-') { + $scale = substr($image_id,-1,1); + $image_id = substr($image_id,0,-2); + } + + // unless proven otherwise $is_default_profile = 1; @@ -69,25 +84,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { $is_default_profile = 0; } } - -logger('profile: ' . $_REQUEST['profile']); - - - // phase 2 - we have finished cropping - - if(argc() != 2) { - notice( t('Image uploaded but image cropping failed.') . EOL ); - return; - } - - $image_id = argv(1); - - if(substr($image_id,-2,1) == '-') { - $scale = substr($image_id,-1,1); - $image_id = substr($image_id,0,-2); - } - $srcX = $_POST['xstart']; $srcY = $_POST['ystart']; @@ -111,30 +108,38 @@ logger('profile: ' . $_REQUEST['profile']); $aid = get_account_id(); - $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'], - 'filename' => $base_image['filename'], 'album' => t('Profile Photos')); + $p = [ + 'aid' => $aid, + 'uid' => local_channel(), + 'resource_id' => $base_image['resource_id'], + 'filename' => $base_image['filename'], + 'album' => t('Profile Photos') + ]; - $p['imgscale'] = 4; + $p['imgscale'] = PHOTO_RES_PROFILE_300; $p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL); $r1 = $im->save($p); $im->scaleImage(80); - $p['imgscale'] = 5; + $p['imgscale'] = PHOTO_RES_PROFILE_80; $r2 = $im->save($p); $im->scaleImage(48); - $p['imgscale'] = 6; + $p['imgscale'] = PHOTO_RES_PROFILE_48; $r3 = $im->save($p); if($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice( t('Image resize failed.') . EOL ); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ", + $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", dbesc($base_image['resource_id']), - local_channel() + local_channel(), + intval(PHOTO_RES_PROFILE_300), + intval(PHOTO_RES_PROFILE_80), + intval(PHOTO_RES_PROFILE_48) ); return; } @@ -184,10 +189,7 @@ logger('profile: ' . $_REQUEST['profile']); // Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures' - profile_photo_set_profile_perms($_REQUEST['profile']); - - - + profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']); } else notice( t('Unable to process image') . EOL); @@ -197,7 +199,9 @@ logger('profile: ' . $_REQUEST['profile']); return; // NOTREACHED } - + // A new photo was uploaded. Store it and save some important details + // in App::$data for use in the cropping function + $hash = photo_new_resource(); $smallest = 0; @@ -221,7 +225,7 @@ logger('profile: ' . $_REQUEST['profile']); $os_storage = false; foreach($i as $ii) { - if(intval($ii['imgscale']) < 2) { + if(intval($ii['imgscale']) < PHOTO_RES_640) { $smallest = intval($ii['imgscale']); $os_storage = intval($ii['os_storage']); $imagedata = $ii['content']; @@ -239,7 +243,10 @@ logger('profile: ' . $_REQUEST['profile']); } return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest); - + + // This will "fall through" to the get() method, and since + // App::$data['imagecrop'] is set, it will proceed to cropping + // rather than present the upload form } @@ -294,11 +301,11 @@ logger('profile: ' . $_REQUEST['profile']); } $havescale = false; foreach($r as $rr) { - if($rr['imgscale'] == 5) + if($rr['imgscale'] == PHOTO_RES_PROFILE_80) $havescale = true; } - // set an already loaded photo as profile photo + // set an already loaded and cropped photo as profile photo if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) { // unset any existing profile photos @@ -319,7 +326,7 @@ logger('profile: ' . $_REQUEST['profile']); dbesc($channel['xchan_hash']) ); - profile_photo_set_profile_perms(); // Reset default photo permissions to public + profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); goaway(z_root() . '/profiles'); } @@ -351,7 +358,7 @@ logger('profile: ' . $_REQUEST['profile']); if($i) { $hash = $i[0]['resource_id']; foreach($i as $ii) { - if(intval($ii['imgscale']) < 2) { + if(intval($ii['imgscale']) < PHOTO_RES_640) { $smallest = intval($ii['imgscale']); } } @@ -359,9 +366,14 @@ logger('profile: ' . $_REQUEST['profile']); } $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest); + + // falls through with App::$data['imagecrop'] set so we go straight to the cropping section } - $profiles = q("select id, profile_name as name, is_default from profile where uid = %d", + + // present an upload form + + $profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc", intval(local_channel()) ); @@ -388,6 +400,9 @@ logger('profile: ' . $_REQUEST['profile']); return $o; } else { + + // present a cropping form + $filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution']; $resolution = \App::$data['imagecrop_resolution']; $tpl = get_markup_template("cropbody.tpl"); @@ -425,13 +440,13 @@ logger('profile: ' . $_REQUEST['profile']); if($max_length > 0) $ph->scaleImage($max_length); - $width = $ph->getWidth(); - $height = $ph->getHeight(); + \App::$data['width'] = $ph->getWidth(); + \App::$data['height'] = $ph->getHeight(); - if($width < 500 || $height < 500) { + if(\App::$data['width'] < 500 || \App::$data['height'] < 500) { $ph->scaleImageUp(400); - $width = $ph->getWidth(); - $height = $ph->getHeight(); + \App::$data['width'] = $ph->getWidth(); + \App::$data['height'] = $ph->getHeight(); } diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php index 33e9d1ece..79ce7a7ed 100644 --- a/Zotlabs/Module/Profperm.php +++ b/Zotlabs/Module/Profperm.php @@ -97,7 +97,7 @@ class Profperm extends \Zotlabs\Web\Controller { //Time to update the permissions on the profile-pictures as well - profile_photo_set_profile_perms($profile['id']); + profile_photo_set_profile_perms(local_channel(),$profile['id']); $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'", intval(local_channel()), -- cgit v1.2.3 From b19bbf54736b83afaa26aa11ba95c7816c7f8599 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 23 Jun 2016 18:12:26 -0700 Subject: change AbConfig to use channel_id instead of channel_hash; which was a mistake in retrospect --- Zotlabs/Module/Connedit.php | 2 +- Zotlabs/Module/Follow.php | 2 +- Zotlabs/Module/Import.php | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 72b854079..feed9cb1a 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -345,7 +345,7 @@ class Connedit extends \Zotlabs\Web\Controller { unset($clone['abook_account']); unset($clone['abook_channel']); - $abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']); + $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); if($abconfig) $clone['abconfig'] = $abconfig; diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index 1df382a89..3641330c9 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -43,7 +43,7 @@ class Follow extends \Zotlabs\Web\Controller { unset($clone['abook_account']); unset($clone['abook_channel']); - $abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']); + $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); if($abconfig) $clone['abconfig'] = $abconfig; diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 4a559fe95..e34f5e49e 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -389,8 +389,7 @@ class Import extends \Zotlabs\Web\Controller { if($abconfig) { // @fixme does not handle sync of del_abconfig foreach($abconfig as $abc) { - if($abc['chan'] === $channel['channel_hash']) - set_abconfig($abc['chan'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']); + set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']); } } -- cgit v1.2.3 From fb93ae21282c86664de6b0d94d613695b3490473 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 24 Jun 2016 02:07:12 -0700 Subject: fix pdledit "list layouts" --- Zotlabs/Module/Pdledit.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Pdledit.php b/Zotlabs/Module/Pdledit.php index accfb6fa1..5cb00f165 100644 --- a/Zotlabs/Module/Pdledit.php +++ b/Zotlabs/Module/Pdledit.php @@ -20,7 +20,7 @@ class Pdledit extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -32,18 +32,18 @@ class Pdledit extends \Zotlabs\Web\Controller { else { $o .= '
    '; $o .= '

    ' . t('Edit System Page Description') . '

    '; - $files = glob('mod/*'); + $files = glob('Zotlabs/Module/*.php'); if($files) { foreach($files as $f) { - $name = basename($f,'.php'); + $name = lcfirst(basename($f,'.php')); $x = theme_include('mod_' . $name . '.pdl'); if($x) { $o .= '' . $name . '
    '; } } } - - $o .= '
    '; + + $o .= ''; // list module pdl files return $o; -- cgit v1.2.3 From 780f83a118146cf67509574ac88024c2cb03cf3a Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 25 Jun 2016 06:27:14 -0500 Subject: Post generation about new wiki is optional, default is NOT to post. Fixed bug in wiki creation. Added embed image dialog and album browser. --- Zotlabs/Module/Wiki.php | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index bef831de8..1c3add38f 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -145,7 +145,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$cancel' => t('Cancel') ) ); - + $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, @@ -170,7 +170,17 @@ class Wiki extends \Zotlabs\Web\Controller { '$pageHistory' => $pageHistory['history'], '$wikiModal' => $wikiModal, '$wikiModalID' => $wikiModalID, - '$commit' => 'HEAD' + '$commit' => 'HEAD', + '$embedPhotos' => t('Embed image from photo albums'), + '$embedPhotosModalTitle' => t('Embed an image from your albums'), + '$embedPhotosModalCancel' => t('Cancel'), + '$embedPhotosModalOK' => t('OK'), + '$modalchooseimages' => t('Choose images to embed'), + '$modalchoosealbum' => t('Choose an album'), + '$modaldiffalbum' => t('Choose a different album...'), + '$modalerrorlist' => t('Error getting album list'), + '$modalerrorlink' => t('Error getting photo link'), + '$modalerroralbum' => t('Error getting album'), )); head_add_js('library/ace/ace.js'); // Ace Code Editor return $o; @@ -202,6 +212,7 @@ class Wiki extends \Zotlabs\Web\Controller { } $wiki = array(); // Generate new wiki info from input name + $wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1); $wiki['rawName'] = $_POST['wikiName']; $wiki['htmlName'] = escape_tags($_POST['wikiName']); $wiki['urlName'] = urlencode($_POST['wikiName']); @@ -235,20 +246,7 @@ class Wiki extends \Zotlabs\Web\Controller { if (local_channel() !== intval($channel['channel_id'])) { logger('Wiki delete permission denied.' . EOL); json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false)); - } else { - /* - $channel = get_channel_by_nick($nick); - $observer_hash = get_observer_hash(); - // Figure out who the page owner is. - $perms = get_all_perms(intval($channel['channel_id']), $observer_hash); - // TODO: Create a new permission setting for wiki analogous to webpages. Until - // then, use webpage permissions - if (!$perms['write_pages']) { - logger('Wiki delete permission denied.' . EOL); - json_return_and_die(array('success' => false)); - } - */ - } + } $resource_id = $_POST['resource_id']; $deleted = wiki_delete_wiki($resource_id); if ($deleted['success']) { @@ -482,7 +480,6 @@ class Wiki extends \Zotlabs\Web\Controller { } } $renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName)); - logger('$renamed: ' . json_encode($renamed)); if($renamed['success']) { $ob = \App::get_observer(); $commit = wiki_git_commit(array( -- cgit v1.2.3 From 0df3978cc5891f1383dd0dbcdc1c6b4c0010e645 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 25 Jun 2016 14:29:52 -0500 Subject: A page name wrapped in double brackets is converted into a link to another page in the current wiki --- Zotlabs/Module/Wiki.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 1c3add38f..de5863d2e 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -74,7 +74,9 @@ class Wiki extends \Zotlabs\Web\Controller { // Configure page template $wikiheaderName = t('Wiki'); $wikiheaderPage = t('Sandbox'); - $content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'; + require_once('library/markdown.php'); + $content = t('"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'); + $renderedContent = Markdown(json_decode($content)); $hide_editor = false; $showPageControls = false; $showNewWikiButton = $wiki_owner; @@ -122,6 +124,9 @@ class Wiki extends \Zotlabs\Web\Controller { goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName); } $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); + // Render the Markdown-formatted page content in HTML + require_once('library/markdown.php'); + $renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName); $hide_editor = false; $showPageControls = $wiki_editor; $showNewWikiButton = $wiki_owner; @@ -133,8 +138,6 @@ class Wiki extends \Zotlabs\Web\Controller { default: // Strip the extraneous URL components goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName); } - // Render the Markdown-formatted page content in HTML - require_once('library/markdown.php'); $wikiModalID = random_string(3); $wikiModal = replace_macros( @@ -162,7 +165,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$acl' => $x['acl'], '$bang' => $x['bang'], '$content' => $content, - '$renderedContent' => Markdown(json_decode($content)), + '$renderedContent' => $renderedContent, '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), '$pageRename' => array('pageRename', t('Enter the new name:'), '', ''), @@ -193,8 +196,12 @@ class Wiki extends \Zotlabs\Web\Controller { // Render mardown-formatted text in HTML for preview if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; + $resource_id = $_POST['resource_id']; require_once('library/markdown.php'); $html = purify_html(Markdown($content)); + $w = wiki_get_wiki($resource_id); + $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName']; + $html = wiki_convert_links($html,$wikiURL); json_return_and_die(array('html' => $html, 'success' => true)); } -- cgit v1.2.3 From b96edd8b9ab86d84a2e67515a87de13f660d5cb1 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 26 Jun 2016 15:04:47 -0400 Subject: Added table of contents generator. Table is inserted wherever [toc] is encountered. --- Zotlabs/Module/Wiki.php | 1 + 1 file changed, 1 insertion(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index de5863d2e..a11960b51 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -198,6 +198,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = $_POST['content']; $resource_id = $_POST['resource_id']; require_once('library/markdown.php'); + $content = wiki_generate_toc($content); $html = purify_html(Markdown($content)); $w = wiki_get_wiki($resource_id); $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName']; -- cgit v1.2.3 From 216f034b6dd0d26282035218126d312080a9adc3 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 26 Jun 2016 15:27:55 -0400 Subject: Also generate table of contents when loading the page --- Zotlabs/Module/Wiki.php | 1 + 1 file changed, 1 insertion(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index a11960b51..9b89ed967 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -126,6 +126,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); + $content = wiki_generate_toc($content); $renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName); $hide_editor = false; $showPageControls = $wiki_editor; -- cgit v1.2.3 From 81da9f99e4ee111623a1ba302a6ab18e369756e9 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 26 Jun 2016 15:41:25 -0400 Subject: Fixed bug with rendering table of contents upon page load --- Zotlabs/Module/Wiki.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 9b89ed967..a5039fa23 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -126,8 +126,9 @@ class Wiki extends \Zotlabs\Web\Controller { $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); - $content = wiki_generate_toc($content); - $renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName); + $toc_content = wiki_generate_toc(json_decode($content)); + $html = purify_html(Markdown($toc_content)); + $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName); $hide_editor = false; $showPageControls = $wiki_editor; $showNewWikiButton = $wiki_owner; -- cgit v1.2.3 From 3035c792dcef91cd679034ee67eb2b28ed6f3d35 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 26 Jun 2016 22:13:59 -0700 Subject: remove the app $a passed to profile_load, also add profile_load to mod_wiki which should fix issue #431 --- Zotlabs/Module/Achievements.php | 2 +- Zotlabs/Module/Block.php | 2 +- Zotlabs/Module/Blocks.php | 2 +- Zotlabs/Module/Cal.php | 2 +- Zotlabs/Module/Channel.php | 2 +- Zotlabs/Module/Chat.php | 2 +- Zotlabs/Module/Cloud.php | 2 +- Zotlabs/Module/Common.php | 2 +- Zotlabs/Module/Connect.php | 2 +- Zotlabs/Module/Cover_photo.php | 2 +- Zotlabs/Module/Dav.php | 2 +- Zotlabs/Module/Editblock.php | 2 +- Zotlabs/Module/Editlayout.php | 2 +- Zotlabs/Module/Editwebpage.php | 2 +- Zotlabs/Module/Hcard.php | 2 +- Zotlabs/Module/Id.php | 2 +- Zotlabs/Module/Layouts.php | 2 +- Zotlabs/Module/Page.php | 2 +- Zotlabs/Module/Photos.php | 2 +- Zotlabs/Module/Profile.php | 2 +- Zotlabs/Module/Profile_photo.php | 2 +- Zotlabs/Module/Profiles.php | 4 ++-- Zotlabs/Module/Profperm.php | 2 +- Zotlabs/Module/Viewconnections.php | 2 +- Zotlabs/Module/Webpages.php | 2 +- Zotlabs/Module/Wiki.php | 2 ++ 26 files changed, 28 insertions(+), 26 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Achievements.php b/Zotlabs/Module/Achievements.php index 8ddefb3e5..1529448d3 100644 --- a/Zotlabs/Module/Achievements.php +++ b/Zotlabs/Module/Achievements.php @@ -18,7 +18,7 @@ class Achievements extends \Zotlabs\Web\Controller { $profile = 0; $profile = argv(1); - profile_load($a,$which,$profile); + profile_load($which,$profile); $r = q("select channel_id from channel where channel_address = '%s'", dbesc($which) diff --git a/Zotlabs/Module/Block.php b/Zotlabs/Module/Block.php index 45e61e4ea..e671730f6 100644 --- a/Zotlabs/Module/Block.php +++ b/Zotlabs/Module/Block.php @@ -12,7 +12,7 @@ class Block extends \Zotlabs\Web\Controller { $which = argv(1); $profile = 0; - profile_load($a,$which,$profile); + profile_load($which,$profile); if(\App::$profile['profile_uid']) head_set_icon(\App::$profile['thumb']); diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php index 475cfa6b3..e6a97794d 100644 --- a/Zotlabs/Module/Blocks.php +++ b/Zotlabs/Module/Blocks.php @@ -22,7 +22,7 @@ class Blocks extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php index 1da42684d..fd4169e68 100644 --- a/Zotlabs/Module/Cal.php +++ b/Zotlabs/Module/Cal.php @@ -20,7 +20,7 @@ class Cal extends \Zotlabs\Web\Controller { if(argc() > 1) { $nick = argv(1); - profile_load($a,$nick); + profile_load($nick); $channelx = channelx_by_nick($nick); diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 29bfcbc3c..d09388901 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -48,7 +48,7 @@ class Channel extends \Zotlabs\Web\Controller { // Run profile_load() here to make sure the theme is set before // we start loading content - profile_load($a,$which,$profile); + profile_load($which,$profile); } diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php index 026e8369a..ff55a9319 100644 --- a/Zotlabs/Module/Chat.php +++ b/Zotlabs/Module/Chat.php @@ -39,7 +39,7 @@ class Chat extends \Zotlabs\Web\Controller { // Run profile_load() here to make sure the theme is set before // we start loading content - profile_load($a,$which,$profile); + profile_load($which,$profile); } diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index b691475ce..833b1b493 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -37,7 +37,7 @@ class Cloud extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= '' . "\r\n"; if ($which) - profile_load($a, $which, $profile); + profile_load( $which, $profile); $auth = new \Zotlabs\Storage\BasicAuth(); diff --git a/Zotlabs/Module/Common.php b/Zotlabs/Module/Common.php index 1c428d256..2f3c57267 100644 --- a/Zotlabs/Module/Common.php +++ b/Zotlabs/Module/Common.php @@ -21,7 +21,7 @@ class Common extends \Zotlabs\Web\Controller { ); if($x) - profile_load($a,$x[0]['channel_address'],0); + profile_load($x[0]['channel_address'],0); } diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php index f68e0baac..962c05cce 100644 --- a/Zotlabs/Module/Connect.php +++ b/Zotlabs/Module/Connect.php @@ -26,7 +26,7 @@ class Connect extends \Zotlabs\Web\Controller { if($r) \App::$data['channel'] = $r[0]; - profile_load($a,$which,''); + profile_load($which,''); } function post() { diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index 5633976c8..9887b8203 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -29,7 +29,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { } $channel = \App::get_channel(); - profile_load($a,$channel['channel_address']); + profile_load($channel['channel_address']); } diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 2fddabe19..6528e0271 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -58,7 +58,7 @@ class Dav extends \Zotlabs\Web\Controller { \App::$page['htmlhead'] .= '' . "\r\n"; if ($which) - profile_load($a, $which, $profile); + profile_load( $which, $profile); diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 1d6ef7a0a..6a9fa5f2d 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -21,7 +21,7 @@ class Editblock extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php index fe794b5fd..26732dc77 100644 --- a/Zotlabs/Module/Editlayout.php +++ b/Zotlabs/Module/Editlayout.php @@ -21,7 +21,7 @@ class Editlayout extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 6d67c08e7..5cd409e1e 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -23,7 +23,7 @@ class Editwebpage extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php index 2636e676b..93c8d3ece 100644 --- a/Zotlabs/Module/Hcard.php +++ b/Zotlabs/Module/Hcard.php @@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller { } } - profile_load($a,$which,$profile); + profile_load($which,$profile); } diff --git a/Zotlabs/Module/Id.php b/Zotlabs/Module/Id.php index 6a94b57f5..e053bf99c 100644 --- a/Zotlabs/Module/Id.php +++ b/Zotlabs/Module/Id.php @@ -57,7 +57,7 @@ class Id extends \Zotlabs\Web\Controller { $profile = ''; $channel = \App::get_channel(); - profile_load($a,$which,$profile); + profile_load($which,$profile); $op = new MysqlProvider; $op->server(); diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php index a0b1c31cc..c07f65ce1 100644 --- a/Zotlabs/Module/Layouts.php +++ b/Zotlabs/Module/Layouts.php @@ -21,7 +21,7 @@ class Layouts extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index deb23da68..6ef285dd0 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -13,7 +13,7 @@ class Page extends \Zotlabs\Web\Controller { $which = argv(1); $profile = 0; - profile_load($a,$which,$profile); + profile_load($which,$profile); diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 1bdc23897..1633e08ef 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -27,7 +27,7 @@ class Photos extends \Zotlabs\Web\Controller { if(argc() > 1) { $nick = argv(1); - profile_load($a,$nick); + profile_load($nick); $channelx = channelx_by_nick($nick); diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php index 8bf358bc8..9e868db92 100644 --- a/Zotlabs/Module/Profile.php +++ b/Zotlabs/Module/Profile.php @@ -48,7 +48,7 @@ class Profile extends \Zotlabs\Web\Controller { } } - profile_load($a,$which,$profile); + profile_load($which,$profile); } diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 72c92e721..62c5e99ae 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -34,7 +34,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { } $channel = \App::get_channel(); - profile_load($a,$channel['channel_address']); + profile_load($channel['channel_address']); } diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 06e5cfd7b..899c79b15 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -193,7 +193,7 @@ class Profiles extends \Zotlabs\Web\Controller { $chan = \App::get_channel(); - profile_load($a,$chan['channel_address'],$r[0]['id']); + profile_load($chan['channel_address'],$r[0]['id']); } } @@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller { if($is_default) { // reload the info for the sidebar widget - why does this not work? - profile_load($a,$channel['channel_address']); + profile_load($channel['channel_address']); \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); } } diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php index 79ce7a7ed..b1da147c1 100644 --- a/Zotlabs/Module/Profperm.php +++ b/Zotlabs/Module/Profperm.php @@ -17,7 +17,7 @@ class Profperm extends \Zotlabs\Web\Controller { $profile = \App::$argv[1]; - profile_load($a,$which,$profile); + profile_load($which,$profile); } diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php index ea478f92a..7523c259b 100644 --- a/Zotlabs/Module/Viewconnections.php +++ b/Zotlabs/Module/Viewconnections.php @@ -11,7 +11,7 @@ class Viewconnections extends \Zotlabs\Web\Controller { return; } if(argc() > 1) - profile_load($a,argv(1)); + profile_load(argv(1)); } function get() { diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index fc292be6f..bb8d9c6ed 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -23,7 +23,7 @@ class Webpages extends \Zotlabs\Web\Controller { else return; - profile_load($a,$which); + profile_load($which); } diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index de5863d2e..6a8bdf0db 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -20,6 +20,8 @@ class Wiki extends \Zotlabs\Web\Controller { notice(t('You must be logged in to see this page.') . EOL); goaway('/login'); } + profile_load($nick); + } function get() { -- cgit v1.2.3 From 8d298d5a068845856c9827c0d2ea3f02f1399d72 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 26 Jun 2016 22:26:45 -0700 Subject: fix for the rendering side of issue #412. We traditionally store all "user generated" content with ENT_COMPAT encoding to reduce the attack vector for JS CSS exploits. This may present compatibility issues sharing wikis to platforms which do not provide such CSS protection. We can either decide that wikis are inherently insecure and filter them on render (with an associated performance penalty), or keep the existing method of filtering on store. I'm not making that choice. I'm merely fixing the obvious rendering issue in mono-platform viewing. --- Zotlabs/Module/Wiki.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 6a8bdf0db..38b49effc 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -125,7 +125,7 @@ class Wiki extends \Zotlabs\Web\Controller { notice('Error retrieving page content' . EOL); goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName); } - $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); + $content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"'); // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); $renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName); -- cgit v1.2.3 From ee1d52749733c1de7e88ede6c63f155215e1ae1c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 27 Jun 2016 16:15:47 -0700 Subject: comment on the setup page about the possible need for intermediate certs. --- Zotlabs/Module/New_channel.php | 4 ++-- Zotlabs/Module/Setup.php | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 30d7c83c6..1dcf84fb0 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -62,7 +62,7 @@ class New_channel extends \Zotlabs\Web\Controller { } - function post() { + function post() { $arr = $_POST; @@ -96,7 +96,7 @@ class New_channel extends \Zotlabs\Web\Controller { } - function get() { + function get() { $acc = \App::get_account(); diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index c4878e217..c5d0ccc21 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -596,7 +596,7 @@ class Setup extends \Zotlabs\Web\Controller { if(! is_writable('store')) { $status = false; - $help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; + $help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; } @@ -639,6 +639,9 @@ class Setup extends \Zotlabs\Web\Controller { $help .= t('If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues.') . EOL; $help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL; $help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL; + + $help .= t('If you are confident that the certificate is valid and signed by a trusted authority, check to see if you have failed to install an intermediate cert. These are not normally required by browsers, but are required for server-to-server communications.') . EOL; + $this->check_add($checks, t('SSL certificate validation'), false, true, $help); } @@ -695,6 +698,7 @@ class Setup extends \Zotlabs\Web\Controller { // install the standard theme set_config('system', 'allowed_themes', 'redbasic'); + // Set a lenient list of ciphers if using openssl. Other ssl engines // (e.g. NSS used in RedHat) require different syntax, so hopefully // the default curl cipher list will work for most sites. If not, @@ -704,7 +708,9 @@ class Setup extends \Zotlabs\Web\Controller { // z_fetch_url() is also used to import shared links and other content // so in theory most any cipher could show up and we should do our best // to make the content available rather than tell folks that there's a - // weird SSL error which they can't do anything about. + // weird SSL error which they can't do anything about. This does not affect + // the SSL server, but is only a client negotiation to find something workable. + // Hence it will not make your system susceptible to POODL or other nasties. $x = curl_version(); if(stristr($x['ssl_version'],'openssl')) -- cgit v1.2.3 From b155e93ab134759f3d31a509d197916a5af84adb Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 27 Jun 2016 19:04:00 -0700 Subject: add letsencrypt x3 intermediate cert and new cert file, improve UX of new registrations --- Zotlabs/Module/Register.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php index 7cd1ee501..6afa4a94c 100644 --- a/Zotlabs/Module/Register.php +++ b/Zotlabs/Module/Register.php @@ -259,7 +259,8 @@ class Register extends \Zotlabs\Web\Controller { '$email' => $email, '$pass1' => $password, '$pass2' => $password2, - '$submit' => ((UNO || $auto_create || $registration_is) ? t('Register') : t('Proceed to create your first channel')) + '$submit' => t('Register'), + '$verify_note' => t('This site may require email verification after submitting this form. If you are returned to a login page, please check your email for instructions.') )); return $o; -- cgit v1.2.3 From 7d7f43c2056fd50ff26aed5df553bf4936ead196 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 27 Jun 2016 22:25:37 -0700 Subject: still working through some issues with curl magic-auth fixed profile photo upload --- Zotlabs/Module/Cover_photo.php | 2 +- Zotlabs/Module/Profile_photo.php | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index 9887b8203..886958b37 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -50,7 +50,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo'); - if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) { + if((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) { // phase 2 - we have finished cropping diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 62c5e99ae..9359b80f8 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -53,7 +53,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); - if((array_key_exists('postfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) { + if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) { // phase 2 - we have finished cropping @@ -90,12 +90,11 @@ class Profile_photo extends \Zotlabs\Web\Controller { $srcY = $_POST['ystart']; $srcW = $_POST['xfinal'] - $srcX; $srcH = $_POST['yfinal'] - $srcY; - + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1", dbesc($image_id), dbesc(local_channel()), intval($scale)); - if($r) { $base_image = $r[0]; -- cgit v1.2.3 From 715b1667d928175c0fac5832b998d9ded92974a3 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 28 Jun 2016 20:48:43 -0700 Subject: readability --- Zotlabs/Module/Viewconnections.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php index 7523c259b..4364d482a 100644 --- a/Zotlabs/Module/Viewconnections.php +++ b/Zotlabs/Module/Viewconnections.php @@ -10,8 +10,11 @@ class Viewconnections extends \Zotlabs\Web\Controller { if(observer_prohibited()) { return; } - if(argc() > 1) + + if(argc() > 1) { profile_load(argv(1)); + } + } function get() { -- cgit v1.2.3 From f098600c41553bc47267a61fb47a4957046e696e Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Jun 2016 23:04:34 +0200 Subject: missing backslash leads to wsod on refresh permissions --- Zotlabs/Module/Connedit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index feed9cb1a..7db4950b1 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -433,7 +433,7 @@ class Connedit extends \Zotlabs\Web\Controller { else { // if you are on a different network we'll force a refresh of the connection basic info - Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id)); + \Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id)); } goaway(z_root() . '/connedit/' . $contact_id); } -- cgit v1.2.3 From 2e93a09d83f16f12796ff4edc1aca09339ae2ccf Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 29 Jun 2016 17:31:48 -0700 Subject: stream large photos through buffered I/O if possible --- Zotlabs/Module/Photo.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 5148c4a94..66aaec49f 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -2,6 +2,7 @@ namespace Zotlabs\Module; require_once('include/security.php'); +require_once('include/attach.php'); require_once('include/photo/photo_driver.php'); @@ -10,6 +11,8 @@ class Photo extends \Zotlabs\Web\Controller { function init() { $prvcachecontrol = false; + $streaming = null; + $channel = null; switch(argc()) { case 4: @@ -131,6 +134,8 @@ class Photo extends \Zotlabs\Web\Controller { $sql_extra = permissions_sql($r[0]['uid']); + $channel = channelx_by_n($r[0]['uid']); + // Now we'll see if we can access the photo $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1", @@ -141,8 +146,9 @@ class Photo extends \Zotlabs\Web\Controller { if($r && $allowed) { $data = dbunescbin($r[0]['content']); $mimetype = $r[0]['mimetype']; - if(intval($r[0]['os_storage'])) - $data = file_get_contents($data); + if(intval($r[0]['os_storage'])) { + $streaming = $data; + } } else { @@ -242,7 +248,25 @@ class Photo extends \Zotlabs\Web\Controller { header("Cache-Control: max-age=" . $cache); } - echo $data; + + // If it's a file resource, stream it. + + if($streaming && $channel) { + if(strpos($streaming,'store') !== false) + $istream = fopen($streaming,'rb'); + else + $istream = fopen('store/' . $channel['channel_address'] . '/' . $streaming,'rb'); + $ostream = fopen('php://output','wb'); + if($istream && $ostream) { + pipe_streams($istream,$ostream); + fclose($istream); + fclose($ostream); + } + } + else { + echo $data; + } + killme(); // NOTREACHED } -- cgit v1.2.3 From 9ef710c557fcc4ea01c87e03fd7a477eb037f09c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 29 Jun 2016 20:59:00 -0700 Subject: provide wiki as a feature (default is on so there aren't any surprises) and add to channel menu and profile tabs --- Zotlabs/Module/Wiki.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 38b49effc..2f22f0a81 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -25,8 +25,18 @@ class Wiki extends \Zotlabs\Web\Controller { } function get() { + + if(observer_prohibited(true)) { + return login(); + } + + $tab = 'wiki'; + + require_once('include/wiki.php'); require_once('include/acl_selectors.php'); + require_once('include/conversation.php'); + // TODO: Combine the interface configuration into a unified object // Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...) $wiki_owner = false; @@ -151,6 +161,11 @@ class Wiki extends \Zotlabs\Web\Controller { ) ); + $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false); + + $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']); + + $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, -- cgit v1.2.3 From bfe84a9ff753d4d9834ea24ad65edfef3561458c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 29 Jun 2016 22:46:47 -0700 Subject: templatise the Dreport page and add a redeliver option for when things stuff up badly. --- Zotlabs/Module/Dreport.php | 52 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index e8709c952..904646d5d 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -16,7 +16,24 @@ class Dreport extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); $mid = ((argc() > 1) ? argv(1) : ''); - + + if($mid === 'push') { + $table = 'push'; + $mid = ((argc() > 2) ? argv(2) : ''); + if($mid) { + $i = q("select id from item where mid = '%s' and author_xchan = '%s' and uid = %d", + dbesc($mid), + dbesc($channel['channel_hash']), + intval($channel['channel_id']) + ); + if($i) { + \Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]); + } + } + sleep(3); + goaway(z_root() . '/dreport/' . urlencode($mid)); + } + if($mid === 'mail') { $table = 'mail'; $mid = ((argc() > 2) ? argv(2) : ''); @@ -60,9 +77,10 @@ class Dreport extends \Zotlabs\Web\Controller { return; } - $o .= '
    '; - $o .= '

    ' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '

    '; - $o .= ''; +// $o .= '
    '; +// $o .= '

    ' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '

    '; + +// $o .= '
    '; for($x = 0; $x < count($r); $x++ ) { $r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' '))); @@ -119,13 +137,29 @@ class Dreport extends \Zotlabs\Web\Controller { } usort($r,'self::dreport_gravity_sort'); - - + + $entries = array(); foreach($r as $rr) { - $o .= ''; + $entries[] = [ + 'name' => $rr['name'], + 'result' => escape_tags($rr['dreport_result']), + 'time' => escape_tags($rr['dreport_time']) + ]; } - $o .= '
    ' . $rr['name'] . '' . escape_tags($rr['dreport_result']) . '' . escape_tags($rr['dreport_time']) . '
    '; - $o .= '
    '; + + $o = replace_macros(get_markup_template('dreport.tpl'), array( + '$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...', + '$table' => $table, + '$mid' => urlencode($mid), + '$push' => t('Redeliver'), + '$entries' => $entries + )); + +// foreach($r as $rr) { +// $o .= '' . $rr['name'] . '' . escape_tags($rr['dreport_result']) . '' . escape_tags($rr['dreport_time']) . ''; +// } +// $o .= ''; +// $o .= ''; return $o; -- cgit v1.2.3 From 1cc816f66223d5ea5043d4c667478503293414b8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 29 Jun 2016 22:53:18 -0700 Subject: dreport: convert timestamp to channel localtime and get rid of old pre-template code --- Zotlabs/Module/Dreport.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index 904646d5d..17ed6515e 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -76,12 +76,7 @@ class Dreport extends \Zotlabs\Web\Controller { notice( t('no results') . EOL); return; } - -// $o .= '
    '; -// $o .= '

    ' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '

    '; -// $o .= ''; - for($x = 0; $x < count($r); $x++ ) { $r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' '))); @@ -143,7 +138,7 @@ class Dreport extends \Zotlabs\Web\Controller { $entries[] = [ 'name' => $rr['name'], 'result' => escape_tags($rr['dreport_result']), - 'time' => escape_tags($rr['dreport_time']) + 'time' => escape_tags(datetime_convert('UTC',date_default_timezone_get(),$rr['dreport_time'])) ]; } @@ -155,11 +150,6 @@ class Dreport extends \Zotlabs\Web\Controller { '$entries' => $entries )); -// foreach($r as $rr) { -// $o .= ''; -// } -// $o .= '
    ' . $rr['name'] . '' . escape_tags($rr['dreport_result']) . '' . escape_tags($rr['dreport_time']) . '
    '; -// $o .= '
    '; return $o; -- cgit v1.2.3 From 7124c0aee5486aab74272c81ceb3e383b2e3a7f7 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 30 Jun 2016 21:50:38 -0400 Subject: Replace homemade table of content generator with existing jQuery plugin. Now toc is linked to document headings. --- Zotlabs/Module/Wiki.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index a5039fa23..f30884bfb 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -126,8 +126,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"'); // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); - $toc_content = wiki_generate_toc(json_decode($content)); - $html = purify_html(Markdown($toc_content)); + $html = wiki_generate_toc(purify_html(Markdown(json_decode($content)))); $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName); $hide_editor = false; $showPageControls = $wiki_editor; @@ -200,8 +199,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = $_POST['content']; $resource_id = $_POST['resource_id']; require_once('library/markdown.php'); - $content = wiki_generate_toc($content); - $html = purify_html(Markdown($content)); + $html = wiki_generate_toc(purify_html(Markdown($content))); $w = wiki_get_wiki($resource_id); $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName']; $html = wiki_convert_links($html,$wikiURL); -- cgit v1.2.3 From 7f8dcf4f12ec334a6dc62633ccf912d92dd519f4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 30 Jun 2016 21:12:39 -0700 Subject: sync flags even if post has not been edited --- Zotlabs/Module/Starred.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Starred.php b/Zotlabs/Module/Starred.php index 73a2dc808..4f1d99ec6 100644 --- a/Zotlabs/Module/Starred.php +++ b/Zotlabs/Module/Starred.php @@ -30,7 +30,20 @@ class Starred extends \Zotlabs\Web\Controller { intval(local_channel()), intval($message_id) ); - + + $r = q("select * from item where id = %d", + intval($message_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + build_sync_packet(local_channel(),[ + 'item' => [ + encode_item($sync_item[0],true) + ] + ]); + } + header('Content-type: application/json'); echo json_encode(array('result' => $item_starred)); killme(); -- cgit v1.2.3 From bd403276f2884ce8cd28102aa613a4de40aad6db Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 30 Jun 2016 21:27:59 -0700 Subject: disable wiki if feature disabled, sync updates of delayed publish posts --- Zotlabs/Module/Wiki.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 6252f7a1a..55a52ea6d 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -29,6 +29,11 @@ class Wiki extends \Zotlabs\Web\Controller { if(observer_prohibited(true)) { return login(); } + + if(! feature_enabled(\App::$profile_uid,'wiki')) { + notice( t('Not found') . EOL); + return; + } $tab = 'wiki'; -- cgit v1.2.3 From bb5ec8cfb89bc5cc1532ffacee22e21aa9415e23 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 1 Jul 2016 02:16:23 -0700 Subject: allow multiple apd's per plugin dir --- Zotlabs/Module/Import_items.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Import_items.php b/Zotlabs/Module/Import_items.php index 07b1c620c..f20cbfe7e 100644 --- a/Zotlabs/Module/Import_items.php +++ b/Zotlabs/Module/Import_items.php @@ -78,6 +78,8 @@ class Import_items extends \Zotlabs\Web\Controller { // logger('import: data: ' . print_r($data,true)); // print_r($data); + if(! is_array($data)) + return; if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { $v1 = substr($data['compatibility']['database'],-4); -- cgit v1.2.3 From 7371e0862543922b65eac920e128ca4ef1348b13 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 1 Jul 2016 12:21:19 +0200 Subject: ditch the change_view widget and make header fixed in fullscreen mode --- Zotlabs/Module/Events.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 3f3f9fb4c..3187cddb4 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -668,8 +668,10 @@ class Events extends \Zotlabs\Web\Controller { '$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''), '$calendar' => cal($y,$m,$links, ' eventcal'), '$events' => $events, - '$upload' => t('Import'), - '$submit' => t('Submit'), + '$view_label' => t('View'), + '$month' => t('Month'), + '$week' => t('Week'), + '$day' => t('Day'), '$prev' => t('Previous'), '$next' => t('Next'), '$today' => t('Today'), -- cgit v1.2.3 From 59474673395242f472124968e962702fb6b5f023 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 1 Jul 2016 20:34:00 -0700 Subject: use small photo for Diaspora attribution correction; the medium looks awkward in the D* stream. --- Zotlabs/Module/Tagger.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index 0a46cf56d..e1ed111a1 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -129,6 +129,15 @@ class Tagger extends \Zotlabs\Web\Controller { store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); $ret = post_activity_item($arr); + + $r = $ret['item']; + if($r) { + build_sync_packet(local_channel(),[ + 'item' => [ + encode_item($,true) + ] + ]); + } if($ret['success']) \Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id'])); -- cgit v1.2.3 From 41fa2d6c697bc4f7483e6c934b24c11fae368390 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 1 Jul 2016 20:46:57 -0700 Subject: delivery invoked twice in mod_tagger, once in post_activity_item() and another at the main module level --- Zotlabs/Module/Tagger.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index e1ed111a1..25f518d53 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -130,18 +130,14 @@ class Tagger extends \Zotlabs\Web\Controller { store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); $ret = post_activity_item($arr); - $r = $ret['item']; - if($r) { - build_sync_packet(local_channel(),[ - 'item' => [ - encode_item($,true) + if($ret['success']) { + build_sync_packet(local_channel(), + [ + 'item' => [ encode_item($ret['activity'],true) ] ] - ]); + ); } - if($ret['success']) - \Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id'])); - killme(); } -- cgit v1.2.3 From b87106b6fe735365587d7683d8b639e0cf37842c Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 3 Jul 2016 17:59:44 +1000 Subject: Mark nickname as required field, if left empty then channel creation fails silently --- Zotlabs/Module/New_channel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 1dcf84fb0..26883b6e2 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -125,9 +125,9 @@ class New_channel extends \Zotlabs\Web\Controller { } } - $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"')); + $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*"); $nickhub = '@' . \App::get_hostname(); - $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub)); + $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*"); $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" ); $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' ' . t('Read more about roles') . '',get_roles()); -- cgit v1.2.3 From 5c062aaec410ca1d5275a4a7079dadddb82c3097 Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 3 Jul 2016 22:21:48 +1000 Subject: force immediate avatar update --- Zotlabs/Module/Profile_photo.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 9359b80f8..f459f7deb 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -180,6 +180,8 @@ class Profile_photo extends \Zotlabs\Web\Controller { dbesc(datetime_convert()), dbesc($channel['xchan_hash']) ); + // Similarly, tell the nav bar to bypass the cache and update the avater image. + $_SESSION['reload_avatar'] = true; info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); -- cgit v1.2.3 From 2a26b0ae91281efd09320ac1950e4345fe7e9771 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 3 Jul 2016 22:47:46 -0700 Subject: perms work - settings page --- Zotlabs/Module/Settings.php | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 875004fae..5c9ff1db0 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -30,7 +30,7 @@ class Settings extends \Zotlabs\Web\Controller { } - function post() { + function post() { if(! local_channel()) return; @@ -40,7 +40,7 @@ class Settings extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); - logger('mod_settings: ' . print_r($_REQUEST,true)); + // logger('mod_settings: ' . print_r($_REQUEST,true)); if((argc() > 1) && (argv(1) === 'oauth') && x($_POST,'remove')){ @@ -311,10 +311,10 @@ class Settings extends \Zotlabs\Web\Controller { intval(local_channel()) ); - $global_perms = get_perms(); + $global_perms = \Zotlabs\Access\Permissions::Perms(); foreach($global_perms as $k => $v) { - $set_perms .= ', ' . $v[0] . ' = ' . intval($_POST[$k]) . ' '; + \Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,intval($_POST[$k])); } $acl = new \Zotlabs\Access\AccessList($channel); $acl->set_from_array($_POST); @@ -370,10 +370,10 @@ class Settings extends \Zotlabs\Web\Controller { ); } - $r = q("update abook set abook_my_perms = %d where abook_channel = %d and abook_self = 1", - intval((array_key_exists('perms_accept',$role_permissions)) ? $role_permissions['perms_accept'] : 0), - intval(local_channel()) - ); + foreach($global_perms as $k => $v) { + set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k,((array_key_exists($k,$role_permissions['perms_accept'])) ? intval($role_permissions['perms_accept'][$k]))); + } + set_pconfig(local_channel(),'system','autoperms',(($role_permissions['perms_auto']) ? intval($role_permissions['perms_accept']) : 0)); foreach($role_permissions as $p => $v) { @@ -864,11 +864,7 @@ class Settings extends \Zotlabs\Web\Controller { return $o; } - - - - - + if(argv(1) === 'channel') { require_once('include/acl_selectors.php'); @@ -885,9 +881,8 @@ class Settings extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); - - $global_perms = get_perms(); - + $global_perms = \Zotlabs\Access\Permissions::Perms(); + $permiss = array(); $perm_opts = array( @@ -905,15 +900,13 @@ class Settings extends \Zotlabs\Web\Controller { foreach($global_perms as $k => $perm) { $options = array(); foreach($perm_opts as $opt) { - if((! $perm[2]) && $opt[1] == PERMS_PUBLIC) - continue; $options[$opt[1]] = $opt[0]; } - $permiss[] = array($k,$perm[3],$channel[$perm[0]],$perm[4],$options); + $permiss[] = array($k,$perm,$channel[$perm[0]],$perm[4],$options); } - // logger('permiss: ' . print_r($permiss,true)); + // logger('permiss: ' . print_r($permiss,true)); -- cgit v1.2.3 From d566ffa678dc9f035a022304a82560b19495a838 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 4 Jul 2016 17:55:13 -0700 Subject: more heavy lifting on extensible perms --- Zotlabs/Module/Connedit.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 7db4950b1..4469330e8 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -131,6 +131,8 @@ class Connedit extends \Zotlabs\Web\Controller { foreach($_POST as $k => $v) { if(strpos($k,'perms_') === 0) { + $perm = substr($k,6); + set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,(($v) ? 1 : 0)); $abook_my_perms += $v; } } @@ -654,7 +656,8 @@ class Connedit extends \Zotlabs\Web\Controller { $perms = array(); $channel = \App::get_channel(); - $global_perms = get_perms(); + $global_perms = \Zotlabs\Access\Permissions::Perms(); + $existing = get_all_perms(local_channel(),$contact['abook_xchan']); $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes'))); @@ -671,8 +674,10 @@ class Connedit extends \Zotlabs\Web\Controller { $affinity = t('Set Affinity & Profile'); foreach($global_perms as $k => $v) { - $thisperm = (($contact['abook_my_perms'] & $v[1]) ? "1" : ''); - $checkinherited = ((($channel[$v[0]]) && ($channel[$v[0]] != PERMS_SPECIFIC)) ? "1" : ''); + $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); +//fixme + + $checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k); // For auto permissions (when $self is true) we don't want to look at existing // permissions because they are enabled for the channel owner -- cgit v1.2.3 From e6224898d29b605da6751b6744f0e544250b600a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 4 Jul 2016 21:33:25 -0700 Subject: more heavy lifting on xtensible perms --- Zotlabs/Module/Connedit.php | 11 +++++++---- Zotlabs/Module/Settings.php | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 4469330e8..a5c5175dc 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -197,8 +197,11 @@ class Connedit extends \Zotlabs\Web\Controller { $role = get_pconfig(local_channel(),'system','permissions_role'); if($role) { $x = get_role_perms($role); - if($x['perms_accept']) - $abook_my_perms = $x['perms_accept']; + if($x['perms_connect']) { + foreach($x['perms_connect'] as $p) { + set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'my_perms',$p,1); + } + } } } @@ -374,8 +377,8 @@ class Connedit extends \Zotlabs\Web\Controller { $role = get_pconfig(local_channel(),'system','permissions_role'); if($role) { $x = get_role_perms($role); - if($x['perms_accept']) - $my_perms = $x['perms_accept']; + if($x['perms_connect']) + $my_perms = $x['perms_connect']; } $yes_no = array(t('No'),t('Yes')); diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 5c9ff1db0..85da261fc 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -371,7 +371,7 @@ class Settings extends \Zotlabs\Web\Controller { } foreach($global_perms as $k => $v) { - set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k,((array_key_exists($k,$role_permissions['perms_accept'])) ? intval($role_permissions['perms_accept'][$k]))); + set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k,((array_key_exists($k,$role_permissions['perms_connect'])) ? 1 : 0)); } set_pconfig(local_channel(),'system','autoperms',(($role_permissions['perms_auto']) ? intval($role_permissions['perms_accept']) : 0)); -- cgit v1.2.3 From d4627a0b1c1a0e08bb0606cf4b6ba4823b7a2862 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 6 Jul 2016 21:31:05 +0200 Subject: fix /cloud after recent changes --- Zotlabs/Module/Cloud.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 833b1b493..2ef67a3f3 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -23,7 +23,6 @@ require_once('vendor/autoload.php'); class Cloud extends \Zotlabs\Web\Controller { function init() { - require_once('include/reddav.php'); if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); @@ -81,7 +80,7 @@ class Cloud extends \Zotlabs\Web\Controller { if($_SERVER['REQUEST_METHOD'] === 'GET') { try { - $x = RedFileData('/' . \App::$cmd, $auth); + $x = $rootDirectory->CollectionData('/' . \App::$cmd, $auth); } catch(\Exception $e) { if($e instanceof Sabre\DAV\Exception\Forbidden) { -- cgit v1.2.3 From 227320f6f01dec264de820863f971d3e92a486ff Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 7 Jul 2016 20:16:27 +0200 Subject: more fixes for /cloud and /dav --- Zotlabs/Module/Cloud.php | 11 ----------- Zotlabs/Module/Dav.php | 2 -- 2 files changed, 13 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 2ef67a3f3..9845c5658 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -78,17 +78,6 @@ class Cloud extends \Zotlabs\Web\Controller { $is_readable = false; - if($_SERVER['REQUEST_METHOD'] === 'GET') { - try { - $x = $rootDirectory->CollectionData('/' . \App::$cmd, $auth); - } - catch(\Exception $e) { - if($e instanceof Sabre\DAV\Exception\Forbidden) { - http_status_exit(401, 'Permission denied.'); - } - } - } - // provide a directory view for the cloud in Hubzilla $browser = new \Zotlabs\Storage\Browser($auth); $auth->setBrowserPlugin($browser); diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 6528e0271..9b4b576c8 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -44,8 +44,6 @@ class Dav extends \Zotlabs\Web\Controller { } } - require_once('include/reddav.php'); - if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); -- cgit v1.2.3 From 233cfc29d6e68f8a8453fab2ebb733ab35fa4b67 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 7 Jul 2016 17:23:52 -0700 Subject: hide the redeliver option one level down since it should rarely be needed by folks outside of shared hosting. --- Zotlabs/Module/Dreport.php | 1 + 1 file changed, 1 insertion(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index 17ed6515e..d2933b464 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -146,6 +146,7 @@ class Dreport extends \Zotlabs\Web\Controller { '$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...', '$table' => $table, '$mid' => urlencode($mid), + '$options' => t('Options'), '$push' => t('Redeliver'), '$entries' => $entries )); -- cgit v1.2.3 From eef40cb3fdb119425848e5e6cfa4680a2b5d85d9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 7 Jul 2016 18:47:18 -0700 Subject: duplicate supression SQL query was horribly inefficient and could cause issues in resource deprived environments. --- Zotlabs/Module/Item.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 369dd3948..7167d218e 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -93,7 +93,7 @@ class Item extends \Zotlabs\Web\Controller { $origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1); - // To represent message-ids on other networks - this will create an item_id record + // To represent message-ids on other networks - this will create an iconfig record $namespace = (($api_source && array_key_exists('namespace',$_REQUEST)) ? strip_tags($_REQUEST['namespace']) : ''); $remote_id = (($api_source && array_key_exists('remote_id',$_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : ''); @@ -535,7 +535,7 @@ class Item extends \Zotlabs\Web\Controller { } /** - * fix naked links by passing through a callback to see if this is a red site + * fix naked links by passing through a callback to see if this is a hubzilla site * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. * First protect any url inside certain bbcode tags so we don't double link it. */ @@ -834,21 +834,23 @@ class Item extends \Zotlabs\Web\Controller { if($orig_post) $datarray['edit'] = true; + // suppress duplicates, *unless* you're editing an existing post. This could get picked up + // as a duplicate if you're editing it very soon after posting it initially and you edited + // some attribute besides the content, such as title or categories. + if(feature_enabled($profile_uid,'suppress_duplicates') && (! $orig_post)) { - $z = q("select created from item where uid = %d and body = '%s'", + $z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1", intval($profile_uid), - dbesc($body) + dbutcnow(), + db_quoteinterval('2 MINUTE'), + dbesc($body), ); if($z) { - foreach($z as $zz) { - if($zz['created'] > datetime_convert('UTC','UTC', 'now - 2 minutes')) { - $datarray['cancel'] = 1; - notice( t('Duplicate post suppressed.') . EOL); - logger('Duplicate post. Faking plugin cancel.'); - } - } + $datarray['cancel'] = 1; + notice( t('Duplicate post suppressed.') . EOL); + logger('Duplicate post. Faking plugin cancel.'); } } -- cgit v1.2.3 From 3b17dca25216c4e7cca11b00008b9a5ea2855480 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 7 Jul 2016 18:51:56 -0700 Subject: typo --- Zotlabs/Module/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 7167d218e..6eae02692 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -844,7 +844,7 @@ class Item extends \Zotlabs\Web\Controller { intval($profile_uid), dbutcnow(), db_quoteinterval('2 MINUTE'), - dbesc($body), + dbesc($body) ); if($z) { -- cgit v1.2.3 From ee1ec0428b21cadb324de44f2cd70c3e8403100a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 7 Jul 2016 18:53:09 -0700 Subject: gak one more typo --- Zotlabs/Module/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 6eae02692..58d39da83 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -842,7 +842,7 @@ class Item extends \Zotlabs\Web\Controller { $z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1", intval($profile_uid), - dbutcnow(), + db_utcnow(), db_quoteinterval('2 MINUTE'), dbesc($body) ); -- cgit v1.2.3 From 917a465ccd7dfa4992241b1e5d4418b3a31f1615 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 9 Jul 2016 19:03:29 -0700 Subject: more work on perms --- Zotlabs/Module/Follow.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index 3641330c9..5de89ef41 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -49,10 +49,11 @@ class Follow extends \Zotlabs\Web\Controller { build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone))); + $can_view_stream = intval(get_abconfig($channel['channel_id'],$clone['abook_xchan'],'their_perms','view_stream')); // If we can view their stream, pull in some posts - if(($result['abook']['abook_their_perms'] & PERMS_R_STREAM) || ($result['abook']['xchan_network'] === 'rss')) + if(($can_view_stream) || ($result['abook']['xchan_network'] === 'rss')) \Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id'])); goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); -- cgit v1.2.3 From c9db8c6857d8676b3eb3c19548eb303656dc5fff Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 9 Jul 2016 21:08:02 -0700 Subject: more permissions work --- Zotlabs/Module/Connedit.php | 17 ++++++++++++++++- Zotlabs/Module/Settings.php | 5 +++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index a5c5175dc..445219894 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -676,6 +676,18 @@ class Connedit extends \Zotlabs\Web\Controller { if($slide && $multiprofs) $affinity = t('Set Affinity & Profile'); + $theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'", + intval(local_channel()), + dbesc($contact['abook_xchan']) + ); + $their_perms = array(); + if($theirs) { + foreach($theirs as $t) { + $their_perms[$t['k']] = $t['v']; + } + } +logger('theris: ' . print_r($their_perms,true)); + foreach($global_perms as $k => $v) { $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); //fixme @@ -686,8 +698,11 @@ class Connedit extends \Zotlabs\Web\Controller { // permissions because they are enabled for the channel owner if((! $self) && ($existing[$k])) $thisperm = "1"; + + + - $perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),$thisperm, $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4], $checkinherited); + $perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); } $locstr = ''; diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 85da261fc..7f34f52b1 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -896,17 +896,18 @@ class Settings extends \Zotlabs\Web\Controller { array( t('Anybody on the internet'), PERMS_PUBLIC) ); + $limits = \Zotlabs\Access\PermissionLimits::Get(local_channel()); foreach($global_perms as $k => $perm) { $options = array(); foreach($perm_opts as $opt) { $options[$opt[1]] = $opt[0]; } - $permiss[] = array($k,$perm,$channel[$perm[0]],$perm[4],$options); + $permiss[] = array($k,$perm,$limits[$k],'',$options); } - // logger('permiss: ' . print_r($permiss,true)); + //logger('permiss: ' . print_r($permiss,true)); -- cgit v1.2.3 From 3d3584b36c9cb1d8d0dfe9c036b77bbc921f4c59 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sun, 10 Jul 2016 13:42:04 +0200 Subject: remove check for mcrypt --- Zotlabs/Module/Setup.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index c5d0ccc21..802f0c216 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -493,7 +493,6 @@ class Setup extends \Zotlabs\Web\Controller { $this->check_add($ck_funcs, t('OpenSSL PHP module'), true, true); $this->check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true); $this->check_add($ck_funcs, t('mb_string PHP module'), true, true); - $this->check_add($ck_funcs, t('mcrypt PHP module'), true, true); $this->check_add($ck_funcs, t('xml PHP module'), true, true); if(function_exists('apache_get_modules')){ @@ -530,10 +529,6 @@ class Setup extends \Zotlabs\Web\Controller { $ck_funcs[4]['status'] = false; $ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.'); } - if(! function_exists('mcrypt_encrypt')) { - $ck_funcs[5]['status'] = false; - $ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.'); - } if(! extension_loaded('xml')) { $ck_funcs[6]['status'] = false; $ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.'); -- cgit v1.2.3 From 67c60229ca663135e8de5b99b27b0838fa6c205a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 11 Jul 2016 13:20:12 -0700 Subject: use the profile_uid here. --- Zotlabs/Module/Item.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 58d39da83..235c5528e 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -905,7 +905,7 @@ class Item extends \Zotlabs\Web\Controller { if($r) { xchan_query($r); $sync_item = fetch_post_tags($r); - build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)))); + build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true)))); } } if(! $nopush) @@ -1000,7 +1000,7 @@ class Item extends \Zotlabs\Web\Controller { if($r) { xchan_query($r); $sync_item = fetch_post_tags($r); - build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)))); + build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true)))); } } @@ -1014,11 +1014,6 @@ class Item extends \Zotlabs\Web\Controller { logger('post_complete'); - - - - - // figure out how to return, depending on from whence we came if($api_source) -- cgit v1.2.3 From 71b001fdb7f4c900f6e7ff15a29952d6dc82c1fc Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 11 Jul 2016 17:02:49 -0700 Subject: more perms work - notably the stuff in public_perms --- Zotlabs/Module/Connedit.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 445219894..8aecfca4c 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -129,14 +129,21 @@ class Connedit extends \Zotlabs\Web\Controller { $abook_my_perms = 0; - foreach($_POST as $k => $v) { - if(strpos($k,'perms_') === 0) { - $perm = substr($k,6); - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,(($v) ? 1 : 0)); - $abook_my_perms += $v; + $all_perms = \Zotlabs\Access\Permissions::Perms(); + + if($all_perms) { + foreach($all_perms as $perm => $desc) { + if(in_array('perms_' . $perm, $_POST)) { + set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm, + intval($_POST['perms_' . $perm])); + $abook_my_perms ++; + } + else { + set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0); + } } } - + $new_friend = false; if(! $is_self) { @@ -686,7 +693,6 @@ class Connedit extends \Zotlabs\Web\Controller { $their_perms[$t['k']] = $t['v']; } } -logger('theris: ' . print_r($their_perms,true)); foreach($global_perms as $k => $v) { $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); -- cgit v1.2.3 From ed0e2b52d7cf66ada81208c5068f70568a0b2310 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 11 Jul 2016 21:46:16 -0700 Subject: move permissiondescription class to zotlabs/lib --- Zotlabs/Module/Channel.php | 3 +-- Zotlabs/Module/Editwebpage.php | 3 +-- Zotlabs/Module/Events.php | 3 +-- Zotlabs/Module/Filestorage.php | 3 +-- Zotlabs/Module/Network.php | 4 +--- Zotlabs/Module/Photos.php | 6 ++---- Zotlabs/Module/Rpost.php | 3 +-- Zotlabs/Module/Settings.php | 4 +--- Zotlabs/Module/Webpages.php | 3 +-- 9 files changed, 10 insertions(+), 22 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index d09388901..c74802ec5 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -9,7 +9,6 @@ require_once('include/security.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); require_once('include/permissions.php'); -require_once('include/PermissionDescription.php'); class Channel extends \Zotlabs\Web\Controller { @@ -133,7 +132,7 @@ class Channel extends \Zotlabs\Web\Controller { 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), 'nickname' => \App::$profile['channel_address'], 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php index 5cd409e1e..be4803a07 100644 --- a/Zotlabs/Module/Editwebpage.php +++ b/Zotlabs/Module/Editwebpage.php @@ -4,7 +4,6 @@ namespace Zotlabs\Module; require_once('include/channel.php'); require_once('include/acl_selectors.php'); require_once('include/conversation.php'); -require_once('include/PermissionDescription.php'); class Editwebpage extends \Zotlabs\Web\Controller { @@ -151,7 +150,7 @@ class Editwebpage extends \Zotlabs\Web\Controller { 'body' => undo_post_tagging($itm[0]['body']), 'post_id' => $post_id, 'visitor' => ($is_owner) ? true : false, - 'acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')), + 'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')), 'showacl' => ($is_owner) ? true : false, 'mimetype' => $mimetype, 'mimeselect' => true, diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index 3187cddb4..def5c437b 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -6,7 +6,6 @@ require_once('include/bbcode.php'); require_once('include/datetime.php'); require_once('include/event.php'); require_once('include/items.php'); -require_once('include/PermissionDescription.php'); class Events extends \Zotlabs\Web\Controller { @@ -471,7 +470,7 @@ class Events extends \Zotlabs\Web\Controller { '$permissions' => t('Permission settings'), // populating the acl dialog was a permission description from view_stream because Cal.php, which // displays events, says "since we don't currently have an event permission - use the stream permission" - '$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \PermissionDescription::fromGlobalPermission('view_stream'))), + '$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'))), '$submit' => t('Submit'), '$advanced' => t('Advanced Options') diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php index 2861f31be..c3ef22e32 100644 --- a/Zotlabs/Module/Filestorage.php +++ b/Zotlabs/Module/Filestorage.php @@ -6,7 +6,6 @@ namespace Zotlabs\Module; */ require_once('include/attach.php'); -require_once('include/PermissionDescription.php'); /** @@ -134,7 +133,7 @@ class Filestorage extends \Zotlabs\Web\Controller { $cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : ''); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']); - $aclselect_e = populate_acl($f, false, \PermissionDescription::fromGlobalPermission('view_storage')); + $aclselect_e = populate_acl($f, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')); $is_a_dir = (intval($f['is_dir']) ? true : false); $lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock'); diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 87ed326e2..3b88cd8d6 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -6,8 +6,6 @@ require_once('include/group.php'); require_once('include/contact_widgets.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); -require_once('include/PermissionDescription.php'); - class Network extends \Zotlabs\Web\Controller { @@ -171,7 +169,7 @@ class Network extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 1633e08ef..1eeab1461 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -9,8 +9,6 @@ require_once('include/bbcode.php'); require_once('include/security.php'); require_once('include/attach.php'); require_once('include/text.php'); -require_once('include/PermissionDescription.php'); - class Photos extends \Zotlabs\Web\Controller { @@ -633,7 +631,7 @@ class Photos extends \Zotlabs\Web\Controller { $lockstate = (($acl->is_private()) ? 'lock' : 'unlock'); } - $aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_storage')) : ''); + $aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : ''); // this is wrong but is to work around an issue with js_upload wherein it chokes if these variables // don't exist. They really should be set to a parseable representation of the channel's default permissions @@ -1023,7 +1021,7 @@ class Photos extends \Zotlabs\Web\Controller { if($can_post) { $album_e = $ph[0]['album']; $caption_e = $ph[0]['description']; - $aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \PermissionDescription::fromGlobalPermission('view_storage')) : ''); + $aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : ''); $albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer'])); $_SESSION['album_return'] = bin2hex($ph[0]['album']); diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php index 1396f2a55..32d52c30c 100644 --- a/Zotlabs/Module/Rpost.php +++ b/Zotlabs/Module/Rpost.php @@ -7,7 +7,6 @@ require_once('include/items.php'); require_once('include/taxonomy.php'); require_once('include/conversation.php'); require_once('include/zot.php'); -require_once('include/PermissionDescription.php'); /** * remote post @@ -116,7 +115,7 @@ class Rpost extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl, true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl($channel_acl, true, Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => '', 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 875004fae..af246a4dc 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -2,8 +2,6 @@ namespace Zotlabs\Module; /** @file */ require_once('include/zot.php'); -require_once('include/PermissionDescription.php'); - class Settings extends \Zotlabs\Web\Controller { @@ -1066,7 +1064,7 @@ class Settings extends \Zotlabs\Web\Controller { '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), '$permissions' => t('Default Post and Publish Permissions'), '$permdesc' => t("\x28click to open/close\x29"), - '$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), + '$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), '$suggestme' => $suggestme, '$group_select' => $group_select, '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()), diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index bb8d9c6ed..cc0a01cce 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -4,7 +4,6 @@ namespace Zotlabs\Module; require_once('include/channel.php'); require_once('include/conversation.php'); require_once('include/acl_selectors.php'); -require_once('include/PermissionDescription.php'); class Webpages extends \Zotlabs\Web\Controller { @@ -105,7 +104,7 @@ class Webpages extends \Zotlabs\Web\Controller { 'is_owner' => true, 'nickname' => \App::$profile['channel_address'], 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''), 'showacl' => (($is_owner) ? true : false), 'visitor' => true, 'hide_location' => true, -- cgit v1.2.3 From f4e4e734de001de50b2a1a3119997b444bf12134 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 12 Jul 2016 21:47:24 -0700 Subject: more work on perms --- Zotlabs/Module/Acl.php | 12 ++++++------ Zotlabs/Module/Mail.php | 12 ++---------- Zotlabs/Module/Manage.php | 4 ++-- 3 files changed, 10 insertions(+), 18 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 2bc4ba62d..e404a7e9d 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -97,7 +97,7 @@ class Acl extends \Zotlabs\Web\Controller { if($extra_channels_sql != '') $extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 "; - $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self + $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self FROM abook left join xchan on abook_xchan = xchan_hash WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , intval(local_channel()) @@ -105,7 +105,7 @@ class Acl extends \Zotlabs\Web\Controller { } else { // Visitors - $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self + $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, xchan_pubforum, 0 as abook_flags, 0 as abook_self FROM xchan left join xlink on xlink_link = xchan_hash WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , dbesc(get_observer_hash()) @@ -121,7 +121,7 @@ class Acl extends \Zotlabs\Web\Controller { $known_hashes[] = "'".$rr['hash']."'"; $known_hashes_sql = 'AND xchan_hash not in ('.join(',',$known_hashes).')'; - $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self + $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc"); if($r2) @@ -150,7 +150,7 @@ class Acl extends \Zotlabs\Web\Controller { } if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) { if((count($r) < 100) && $type == 'c') { - $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self + $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self, xchan_pubforum FROM xchan WHERE xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ); @@ -173,7 +173,7 @@ class Acl extends \Zotlabs\Web\Controller { } elseif(($type == 'a') || ($type == 'p')) { - $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash + $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , xchan_pubforum, abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and xchan_deleted = 0 $sql_extra3 @@ -213,7 +213,7 @@ class Acl extends \Zotlabs\Web\Controller { if(strpos($g['hash'],'/') && $type != 'a') continue; - if(($g['abook_their_perms'] & PERMS_W_TAGWALL) && $type == 'c' && (! $noforums)) { + if(($g['xchan_pubforum']) && $type == 'c' && (! $noforums)) { $contacts[] = array( "type" => "c", "photo" => "images/twopeople.png", diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index aae7585c4..043c28078 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -57,8 +57,6 @@ class Mail extends \Zotlabs\Web\Controller { $their_perms = 0; - $global_perms = get_perms(); - if($j['permissions']['data']) { $permissions = crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']); if($permissions) @@ -68,13 +66,7 @@ class Mail extends \Zotlabs\Web\Controller { else $permissions = $j['permissions']; - foreach($permissions as $k => $v) { - if($v) { - $their_perms = $their_perms | intval($global_perms[$k][1]); - } - } - - if(! ($their_perms & PERMS_W_MAIL)) { + if(! ($permissions['post_mail'])) { notice( t('Selected channel has private message restrictions. Send failed.')); // reported issue: let's still save the message and continue. We'll just tell them // that nothing useful is likely to happen. They might have spent hours on it. @@ -120,7 +112,7 @@ class Mail extends \Zotlabs\Web\Controller { } - function get() { + function get() { $o = ''; nav_set_selected('messages'); diff --git a/Zotlabs/Module/Manage.php b/Zotlabs/Module/Manage.php index 4ca044c4a..8f815d6d4 100644 --- a/Zotlabs/Module/Manage.php +++ b/Zotlabs/Module/Manage.php @@ -143,9 +143,9 @@ class Manage extends \Zotlabs\Web\Controller { $create = array( 'new_channel', t('Create a new channel'), t('Create New')); $delegates = q("select * from abook left join xchan on abook_xchan = xchan_hash where - abook_channel = %d and (abook_their_perms & %d) > 0", + abook_channel = %d and abook_xchan in ( select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'delegate' and v = 1 )", intval(local_channel()), - intval(PERMS_A_DELEGATE) + intval(local_channel()) ); if($delegates) { -- cgit v1.2.3 From 18565600b2b9e36f1792bf29d5575f681fafc0b5 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 12 Jul 2016 22:58:12 -0700 Subject: missing namespace prefix \ --- Zotlabs/Module/Rpost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php index 32d52c30c..9e3043d10 100644 --- a/Zotlabs/Module/Rpost.php +++ b/Zotlabs/Module/Rpost.php @@ -115,7 +115,7 @@ class Rpost extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl, true, Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'bang' => '', 'visitor' => true, 'profile_uid' => local_channel(), -- cgit v1.2.3 From f60a0c5ce050febb0b200938eb51d88cf563b88f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 13 Jul 2016 17:51:19 -0700 Subject: document mod_acl a bit better and try to remove some redundancies and consolidate the various options --- Zotlabs/Module/Acl.php | 84 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 25 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 2bc4ba62d..f33e257f4 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -1,7 +1,18 @@ standard ACL request + // 'g' => Groups only ACL request + // 'c' => Connections only ACL request or editor (textarea) mention request + // $_REQUEST['search'] contains ACL search text. + + + // $type = + // 'm' => autocomplete private mail recipient (checks post_mail permission) + // 'a' => autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos) + // 'x' => nav search bar autocomplete (match any xchan) + // $_REQUEST['query'] contains autocomplete search text. + + // List of channels whose connections to also suggest, + // e.g. currently viewed channel or channels mentioned in a post + $extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array()); - // For use with jquery.autocomplete for private mail completion + // The different autocomplete libraries use different names for the search text + // parameter. Internaly we'll use $search to represent the search text no matter + // what request variable it was attached to. - if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) { - if(! $type) - $type = 'm'; + if(array_key_exists('query',$_REQUEST)) { $search = $_REQUEST['query']; } - if(!(local_channel())) - if(!($type == 'x' || $type == 'c')) - killme(); + if( (! local_channel()) && (! ($type == 'x' || $type == 'c'))) + killme(); - if ($search != "") { + if($search) { $sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; - // This horrible mess is needed because position also returns 0 if nothing is found. W/ould be MUCH easier if it instead returned a very large value - // Otherwise we could just order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)). - $order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) ." then POSITION('".dbesc($search)."' IN xchan_name) else position('".dbesc($search)."' IN xchan_addr) end, "; + // This horrible mess is needed because position also returns 0 if nothing is found. + // Would be MUCH easier if it instead returned a very large value + // Otherwise we could just + // order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)). + + $order_extra2 = "CASE WHEN xchan_name LIKE " + . protect_sprintf( "'%" . dbesc($search) . "%'" ) + . " then POSITION('" . dbesc($search) + . "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, "; + $col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' ); $sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; - } else { + } + else { $sql_extra = $sql_extra2 = $sql_extra3 = ""; } @@ -51,7 +85,7 @@ class Acl extends \Zotlabs\Web\Controller { $groups = array(); $contacts = array(); - if ($type=='' || $type=='g'){ + if($type == '' || $type == 'g') { $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname` FROM `groups`,`group_member` @@ -82,7 +116,7 @@ class Acl extends \Zotlabs\Web\Controller { } } - if ($type=='' || $type=='c') { + if($type == '' || $type == 'c') { $extra_channels_sql = ''; // Only include channels who allow the observer to view their permissions foreach($extra_channels as $channel) { @@ -171,7 +205,7 @@ class Acl extends \Zotlabs\Web\Controller { intval(PERMS_W_MAIL) ); } - elseif(($type == 'a') || ($type == 'p')) { + elseif($type == 'a') { $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d @@ -296,7 +330,7 @@ class Acl extends \Zotlabs\Web\Controller { $url = $directory['url'] . '/dirsearch'; } - $count = (x($_REQUEST,'count')?$_REQUEST['count']:100); + $count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100); if($url) { $query = $url . '?f=' ; $query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : ''); -- cgit v1.2.3 From 1fd65c934da1efcbc3e44c5ec1c5112859ba50f9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 13 Jul 2016 19:53:28 -0700 Subject: lots more permission work --- Zotlabs/Module/Acl.php | 59 +++++++++++++++++++++++++++++++-------------- Zotlabs/Module/Connedit.php | 2 +- Zotlabs/Module/Probe.php | 2 -- 3 files changed, 42 insertions(+), 21 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index d7516af33..0e02a2f66 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -58,7 +58,23 @@ class Acl extends \Zotlabs\Web\Controller { if( (! local_channel()) && (! ($type == 'x' || $type == 'c'))) killme(); - + + $permitted = []; + + if(in_array($type, [ 'm', 'a', 'c' ])) { + + // These queries require permission checking. We'll create a simple array of xchan_hash for those with + // the requisite permissions which we can check against. + + $x = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = '%s' and v = 1", + intval(local_channel()), + dbesc(($type === 'm') ? 'post_mail' : 'tag_deliver') + ); + + $permitted = ids_to_array($x,'xchan'); + } + + if($search) { $sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; @@ -87,13 +103,13 @@ class Acl extends \Zotlabs\Web\Controller { if($type == '' || $type == 'g') { - $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname` - FROM `groups`,`group_member` - WHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d - AND `group_member`.`gid`=`groups`.`id` + $r = q("SELECT groups.id, groups.hash, groups.gname + FROM groups,group_member + WHERE groups.deleted = 0 AND groups.uid = %d + AND group_member.gid=groups.id $sql_extra - GROUP BY `groups`.`id` - ORDER BY `groups`.`gname` + GROUP BY groups.id + ORDER BY groups.gname LIMIT %d OFFSET %d", intval(local_channel()), intval($count), @@ -139,7 +155,7 @@ class Acl extends \Zotlabs\Web\Controller { } else { // Visitors - $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, xchan_pubforum, 0 as abook_flags, 0 as abook_self + $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self FROM xchan left join xlink on xlink_link = xchan_hash WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , dbesc(get_observer_hash()) @@ -155,7 +171,7 @@ class Acl extends \Zotlabs\Web\Controller { $known_hashes[] = "'".$rr['hash']."'"; $known_hashes_sql = 'AND xchan_hash not in ('.join(',',$known_hashes).')'; - $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self + $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc"); if($r2) @@ -184,7 +200,7 @@ class Acl extends \Zotlabs\Web\Controller { } if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) { if((count($r) < 100) && $type == 'c') { - $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self, xchan_pubforum + $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self FROM xchan WHERE xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ); @@ -194,20 +210,27 @@ class Acl extends \Zotlabs\Web\Controller { } } elseif($type == 'm') { - - $r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url + $r = array(); + $z = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0) + WHERE abook_channel = %d and xchan_deleted = 0 $sql_extra3 - ORDER BY `xchan_name` ASC ", - intval(local_channel()), - intval(PERMS_W_MAIL) + ORDER BY xchan_name ASC ", + intval(local_channel()) ); + if($z) { + foreach($z as $zz) { + if(in_array($zz['id'],$permitted)) { + $r[] = $zz; + } + } + } + } elseif($type == 'a') { - $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , xchan_pubforum, abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash + $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and xchan_deleted = 0 $sql_extra3 @@ -247,7 +270,7 @@ class Acl extends \Zotlabs\Web\Controller { if(strpos($g['hash'],'/') && $type != 'a') continue; - if(($g['xchan_pubforum']) && $type == 'c' && (! $noforums)) { + if(in_array($g['hash'],$permitted) && $type == 'c' && (! $noforums)) { $contacts[] = array( "type" => "c", "photo" => "images/twopeople.png", diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 8aecfca4c..f9b1336a8 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -133,7 +133,7 @@ class Connedit extends \Zotlabs\Web\Controller { if($all_perms) { foreach($all_perms as $perm => $desc) { - if(in_array('perms_' . $perm, $_POST)) { + if(array_key_exists('perms_' . $perm, $_POST)) { set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm, intval($_POST['perms_' . $perm])); $abook_my_perms ++; diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php index dda792131..7fc0e8ff5 100644 --- a/Zotlabs/Module/Probe.php +++ b/Zotlabs/Module/Probe.php @@ -23,8 +23,6 @@ class Probe extends \Zotlabs\Web\Controller { $j = \Zotlabs\Zot\Finger::run($addr,$channel,false); - // $res = zot_finger($addr,$channel,false); - $o .= '
    ';
     			if(! $j['success']) {
     				$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
    -- 
    cgit v1.2.3
    
    
    From b3a785711cde52a3c03c0a0eb90ce4e9ce8d9059 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Wed, 13 Jul 2016 22:11:06 -0700
    Subject: deprecate/remove json_decode_plus
    
    ---
     Zotlabs/Module/Editpost.php    | 4 ++--
     Zotlabs/Module/Editwebpage.php | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php
    index da859de3e..838fe9e4f 100644
    --- a/Zotlabs/Module/Editpost.php
    +++ b/Zotlabs/Module/Editpost.php
    @@ -47,9 +47,9 @@ class Editpost extends \Zotlabs\Web\Controller {
     		if(intval($itm[0]['item_obscured'])) {
     			$key = get_config('system','prvkey');
     			if($itm[0]['title'])
    -				$itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key);
    +				$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
     			if($itm[0]['body'])
    -				$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
    +				$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
     		}
     
     		$category = '';
    diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php
    index be4803a07..a55f81101 100644
    --- a/Zotlabs/Module/Editwebpage.php
    +++ b/Zotlabs/Module/Editwebpage.php
    @@ -108,9 +108,9 @@ class Editwebpage extends \Zotlabs\Web\Controller {
     		if(intval($itm[0]['item_obscured'])) {
     			$key = get_config('system','prvkey');
     			if($itm[0]['title'])
    -				$itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key);
    +				$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
     			if($itm[0]['body'])
    -				$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
    +				$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
     		}
     
     		$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
    -- 
    cgit v1.2.3
    
    
    From 191cd21028ab108c2a7f982c654601d780865eff Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Wed, 13 Jul 2016 23:05:19 -0700
    Subject: more perms work
    
    ---
     Zotlabs/Module/Connedit.php | 20 +++++++++++++-------
     Zotlabs/Module/Follow.php   |  2 +-
     2 files changed, 14 insertions(+), 8 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
    index f9b1336a8..260952b4e 100644
    --- a/Zotlabs/Module/Connedit.php
    +++ b/Zotlabs/Module/Connedit.php
    @@ -205,20 +205,26 @@ class Connedit extends \Zotlabs\Web\Controller {
     			if($role) {
     				$x = get_role_perms($role);
     				if($x['perms_connect']) {
    -					foreach($x['perms_connect'] as $p) {
    -						set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'my_perms',$p,1);
    -					}
    +					$abook_my_perms = $x['perms_connect'];
    +				}
    +			}
    +
    +			if($all_perms) {
    +				foreach($all_perms as $perm => $desc) {
    +					if(array_key_exists($perm, $abook_my_perms))
    +						set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,1);
    +					else
    +						set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0);
     				}
     			}
     		}
    -	
    +
     		$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
     	
    -		$r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_pending = %d,
    +		$r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d,
     			abook_incl = '%s', abook_excl = '%s'
     			where abook_id = %d AND abook_channel = %d",
     			dbesc($profile_id),
    -			intval($abook_my_perms),
     			intval($closeness),
     			intval($abook_pending),
     			dbesc($abook_incl),
    @@ -239,7 +245,7 @@ class Connedit extends \Zotlabs\Web\Controller {
     			info( t('Connection updated.') . EOL);
     		else
     			notice( t('Failed to update connection record.') . EOL);
    -	
    +//@fixme perms	
     		if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms
     			&& (! intval(\App::$poi['abook_self']))) {
     			\Zotlabs\Daemon\Master::Summon(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id));
    diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php
    index 5de89ef41..da9ab3670 100644
    --- a/Zotlabs/Module/Follow.php
    +++ b/Zotlabs/Module/Follow.php
    @@ -47,7 +47,7 @@ class Follow extends \Zotlabs\Web\Controller {
     		if($abconfig)
     			$clone['abconfig'] = $abconfig;
     	
    -		build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
    +		build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)), true);
     	
     		$can_view_stream = intval(get_abconfig($channel['channel_id'],$clone['abook_xchan'],'their_perms','view_stream'));
     	
    -- 
    cgit v1.2.3
    
    
    From f70f4a4e8558a6d715eb7ca0d02ac38753094068 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Thu, 14 Jul 2016 20:26:22 -0700
    Subject: add zat to acl
    
    ---
     Zotlabs/Module/Acl.php | 27 ++++++++++++++++++++++++++-
     1 file changed, 26 insertions(+), 1 deletion(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
    index f33e257f4..c8a4fdd7c 100644
    --- a/Zotlabs/Module/Acl.php
    +++ b/Zotlabs/Module/Acl.php
    @@ -130,13 +130,38 @@ class Acl extends \Zotlabs\Web\Controller {
     			if(local_channel()) {
     				if($extra_channels_sql != '')
     					$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
    +
    +				$r2 = null;
    +
    +				$r1 = q("select * from atoken where atoken_uid = %d",
    +					intval(local_channel())
    +				);
    +				if($r1) {
    +					$r2 = array();
    +					foreach($r1 as $rr) {
    +						$r2[] = [ 
    +							'id' => 'a' . $rr['atoken_id'] ,
    +							'hash' => $rr['atoken_uid'] . '.' . $rr['atoken_name'],
    +							'name' => $rr['atoken_name'],
    +							'micro' => get_default_profile_photo(48),
    +							'url' => z_root(),
    +							'nick' => t('guest:') . $rr['atoken_name'],
    +							'abook_their_perms' => 0,
    +							'abook_flags' => 0,
    +							'abook_self' => 0
    +						];
    +					}
    +				} 
    +
     	
     				$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self 
     					FROM abook left join xchan on abook_xchan = xchan_hash 
     					WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
     					intval(local_channel())
     				);
    -	
    +				if($r2)
    +					$r = array_merge($r2,$r);
    +
     			}
     			else { // Visitors
     				$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
    -- 
    cgit v1.2.3
    
    
    From 397a23499dc64e2abdd2c27ccdf7e059a23dcfff Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Thu, 14 Jul 2016 21:28:17 -0700
    Subject: make the xchan_hash for the access token location independent
    
    ---
     Zotlabs/Module/Acl.php | 10 ++++++----
     1 file changed, 6 insertions(+), 4 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
    index c8a4fdd7c..15609c3c8 100644
    --- a/Zotlabs/Module/Acl.php
    +++ b/Zotlabs/Module/Acl.php
    @@ -137,15 +137,17 @@ class Acl extends \Zotlabs\Web\Controller {
     					intval(local_channel())
     				);
     				if($r1) {
    +					require_once('include/security.php');
     					$r2 = array();
     					foreach($r1 as $rr) {
    +						$x = atoken_xchan($rr);
     						$r2[] = [ 
     							'id' => 'a' . $rr['atoken_id'] ,
    -							'hash' => $rr['atoken_uid'] . '.' . $rr['atoken_name'],
    -							'name' => $rr['atoken_name'],
    -							'micro' => get_default_profile_photo(48),
    +							'hash' => $x['xchan_hash'],
    +							'name' => $x['xchan_name'],
    +							'micro' => $x['xchan_photo_m'],
     							'url' => z_root(),
    -							'nick' => t('guest:') . $rr['atoken_name'],
    +							'nick' => $x['xchan_addr'],
     							'abook_their_perms' => 0,
     							'abook_flags' => 0,
     							'abook_self' => 0
    -- 
    cgit v1.2.3
    
    
    From 7ee7f00bf34b11d0427f03df9494088cf56ef9ee Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Thu, 14 Jul 2016 22:41:53 -0700
    Subject: Here's the basic UI for the Zot Access Tokens, requires some minor
     cleanup
    
    ---
     Zotlabs/Module/Settings.php | 78 ++++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 77 insertions(+), 1 deletion(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php
    index af246a4dc..60c9be519 100644
    --- a/Zotlabs/Module/Settings.php
    +++ b/Zotlabs/Module/Settings.php
    @@ -28,7 +28,7 @@ class Settings extends \Zotlabs\Web\Controller {
     	}
     	
     	
    -		function post() {
    +	function post() {
     	
     		if(! local_channel())
     			return;
    @@ -117,6 +117,43 @@ class Settings extends \Zotlabs\Web\Controller {
     			build_sync_packet();
     			return;
     		}
    +
    +
    +		if((argc() > 1) && (argv(1) == 'tokens')) {
    +			check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
    +			
    +			$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
    +			$name = trim(escape_tags($_POST['name']));
    +			$token = trim($_POST['token']);
    +			if(trim($_POST['expires']))
    +				$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
    +			else
    +				$expires = NULL_DATE;
    +
    +			if($atoken_id) {
    +				$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expire = '%s' 
    +					where atoken_id = %d and atoken_uid = %d",
    +					dbesc($name),
    +					dbesc($token),
    +					dbesc($expires),
    +					intval($atoken_id),
    +					intval($channel['channel_id'])
    +				);
    +			}
    +			else {
    +				$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expire )
    +					values ( %d, %d, '%s', '%s', '%s' ) ",
    +					intval($channel['channel_account_id']),
    +					intval($channel['channel_id']),
    +					dbesc($name),
    +					dbesc($token),
    +					dbesc($expires)
    +				);
    +			}
    +		
    +			info( t('Token saved.') . EOL);
    +			return;
    +		}
     	
     	
     	
    @@ -706,6 +743,45 @@ class Settings extends \Zotlabs\Web\Controller {
     			));
     			return $o;
     		}
    +
    +		if((argc() > 1) && (argv(1) === 'tokens')) {
    +			$atoken = null;
    +			if(argc() > 2) {
    +				$id = argv(2);			
    +
    +				$atoken = q("select * from atoken where atoken_id = %d and atoken_uid = %d",
    +					intval($id),
    +					intval(local_channel())
    +				);
    +
    +				if($atoken)
    +					$atoken = $atoken[0];
    +
    +				if($atoken && argc() > 3 && argv(3) === 'drop') {
    +					$r = q("delete from atoken where atoken_id = %d",
    +						intval($id)
    +					);
    +				}
    +			}
    +			$t = q("select * from atoken where atoken_uid = %d",
    +				intval(local_channel())
    +			);			
    +
    +			$tpl = get_markup_template("settings_tokens.tpl");
    +			$o .= replace_macros($tpl, array(
    +				'$form_security_token' => get_form_security_token("settings_tokens"),
    +				'$title'	=> t('Guest Access Tokens'),
    +				'$tokens' => $t,
    +				'$atoken' => $atoken,
    +				'$name' => array('name', t('Login Name'), (($atoken) ? $atoken['atoken_name'] : ''),''),
    +				'$token'=> array('token', t('Login Password'),(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''),
    +				'$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] != NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''),
    +				'$submit' 	=> t('Submit')
    +			));
    +			return $o;
    +		}
    +
    +
     	
     	
     	
    -- 
    cgit v1.2.3
    
    
    From f666d8a0838efec0e05fcd9ea884eb6733cea3a8 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Fri, 15 Jul 2016 01:06:25 -0700
    Subject: enforce non-empty name and token/password on access tokens until
     better checks are instituted.
    
    ---
     Zotlabs/Module/Settings.php | 25 ++++++++++++++++---------
     1 file changed, 16 insertions(+), 9 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php
    index 60c9be519..b1f6c8144 100644
    --- a/Zotlabs/Module/Settings.php
    +++ b/Zotlabs/Module/Settings.php
    @@ -121,15 +121,22 @@ class Settings extends \Zotlabs\Web\Controller {
     
     		if((argc() > 1) && (argv(1) == 'tokens')) {
     			check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
    -			
    -			$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
    -			$name = trim(escape_tags($_POST['name']));
    -			$token = trim($_POST['token']);
    -			if(trim($_POST['expires']))
    -				$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
    -			else
    -				$expires = NULL_DATE;
    -
    +			$token_errs = 0;
    +			if(array_key_exists('token',$_POST)) {
    +				$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
    +				$name = trim(escape_tags($_POST['name']));
    +				$token = trim($_POST['token']);
    +				if((! $name) || (! $token))
    +						$token_errs ++;
    +				if(trim($_POST['expires']))
    +					$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
    +				else
    +					$expires = NULL_DATE;
    +			}
    +			if($token_errs) {
    +				notice( t('Name and Token are required.') . EOL);
    +				return;
    +			}
     			if($atoken_id) {
     				$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expire = '%s' 
     					where atoken_id = %d and atoken_uid = %d",
    -- 
    cgit v1.2.3
    
    
    From 5e475acb85cac2dd87f92f6c8d51dc0071e5c2eb Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Fri, 15 Jul 2016 01:33:28 -0700
    Subject: cleanup and debug of atoken feature
    
    ---
     Zotlabs/Module/Settings.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php
    index b1f6c8144..44088fea5 100644
    --- a/Zotlabs/Module/Settings.php
    +++ b/Zotlabs/Module/Settings.php
    @@ -138,7 +138,7 @@ class Settings extends \Zotlabs\Web\Controller {
     				return;
     			}
     			if($atoken_id) {
    -				$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expire = '%s' 
    +				$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expires = '%s' 
     					where atoken_id = %d and atoken_uid = %d",
     					dbesc($name),
     					dbesc($token),
    @@ -148,7 +148,7 @@ class Settings extends \Zotlabs\Web\Controller {
     				);
     			}
     			else {
    -				$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expire )
    +				$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )
     					values ( %d, %d, '%s', '%s', '%s' ) ",
     					intval($channel['channel_account_id']),
     					intval($channel['channel_id']),
    -- 
    cgit v1.2.3
    
    
    From d54f5a3831ec003468e33185318a060711cb9c09 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Fri, 15 Jul 2016 01:43:09 -0700
    Subject: more cleanup of atoken UI
    
    ---
     Zotlabs/Module/Settings.php | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php
    index 44088fea5..20aa59f78 100644
    --- a/Zotlabs/Module/Settings.php
    +++ b/Zotlabs/Module/Settings.php
    @@ -134,7 +134,7 @@ class Settings extends \Zotlabs\Web\Controller {
     					$expires = NULL_DATE;
     			}
     			if($token_errs) {
    -				notice( t('Name and Token are required.') . EOL);
    +				notice( t('Name and Password are required.') . EOL);
     				return;
     			}
     			if($atoken_id) {
    @@ -774,10 +774,13 @@ class Settings extends \Zotlabs\Web\Controller {
     				intval(local_channel())
     			);			
     
    +			$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access the private content.');
    +
     			$tpl = get_markup_template("settings_tokens.tpl");
     			$o .= replace_macros($tpl, array(
     				'$form_security_token' => get_form_security_token("settings_tokens"),
     				'$title'	=> t('Guest Access Tokens'),
    +				'$desc'     => $desc,
     				'$tokens' => $t,
     				'$atoken' => $atoken,
     				'$name' => array('name', t('Login Name'), (($atoken) ? $atoken['atoken_name'] : ''),''),
    -- 
    cgit v1.2.3
    
    
    From da5ec98f98dd8cef034d568bf0f67231e8517bd4 Mon Sep 17 00:00:00 2001
    From: redmatrix 
    Date: Fri, 15 Jul 2016 02:07:27 -0700
    Subject: make lockview work with throwaway identities
    
    ---
     Zotlabs/Module/Lockview.php | 35 +++++++++++++++++++++++++++++++++--
     1 file changed, 33 insertions(+), 2 deletions(-)
    
    (limited to 'Zotlabs/Module')
    
    diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php
    index 4776e1c56..d86a3c1d8 100644
    --- a/Zotlabs/Module/Lockview.php
    +++ b/Zotlabs/Module/Lockview.php
    @@ -1,17 +1,31 @@
      1) ? argv(1) : 0);
     		if (is_numeric($type)) {
     			$item_id = intval($type);
     			$type='item';
    -		} else {
    +		} 
    +		else {
     			$item_id = ((argc() > 2) ? intval(argv(2)) : 0);
     		}
     	  
    @@ -98,6 +112,13 @@ class Lockview extends \Zotlabs\Web\Controller {
     			if($r)
     				foreach($r as $rr) 
     					$l[] = '
  • ' . $rr['xchan_name'] . '
  • '; + if($atokens) { + foreach($atokens as $at) { + if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) { + $l[] = '
  • ' . $at['xchan_name'] . '
  • '; + } + } + } } if(count($deny_groups)) { $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); @@ -110,6 +131,16 @@ class Lockview extends \Zotlabs\Web\Controller { if($r) foreach($r as $rr) $l[] = '
  • ' . $rr['xchan_name'] . '
  • '; + + if($atokens) { + foreach($atokens as $at) { + if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) { + $l[] = '
  • ' . $at['xchan_name'] . '
  • '; + } + } + } + + } echo $o . implode($l); -- cgit v1.2.3 From dcb3c2c299057467105200e298a03d7b2ee072e8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 15 Jul 2016 15:26:36 -0700 Subject: mod_home: if using an atoken login on the home page redirect to the channel page of the channel that owns the atoken. --- Zotlabs/Module/Home.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php index f3ba96fdd..79449c3b2 100644 --- a/Zotlabs/Module/Home.php +++ b/Zotlabs/Module/Home.php @@ -28,6 +28,19 @@ class Home extends \Zotlabs\Web\Controller { goaway($dest); } + + if(remote_channel() && (! $splash) && $_SESSION['atoken']) { + $r = q("select * from atoken where atoken_id = %d", + intval($_SESSION['atoken']) + ); + if($r) { + $x = channelx_by_n($r[0]['atoken_uid']); + if($x) { + goaway(z_root() . '/channel/' . $x['channel_address']); + } + } + } + if(get_account_id() && ! $splash) { goaway(z_root() . '/new_channel'); -- cgit v1.2.3 From f3aff45042096ab113b77492c0018d5e6b47c7e4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 15 Jul 2016 16:31:21 -0700 Subject: provide examples for using access tokens in urls --- Zotlabs/Module/Settings.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 20aa59f78..ccc5ec04a 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -776,15 +776,20 @@ class Settings extends \Zotlabs\Web\Controller { $desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access the private content.'); + $desc2 = t('You may also provide dropbox style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:'); + $tpl = get_markup_template("settings_tokens.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_tokens"), '$title' => t('Guest Access Tokens'), '$desc' => $desc, + '$desc2' => $desc2, '$tokens' => $t, '$atoken' => $atoken, - '$name' => array('name', t('Login Name'), (($atoken) ? $atoken['atoken_name'] : ''),''), - '$token'=> array('token', t('Login Password'),(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''), + '$url1' => z_root() . '/channel/' . $channel['channel_address'], + '$url2' => z_root() . '/photos/' . $channel['channel_address'], + '$name' => array('name', t('Login Name') . ' *', (($atoken) ? $atoken['atoken_name'] : ''),''), + '$token'=> array('token', t('Login Password') . ' *',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''), '$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] != NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''), '$submit' => t('Submit') )); -- cgit v1.2.3 From 8e667866fd2cb834563b1eee8fadf6eedec77660 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 15 Jul 2016 21:57:41 -0700 Subject: add service class restrictions to access_tokens --- Zotlabs/Module/Settings.php | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index ccc5ec04a..b1258e049 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -132,6 +132,16 @@ class Settings extends \Zotlabs\Web\Controller { $expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']); else $expires = NULL_DATE; + $max_atokens = service_class_fetch(local_channel(),'access_tokens'); + if($max_atokens) { + $r = q("select count(atoken_id) as total where atoken_uid = %d", + intval(local_channel()) + ); + if($r && intval($r[0]['total']) >= $max_tokens) { + notice( sprintf( t('This channel is limited to %d tokens'), $max_tokens) . EOL); + return; + } + } } if($token_errs) { notice( t('Name and Password are required.') . EOL); -- cgit v1.2.3 From 2b674d4cd983d637ddc863f9b87b9d863542e250 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Sun, 17 Jul 2016 12:54:10 +0200 Subject: hide fullscreen button in embedphotos modal album view --- Zotlabs/Module/Embedphotos.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php index 2cd420664..0dac873c5 100644 --- a/Zotlabs/Module/Embedphotos.php +++ b/Zotlabs/Module/Embedphotos.php @@ -159,7 +159,7 @@ function embedphotos_widget_album($args) { '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)), '$order' => false, '$upload_form' => $upload_form, - '$usage' => $usage_message + '$no_fullscreen_btn' => true )); return $o; -- cgit v1.2.3 From dc9fa7cf64ee41e0c9457737079aee16093a4b9c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 17 Jul 2016 16:04:00 -0700 Subject: include attach.php at the module level since 2d4b75428a87038 wasn't backported to dev and we're about to branch an RC --- Zotlabs/Module/Cloud.php | 3 +++ Zotlabs/Module/Dav.php | 1 + 2 files changed, 4 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 9845c5658..68d84e070 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -13,6 +13,9 @@ use \Zotlabs\Storage; // composer autoloader for SabreDAV require_once('vendor/autoload.php'); +require_once('include/attach.php'); + + /** * @brief Fires up the SabreDAV server. * diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 9b4b576c8..ba2394388 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -14,6 +14,7 @@ use \Zotlabs\Storage; // composer autoloader for SabreDAV require_once('vendor/autoload.php'); +require_once('include/attach.php'); /** * @brief Fires up the SabreDAV server. -- cgit v1.2.3 From b5b57523f14597f13b88a93f8787bb5a4f966c58 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 18 Jul 2016 16:45:43 -0700 Subject: more perms work --- Zotlabs/Module/Import.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index e34f5e49e..d27f013b9 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -8,6 +8,7 @@ namespace Zotlabs\Module; require_once('include/zot.php'); require_once('include/channel.php'); require_once('include/import.php'); +require_once('include/perm_upgrade.php'); @@ -339,6 +340,8 @@ class Import extends \Zotlabs\Web\Controller { $abooks = $data['abook']; if($abooks) { foreach($abooks as $abook) { + + $abook_copy = $abook; $abconfig = null; if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) @@ -347,6 +350,10 @@ class Import extends \Zotlabs\Web\Controller { unset($abook['abook_id']); unset($abook['abook_rating']); unset($abook['abook_rating_text']); + unset($abook['abconfig']); + unset($abook['abook_their_perms']); + unset($abook['abook_my_perms']); + $abook['abook_account'] = $account_id; $abook['abook_channel'] = $channel['channel_id']; if(! array_key_exists('abook_blocked',$abook)) { @@ -385,6 +392,8 @@ class Import extends \Zotlabs\Web\Controller { $friends ++; if(intval($abook['abook_feed'])) $feeds ++; + + translate_abook_perms_inbound($channel,$abook_copy); if($abconfig) { // @fixme does not handle sync of del_abconfig -- cgit v1.2.3 From b63165b6e0d856848b20d184783bfdf358210f9b Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 18 Jul 2016 21:37:34 -0700 Subject: more perms work (a lot more) --- Zotlabs/Module/Connedit.php | 36 +++++++++++++++++++++--------------- Zotlabs/Module/Settings.php | 32 +++++++++++++++++--------------- 2 files changed, 38 insertions(+), 30 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 260952b4e..7f34cfc9b 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -126,9 +126,7 @@ class Connedit extends \Zotlabs\Web\Controller { $rating = 10; $rating_text = trim(escape_tags($_REQUEST['rating_text'])); - - $abook_my_perms = 0; - + $all_perms = \Zotlabs\Access\Permissions::Perms(); if($all_perms) { @@ -136,13 +134,21 @@ class Connedit extends \Zotlabs\Web\Controller { if(array_key_exists('perms_' . $perm, $_POST)) { set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm, intval($_POST['perms_' . $perm])); - $abook_my_perms ++; + if($autoperms) { + set_pconfig($channel['channel_id'],'autoperms',$perm,intval($_POST['perms_' . $perm])); + } } else { set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0); + if($autoperms) { + set_pconfig($channel['channel_id'],'autoperms',$perm,0); + } } } } + + if(! is_null($autoperms)) + set_pconfig($channel['channel_id'],'system','autoperms',$autoperms); $new_friend = false; @@ -209,14 +215,11 @@ class Connedit extends \Zotlabs\Web\Controller { } } - if($all_perms) { - foreach($all_perms as $perm => $desc) { - if(array_key_exists($perm, $abook_my_perms)) - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,1); - else - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0); - } + $filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms); + foreach($filled_perms as $k => $v) { + set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v); } + } $abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']); @@ -245,10 +248,13 @@ class Connedit extends \Zotlabs\Web\Controller { info( t('Connection updated.') . EOL); else notice( t('Failed to update connection record.') . EOL); -//@fixme perms - if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms - && (! intval(\App::$poi['abook_self']))) { - \Zotlabs\Daemon\Master::Summon(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id)); + + if(! intval(\App::$poi['abook_self'])) { + \Zotlabs\Daemon\Master::Summon( [ + 'Notifier', + (($new_friend) ? 'permission_create' : 'permission_update'), + $contact_id + ]); } if($new_friend) { diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 81d76a2dd..514078b2f 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -21,10 +21,7 @@ class Settings extends \Zotlabs\Web\Controller { // We are setting these values - don't use the argc(), argv() functions here \App::$argc = 2; \App::$argv[] = 'channel'; - } - - - + } } @@ -422,20 +419,25 @@ class Settings extends \Zotlabs\Web\Controller { ); } - foreach($global_perms as $k => $v) { - set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k,((array_key_exists($k,$role_permissions['perms_connect'])) ? 1 : 0)); - } - - set_pconfig(local_channel(),'system','autoperms',(($role_permissions['perms_auto']) ? intval($role_permissions['perms_accept']) : 0)); - - foreach($role_permissions as $p => $v) { - if(strpos($p,'channel_') !== false) { - $set_perms .= ', ' . $p . ' = ' . intval($v) . ' '; + $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']); + foreach($x as $k => $v) { + set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v); + if($role_permissions['perms_auto']) { + set_pconfig(local_channel(),'autoperms',$k,$v); + } + else { + del_pconfig(local_channel(),'autoperms',$k); } - if($p === 'directory_publish') { - $publish = intval($v); + } + + if($role_permissions['limits']) { + foreach($role_permissions['limits'] as $k => $v) { + \Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,$v); } } + if(array_key_exists('directory_publish',$role_permissions)) { + $publish = intval($role_permissions['directory_publish']); + } } set_pconfig(local_channel(),'system','hide_online_status',$hide_presence); -- cgit v1.2.3 From ea830328634b084e44f9e16f037a8bef3c98280a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 19 Jul 2016 17:52:45 -0700 Subject: translate more old perms calls --- Zotlabs/Module/Connedit.php | 4 ++-- Zotlabs/Module/Settings.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 7f34cfc9b..93ee30999 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -209,7 +209,7 @@ class Connedit extends \Zotlabs\Web\Controller { $role = get_pconfig(local_channel(),'system','permissions_role'); if($role) { - $x = get_role_perms($role); + $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if($x['perms_connect']) { $abook_my_perms = $x['perms_connect']; } @@ -395,7 +395,7 @@ class Connedit extends \Zotlabs\Web\Controller { $my_perms = get_channel_default_perms(local_channel()); $role = get_pconfig(local_channel(),'system','permissions_role'); if($role) { - $x = get_role_perms($role); + $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if($x['perms_connect']) $my_perms = $x['perms_connect']; } diff --git a/Zotlabs/Module/Settings.php b/Zotlabs/Module/Settings.php index 514078b2f..af3a25c60 100644 --- a/Zotlabs/Module/Settings.php +++ b/Zotlabs/Module/Settings.php @@ -379,7 +379,7 @@ class Settings extends \Zotlabs\Web\Controller { ); } else { - $role_permissions = get_role_perms($_POST['permissions_role']); + $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']); if(! $role_permissions) { notice('Permissions category could not be found.'); return; -- cgit v1.2.3 From a961d5e6c8cd79b375e13a0b3d887e521392f8aa Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 19 Jul 2016 20:49:54 -0700 Subject: permission fixes --- Zotlabs/Module/Item.php | 8 +++++--- Zotlabs/Module/Profiles.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 235c5528e..919ee3c4a 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -316,9 +316,11 @@ class Item extends \Zotlabs\Web\Controller { } $acl = new \Zotlabs\Access\AccessList($channel); + + $view_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'); + $comment_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'); - - $public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($channel['channel_r_stream'],true)); + $public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($view_policy,true)); if($webpage) $public_policy = ''; if($public_policy) @@ -810,7 +812,7 @@ class Item extends \Zotlabs\Web\Controller { $datarray['layout_mid'] = $layout_mid; $datarray['public_policy'] = $public_policy; - $datarray['comment_policy'] = map_scope($channel['channel_w_comment']); + $datarray['comment_policy'] = map_scope($comment_policy); $datarray['term'] = $post_tags; $datarray['plink'] = $plink; $datarray['route'] = $route; diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 899c79b15..4b05182c2 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -708,7 +708,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$profile_id' => $r[0]['id'], '$profile_name' => array('profile_name', t('Profile name'), $r[0]['profile_name'], t('Required'), '*'), '$is_default' => $is_default, - '$default' => t('This is your default profile.') . EOL . translate_scope(map_scope($channel['channel_r_profile'])), + '$default' => t('This is your default profile.') . EOL . translate_scope(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile'))), '$advanced' => $advanced, '$name' => array('name', t('Your full name'), $r[0]['fullname'], t('Required'), '*'), '$pdesc' => array('pdesc', t('Title/Description'), $r[0]['pdesc']), @@ -767,7 +767,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$alt' => t('Profile Image'), '$profile_name' => $rr['profile_name'], '$visible' => (($rr['is_default']) - ? '' . translate_scope(map_scope($channel['channel_r_profile'])) . '' + ? '' . translate_scope(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile'))) . '' : '' . t('Edit visibility') . '') )); } -- cgit v1.2.3 From a3e5307b93ea524781abd885e26a5d6c8f5c4c54 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 19 Jul 2016 22:57:23 -0700 Subject: fix the forum detection in include/zot --- Zotlabs/Module/Item.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 919ee3c4a..f0cb82286 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -528,11 +528,11 @@ class Item extends \Zotlabs\Web\Controller { if((! $parent) && (get_pconfig($profile_uid,'system','tagifonlyrecip')) && (substr_count($str_contact_allow,'<') == 1) && ($str_group_allow == '') && ($str_contact_deny == '') && ($str_group_deny == '')) { - $x = q("select abook_id, abook_their_perms from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + $x = q("select abook_id, abconfig.v from abook left join abconfig on abook_xchan = abconfig.xchan and abook_channel = abconfig.chan and cat= 'their_perms' and abconfig.k = 'tag_deliver' and abconfig.v = 1 and abook_xchan = '%s' and abook_channel = %d limit 1", dbesc(str_replace(array('<','>'),array('',''),$str_contact_allow)), intval($profile_uid) ); - if($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL)) + if($x) $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; } -- cgit v1.2.3 From 4da005e209624b43610aeefe30d7a9f9fe0ac7c0 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 20 Jul 2016 22:00:41 +0200 Subject: type m query in Acl.php should probably^Ceturn xchan_hash as hash and not as id. This fixes the issue that autocomplete for mail returns null for data.xid --- Zotlabs/Module/Acl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 15609c3c8..76a001fdd 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -222,7 +222,7 @@ class Acl extends \Zotlabs\Web\Controller { } elseif($type == 'm') { - $r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url + $r = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0) and xchan_deleted = 0 -- cgit v1.2.3 From 3affb2e8172b4cc673aafe9551c21dad6f606d87 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 20 Jul 2016 17:55:40 -0700 Subject: sort out some of the authentication mess - with luck this may fix the DAV auth issue which I simply could not duplicate or find a reason for. --- Zotlabs/Module/Dav.php | 85 ++-------------------------------------- Zotlabs/Module/Login.php | 3 ++ Zotlabs/Module/Openid.php | 2 +- Zotlabs/Module/Register.php | 2 +- Zotlabs/Module/Removeaccount.php | 3 +- Zotlabs/Module/Removeme.php | 4 +- 6 files changed, 14 insertions(+), 85 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index ba2394388..aaf69844c 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -48,55 +48,13 @@ class Dav extends \Zotlabs\Web\Controller { if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); - $which = null; if (argc() > 1) - $which = argv(1); + profile_load(argv(1),0); - $profile = 0; - - \App::$page['htmlhead'] .= '' . "\r\n"; - - if ($which) - profile_load( $which, $profile); - - - $auth = new \Zotlabs\Storage\BasicAuth(); - $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV'); - -// $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) { -// if(account_verify_password($userName,$password)) -// return true; -// return false; -// }); + $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . ' ' . 'WebDAV'); -// $ob_hash = get_observer_hash(); - -// if ($ob_hash) { -// if (local_channel()) { -// $channel = \App::get_channel(); -// $auth->setCurrentUser($channel['channel_address']); -// $auth->channel_id = $channel['channel_id']; -// $auth->channel_hash = $channel['channel_hash']; -// $auth->channel_account_id = $channel['channel_account_id']; -// if($channel['channel_timezone']) -// $auth->setTimezone($channel['channel_timezone']); -// } -// $auth->observer = $ob_hash; -// } - -// if ($_GET['davguest']) -// $_SESSION['davguest'] = true; - -// $_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); // A SabreDAV server-object @@ -113,48 +71,13 @@ class Dav extends \Zotlabs\Web\Controller { $server->addPlugin($lockPlugin); - // The next section of code allows us to bypass prompting for http-auth if a - // FILE is being accessed anonymously and permissions allow this. This way - // one can create hotlinks to public media files in their cloud and anonymous - // viewers won't get asked to login. - // If a DIRECTORY is accessed or there are permission issues accessing the - // file and we aren't previously authenticated via zot, prompt for HTTP-auth. - // This will be the default case for mounting a DAV directory. - // In order to avoid prompting for passwords for viewing a DIRECTORY, add - // the URL query parameter 'davguest=1'. - -// $isapublic_file = false; -// $davguest = ((x($_SESSION, 'davguest')) ? true : false); - -// if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) { -// try { -// $x = RedFileData('/' . \App::$cmd, $auth); -// if($x instanceof \Zotlabs\Storage\File) -// $isapublic_file = true; -// } -// catch (Exception $e) { -// $isapublic_file = false; -// } -// } - -// if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) { -// try { -// $auth->Authenticate($server, t('$Projectname channel')); -// } -// catch (Exception $e) { -// logger('mod_cloud: auth exception' . $e->getMessage()); -// http_status_exit($e->getHTTPCode(), $e->getMessage()); -// } -// } - - // require_once('Zotlabs/Storage/Browser.php'); // provide a directory view for the cloud in Hubzilla $browser = new \Zotlabs\Storage\Browser($auth); $auth->setBrowserPlugin($browser); // Experimental QuotaPlugin - // require_once('Zotlabs/Storage/QuotaPlugin.php'); - // $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth)); + // require_once('Zotlabs/Storage/QuotaPlugin.php'); + // $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth)); // All we need to do now, is to fire up the server $server->exec(); diff --git a/Zotlabs/Module/Login.php b/Zotlabs/Module/Login.php index ff75e5268..ae35b922f 100644 --- a/Zotlabs/Module/Login.php +++ b/Zotlabs/Module/Login.php @@ -7,6 +7,9 @@ class Login extends \Zotlabs\Web\Controller { function get() { if(local_channel()) goaway(z_root()); + if(remote_channel() && $_SESSION['atoken']) + goaway(z_root()); + return login((\App::$config['system']['register_policy'] == REGISTER_CLOSED) ? false : true); } diff --git a/Zotlabs/Module/Openid.php b/Zotlabs/Module/Openid.php index 7a6e4a81f..8cbc6d2fd 100644 --- a/Zotlabs/Module/Openid.php +++ b/Zotlabs/Module/Openid.php @@ -48,7 +48,7 @@ class Openid extends \Zotlabs\Web\Controller { $_SESSION['uid'] = $r[0]['channel_id']; $_SESSION['account_id'] = $r[0]['channel_account_id']; $_SESSION['authenticated'] = true; - authenticate_success($record,true,true,true,true); + authenticate_success($record,$r[0],true,true,true,true); goaway(z_root()); } } diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php index 6afa4a94c..45123b88d 100644 --- a/Zotlabs/Module/Register.php +++ b/Zotlabs/Module/Register.php @@ -146,7 +146,7 @@ class Register extends \Zotlabs\Web\Controller { goaway(z_root()); } - authenticate_success($result['account'],true,false,true); + authenticate_success($result['account'],null,true,false,true); $new_channel = false; $next_page = 'new_channel'; diff --git a/Zotlabs/Module/Removeaccount.php b/Zotlabs/Module/Removeaccount.php index 39e06bb7f..9fac7838e 100644 --- a/Zotlabs/Module/Removeaccount.php +++ b/Zotlabs/Module/Removeaccount.php @@ -25,7 +25,8 @@ class Removeaccount extends \Zotlabs\Web\Controller { $account = \App::get_account(); $account_id = get_account_id(); - if(! account_verify_password($account['account_email'],$_POST['qxz_password'])) + $x = account_verify_password($account['account_email'],$_POST['qxz_password']); + if(! ($x && $x['account'])) return; if($account['account_password_changed'] != NULL_DATE) { diff --git a/Zotlabs/Module/Removeme.php b/Zotlabs/Module/Removeme.php index e611d8112..bc18fe0f8 100644 --- a/Zotlabs/Module/Removeme.php +++ b/Zotlabs/Module/Removeme.php @@ -24,7 +24,9 @@ class Removeme extends \Zotlabs\Web\Controller { $account = \App::get_account(); - if(! account_verify_password($account['account_email'],$_POST['qxz_password'])) + + $x = account_verify_password($account['account_email'],$_POST['qxz_password']); + if(! ($x && $x['account'])) return; if($account['account_password_changed'] != NULL_DATE) { -- cgit v1.2.3 From da707736a075e8f050458316edfcf0177aef0bfc Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 20 Jul 2016 23:04:07 -0700 Subject: issue #453 and a bug noted from the logfiles related to the schema change last month --- Zotlabs/Module/Item.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index f0cb82286..2d0c1ba02 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -183,7 +183,9 @@ class Item extends \Zotlabs\Web\Controller { } // can_comment_on_post() needs info from the following xchan_query - xchan_query($r); + // This may be from the discover tab which means we need to correct the effective uid + + xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel())); $parent_item = $r[0]; $parent = $r[0]['id']; -- cgit v1.2.3 From 7d897a3f03bd57ed556433eb84a41963ba44e02e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 21 Jul 2016 23:06:55 -0700 Subject: more work on #453 --- Zotlabs/Module/Like.php | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 1ca37d646..170349509 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -264,23 +264,22 @@ class Like extends \Zotlabs\Web\Controller { logger('like: no item ' . $item_id); killme(); } - - + + + xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel())); + $item = $r[0]; - $owner_uid = $item['uid']; - $owner_aid = $item['aid']; - - - $sys = get_sys_channel(); - - - // if this is a "discover" item, (item['uid'] is the sys channel), - // fallback to the item comment policy, which should've been - // respected when generating the conversation thread. - // Even if the activity is rejected by the item owner, it should still get attached - // to the local discover conversation on this site. - - if(($owner_uid != $sys['channel_id']) && (! perm_is_allowed($owner_uid,$observer['xchan_hash'],'post_comments'))) { + + $owner_uid = $r[0]['uid']; + $owner_aid = $r[0]['aid']; + + $can_comment = false; + if((array_key_exists('owner',$item)) && intval($item['owner']['abook_self'])) + $can_comment = perm_is_allowed($item['uid'],$observer['xchan_hash'],'post_comments'); + else + $can_comment = can_comment_on_post($observer['xchan_hash'],$item); + + if(! $can_comment) { notice( t('Permission denied') . EOL); killme(); } -- cgit v1.2.3