public function replace_macros($s, $r) { $template = ''; // these are available for use in all templates $r['$z_baseurl'] = z_root(); $r['$z_server_role'] = \Zotlabs\Lib\System::get_server_role(); $r['$z_techlevel'] = get_account_techlevel(); if (gettype($s) === 'string') { $template = $s; $s = new SmartyInterface(); } foreach ($r as $key => $value) { if ($key[0] === '$') { $key = substr($key, 1); } $s->assign($key, $value); } return $s->parsed($template); }
function get_features($filtered = true) { $server_role = \Zotlabs\Lib\System::get_server_role(); if ($server_role === 'basic' && $filtered) { return array(); } $arr = ['general' => [t('General Features'), ['multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, get_config('feature_lock', 'multi_profiles'), feature_level('multi_profiles', 3)], ['advanced_profiles', t('Advanced Profiles'), t('Additional profile sections and selections'), false, get_config('feature_lock', 'advanced_profiles'), feature_level('advanced_profiles', 1)], ['profile_export', t('Profile Import/Export'), t('Save and load profile details across sites/channels'), false, get_config('feature_lock', 'profile_export'), feature_level('profile_export', 3)], ['webpages', t('Web Pages'), t('Provide managed web pages on your channel'), false, get_config('feature_lock', 'webpages'), feature_level('webpages', 3)], ['wiki', t('Wiki'), t('Provide a wiki for your channel'), false, get_config('feature_lock', 'wiki'), feature_level('wiki', 2)], ['private_notes', t('Private Notes'), t('Enables a tool to store notes and reminders (note: not encrypted)'), false, get_config('feature_lock', 'private_notes'), feature_level('private_notes', 1)], ['nav_channel_select', t('Navigation Channel Select'), t('Change channels directly from within the navigation dropdown menu'), false, get_config('feature_lock', 'nav_channel_select'), feature_level('nav_channel_select', 3)], ['photo_location', t('Photo Location'), t('If location data is available on uploaded photos, link this to a map.'), false, get_config('feature_lock', 'photo_location'), feature_level('photo_location', 2)], ['ajaxchat', t('Access Controlled Chatrooms'), t('Provide chatrooms and chat services with access control.'), true, get_config('feature_lock', 'ajaxchat'), feature_level('ajaxchat', 1)], ['smart_birthdays', t('Smart Birthdays'), t('Make birthday events timezone aware in case your friends are scattered across the planet.'), true, get_config('feature_lock', 'smart_birthdays'), feature_level('smart_birthdays', 2)], ['advanced_dirsearch', t('Advanced Directory Search'), t('Allows creation of complex directory search queries'), false, get_config('feature_lock', 'advanced_dirsearch'), feature_level('advanced_dirsearch', 4)], ['advanced_theming', t('Advanced Theme and Layout Settings'), t('Allows fine tuning of themes and page layouts'), false, get_config('feature_lock', 'advanced_theming'), feature_level('advanced_theming', 4)]], 'composition' => [t('Post Composition Features'), ['large_photos', t('Large Photos'), t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'), false, get_config('feature_lock', 'large_photos'), feature_level('large_photos', 1)], ['channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'), false, get_config('feature_lock', 'channel_sources'), feature_level('channel_sources', 3)], ['content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'), false, get_config('feature_lock', 'content_encrypt'), feature_level('content_encrypt', 3)], ['consensus_tools', t('Enable Voting Tools'), t('Provide a class of post which others can vote on'), false, get_config('feature_lock', 'consensus_tools'), feature_level('consensus_tools', 3)], ['disable_comments', t('Disable Comments'), t('Provide the option to disable comments for a post'), false, get_config('feature_lock', 'disable_comments'), feature_level('disable_comments', 2)], ['delayed_posting', t('Delayed Posting'), t('Allow posts to be published at a later date'), false, get_config('feature_lock', 'delayed_posting'), feature_level('delayed_posting', 2)], ['content_expire', t('Content Expiration'), t('Remove posts/comments and/or private messages at a future time'), false, get_config('feature_lock', 'content_expire'), feature_level('content_expire', 1)], ['suppress_duplicates', t('Suppress Duplicate Posts/Comments'), t('Prevent posts with identical content to be published with less than two minutes in between submissions.'), true, get_config('feature_lock', 'suppress_duplicates'), feature_level('suppress_duplicates', 1)]], 'net_module' => [t('Network and Stream Filtering'), ['archives', t('Search by Date'), t('Ability to select posts by date ranges'), false, get_config('feature_lock', 'archives'), feature_level('archives', 1)], ['groups', t('Privacy Groups'), t('Enable management and selection of privacy groups'), true, get_config('feature_lock', 'groups'), feature_level('groups', 0)], ['savedsearch', t('Saved Searches'), t('Save search terms for re-use'), false, get_config('feature_lock', 'savedsearch'), feature_level('savedsearch', 2)], ['personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'), false, get_config('feature_lock', 'personal_tab'), feature_level('personal_tab', 1)], ['new_tab', t('Network New Tab'), t('Enable tab to display all new Network activity'), false, get_config('feature_lock', 'new_tab'), feature_level('new_tab', 2)], ['affinity', t('Affinity Tool'), t('Filter stream activity by depth of relationships'), false, get_config('feature_lock', 'affinity'), feature_level('affinity', 1)], ['suggest', t('Suggest Channels'), t('Show friend and connection suggestions'), false, get_config('feature_lock', 'suggest'), feature_level('suggest', 1)], ['connfilter', t('Connection Filtering'), t('Filter incoming posts from connections based on keywords/content'), false, get_config('feature_lock', 'connfilter'), feature_level('connfilter', 3)]], 'tools' => [t('Post/Comment Tools'), ['commtag', t('Community Tagging'), t('Ability to tag existing posts'), false, get_config('feature_lock', 'commtag'), feature_level('commtag', 1)], ['categories', t('Post Categories'), t('Add categories to your posts'), false, get_config('feature_lock', 'categories'), feature_level('categories', 1)], ['emojis', t('Emoji Reactions'), t('Add emoji reaction ability to posts'), true, get_config('feature_lock', 'emojis'), feature_level('emojis', 1)], ['filing', t('Saved Folders'), t('Ability to file posts under folders'), false, get_config('feature_lock', 'filing'), feature_level('filing', 2)], ['dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'), false, get_config('feature_lock', 'dislike'), feature_level('dislike', 1)], ['star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'), false, get_config('feature_lock', 'star_posts'), feature_level('star_posts', 1)], ['tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your channel page'), false, get_config('feature_lock', 'tagadelic'), feature_level('tagadelic', 2)]]]; if ($server_role === 'pro') { $arr['general'][] = ['premium_channel', t('Premium Channel'), t('Allows you to set restrictions and terms on those that connect with your channel'), false, get_config('feature_lock', 'premium_channel'), feature_level('premium_channel', 4)]; } $techlevel = get_account_techlevel(); // removed any locked features and remove the entire category if this makes it empty if ($filtered) { $narr = []; foreach ($arr as $k => $x) { $narr[$k] = [$arr[$k][0]]; $has_items = false; for ($y = 0; $y < count($arr[$k]); $y++) { $disabled = false; if (is_array($arr[$k][$y])) { if ($arr[$k][$y][5] > $techlevel) { $disabled = true; } if ($arr[$k][$y][4] !== false) { $disabled = true; } if (!$disabled) { $has_items = true; $narr[$k][$y] = $arr[$k][$y]; } } } if (!$has_items) { unset($narr[$k]); } } } else { $narr = $arr; } call_hooks('get_features', $narr); return $narr; }
function get() { require_once 'include/acl_selectors.php'; require_once 'include/permissions.php'; $yes_no = array(t('No'), t('Yes')); $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 = \Zotlabs\Access\Permissions::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)); $limits = \Zotlabs\Access\PermissionLimits::Get(local_channel()); foreach ($global_perms as $k => $perm) { $options = array(); foreach ($perm_opts as $opt) { if (!strstr($k, 'view') && $opt[1] == PERMS_PUBLIC) { continue; } $options[$opt[1]] = $opt[0]; } $permiss[] = array($k, $perm, $limits[$k], '', $options); } $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 = '<input type="hidden" name="profile_in_directory" value="1" />'; } 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()) ? '<br />' . 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; $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); if (get_account_techlevel() < 4 && $permissions_role !== 'custom') { unset($perm_roles[t('Other')]); } $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\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), '$lbl_pmacro' => t('Simple Privacy Settings:'), '$pmacro3' => t('Very Public - <em>extremely permissive (should be used with caution)</em>'), '$pmacro2' => t('Typical - <em>default public, privacy when desired (similar to social network permissions but with improved privacy)</em>'), '$pmacro1' => t('Private - <em>default private, never open or public</em>'), '$pmacro0' => t('Blocked - <em>default blocked to/from everybody</em>'), '$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('Channel Permission Limits'), '$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 Access Control List (ACL)'), '$permdesc' => t("(click to open/close)"), '$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), '$allow_cid' => acl2json($perm_defaults['allow_cid']), '$allow_gid' => acl2json($perm_defaults['allow_gid']), '$deny_cid' => acl2json($perm_defaults['deny_cid']), '$deny_gid' => acl2json($perm_defaults['deny_gid']), '$suggestme' => $suggestme, '$group_select' => $group_select, '$role' => array('permissions_role', t('Channel permissions category:'), $permissions_role, '', $perm_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 <em>interesting</em> 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, '$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 .= '</form>' . "\r\n"; return $o; }
/** * Get data in a form usable by a conversation template * * Returns: * _ The data requested on success * _ false on failure */ public function get_template_data($conv_responses, $thread_level = 1) { $result = array(); $item = $this->get_data(); $commentww = ''; $sparkle = ''; $buttons = ''; $dropping = false; $star = false; $isstarred = "unstarred fa-star-o"; $indent = ''; $osparkle = ''; $total_children = $this->count_descendants(); $unseen_comments = $item['real_uid'] ? 0 : $this->count_unseen_descendants(); $conv = $this->get_conversation(); $observer = $conv->get_observer(); $lock = $item['item_private'] == 1 || $item['uid'] == local_channel() && (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) ? t('Private Message') : false; $shareable = $conv->get_profile_owner() == local_channel() && local_channel() && $item['item_private'] != 1 ? true : false; // allow an exemption for sharing stuff from your private feeds if ($item['author']['xchan_network'] === 'rss') { $shareable = true; } $mode = $conv->get_mode(); if (local_channel() && $observer['xchan_hash'] === $item['author_xchan']) { $edpost = array(z_root() . "/editpost/" . $item['id'], t("Edit")); } else { $edpost = false; } if ($observer['xchan_hash'] == $this->get_data_value('author_xchan') || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') || $this->get_data_value('uid') == local_channel()) { $dropping = true; } if (array_key_exists('real_uid', $item)) { $edpost = false; $dropping = false; } if ($dropping) { $drop = array('dropping' => $dropping, 'delete' => t('Delete')); } // FIXME if ($observer_is_pageowner) { $multidrop = array('select' => t('Select')); } $filer = $conv->get_profile_owner() == local_channel() && !array_key_exists('real_uid', $item) ? t("Save to Folder") : false; $profile_avatar = $item['author']['xchan_photo_m']; $profile_link = chanlink_url($item['author']['xchan_url']); $profile_name = $item['author']['xchan_name']; $location = format_location($item); $isevent = false; $attend = null; $canvote = false; // process action responses - e.g. like/dislike/attend/agree/whatever $response_verbs = array('like'); if (feature_enabled($conv->get_profile_owner(), 'dislike')) { $response_verbs[] = 'dislike'; } if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) { $response_verbs[] = 'attendyes'; $response_verbs[] = 'attendno'; $response_verbs[] = 'attendmaybe'; if ($this->is_commentable()) { $isevent = true; $attend = array(t('I will attend'), t('I will not attend'), t('I might attend')); } } $consensus = intval($item['item_consensus']) ? true : false; if ($consensus) { $response_verbs[] = 'agree'; $response_verbs[] = 'disagree'; $response_verbs[] = 'abstain'; if ($this->is_commentable()) { $conlabels = array(t('I agree'), t('I disagree'), t('I abstain')); $canvote = true; } } if (!feature_enabled($conv->get_profile_owner(), 'dislike')) { unset($conv_responses['dislike']); } $responses = get_responses($conv_responses, $response_verbs, $this, $item); $my_responses = []; foreach ($response_verbs as $v) { $my_responses[$v] = $conv_responses[$v][$item['mid'] . '-m'] ? 1 : 0; } $like_count = x($conv_responses['like'], $item['mid']) ? $conv_responses['like'][$item['mid']] : ''; $like_list = x($conv_responses['like'], $item['mid']) ? $conv_responses['like'][$item['mid'] . '-l'] : ''; if (count($like_list) > MAX_LIKERS) { $like_list_part = array_slice($like_list, 0, MAX_LIKERS); array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); } else { $like_list_part = ''; } $like_button_label = tt('Like', 'Likes', $like_count, 'noun'); if (feature_enabled($conv->get_profile_owner(), 'dislike')) { $dislike_count = x($conv_responses['dislike'], $item['mid']) ? $conv_responses['dislike'][$item['mid']] : ''; $dislike_list = x($conv_responses['dislike'], $item['mid']) ? $conv_responses['dislike'][$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, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); } else { $dislike_list_part = ''; } } $showlike = x($conv_responses['like'], $item['mid']) ? format_like($conv_responses['like'][$item['mid']], $conv_responses['like'][$item['mid'] . '-l'], 'like', $item['mid']) : ''; $showdislike = x($conv_responses['dislike'], $item['mid']) && feature_enabled($conv->get_profile_owner(), 'dislike') ? format_like($conv_responses['dislike'][$item['mid']], $conv_responses['dislike'][$item['mid'] . '-l'], 'dislike', $item['mid']) : ''; /* * We should avoid doing this all the time, but it depends on the conversation mode * And the conv mode may change when we change the conv, or it changes its mode * Maybe we should establish a way to be notified about conversation changes */ $this->check_wall_to_wall(); if ($this->is_toplevel()) { // FIXME check this permission if ($conv->get_profile_owner() == local_channel() && !array_key_exists('real_uid', $item)) { // FIXME we don't need all this stuff, some can be done in the template $star = array('do' => t("Add Star"), 'undo' => t("Remove Star"), 'toggle' => t("Toggle Star Status"), 'classdo' => intval($item['item_starred']) ? "hidden" : "", 'classundo' => intval($item['item_starred']) ? "" : "hidden", 'isstarred' => intval($item['item_starred']) ? "starred fa-star" : "unstarred fa-star-o", 'starred' => t('starred')); } } else { $indent = 'comment'; } $verified = intval($item['item_verified']) ? t('Message signature validated') : ''; $forged = $item['sig'] && !intval($item['item_verified']) ? t('Message signature incorrect') : ''; $unverified = ''; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : ''); // FIXME - check this permission if ($conv->get_profile_owner() == local_channel()) { $tagger = array('tagit' => t("Add Tag"), 'classtagger' => ""); } $server_role = get_config('system', 'server_role'); $has_bookmarks = false; if (is_array($item['term'])) { foreach ($item['term'] as $t) { if (get_account_techlevel() > 0 && $t['ttype'] == TERM_BOOKMARK) { $has_bookmarks = true; } } } $has_event = false; if ($item['obj_type'] === ACTIVITY_OBJ_EVENT && $conv->get_profile_owner() == local_channel()) { $has_event = true; } if ($this->is_commentable()) { $like = array(t("I like this (toggle)"), t("like")); $dislike = array(t("I don't like this (toggle)"), t("dislike")); } if ($shareable) { $share = array(t('Share This'), t('share')); } $dreport = ''; $keep_reports = intval(get_config('system', 'expire_delivery_reports')); if ($keep_reports === 0) { $keep_reports = 30; } if (!get_config('system', 'disable_dreport') && strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', "now - {$keep_reports} days")) > 0) { $dreport = t('Delivery Report'); } if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) { $indent .= ' shiny'; } localize_item($item); $body = prepare_body($item, true); // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link // since we can't depend on llink or plink pointing to the right local location. $owner_address = substr($item['owner']['xchan_addr'], 0, strpos($item['owner']['xchan_addr'], '@')); $viewthread = $item['llink']; if ($conv->get_mode() === 'channel') { $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid']; } $comment_count_txt = sprintf(tt('%d comment', '%d comments', $total_children), $total_children); $list_unseen_txt = $unseen_comments ? sprintf('%d unseen', $unseen_comments) : ''; $children = $this->get_children(); $has_tags = $body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders'] ? true : false; $tmp_item = array('template' => $this->get_template(), 'mode' => $mode, 'type' => implode("", array_slice(explode("/", $item['verb']), -1)), 'body' => $body['html'], 'tags' => $body['tags'], 'categories' => $body['categories'], 'mentions' => $body['mentions'], 'attachments' => $body['attachments'], 'folders' => $body['folders'], 'text' => strip_tags($body['html']), 'id' => $this->get_id(), 'mid' => $item['mid'], 'isevent' => $isevent, 'attend' => $attend, 'consensus' => $consensus, 'conlabels' => $conlabels, 'canvote' => $canvote, 'linktitle' => sprintf(t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']), 'olinktitle' => sprintf(t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']), 'llink' => $item['llink'], 'viewthread' => $viewthread, 'to' => t('to'), 'via' => t('via'), 'wall' => t('Wall-to-Wall'), 'vwall' => t('via Wall-To-Wall:'), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'dreport' => $dreport, 'name' => $profile_name, 'thumb' => $profile_avatar, 'osparkle' => $osparkle, 'sparkle' => $sparkle, 'title' => $item['title'], 'title_tosource' => get_pconfig($conv->get_profile_owner(), 'system', 'title_tosource'), 'ago' => relative_date($item['created']), 'app' => $item['app'], 'str_app' => sprintf(t('from %s'), $item['app']), 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), 'editedtime' => $item['edited'] != $item['created'] ? sprintf(t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : '', 'expiretime' => $item['expires'] > NULL_DATE ? sprintf(t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')) : '', 'lock' => $lock, 'verified' => $verified, 'unverified' => $unverified, 'forged' => $forged, 'location' => $location, 'indent' => $indent, 'owner_url' => $this->get_owner_url(), 'owner_photo' => $this->get_owner_photo(), 'owner_name' => $this->get_owner_name(), 'photo' => $body['photo'], 'event' => $body['event'], 'has_tags' => $has_tags, 'reactions' => $this->reactions, 'emojis' => $this->is_toplevel() && $this->is_commentable() && feature_enabled($conv->get_profile_owner(), 'emojis') ? '1' : '', 'like' => $like, 'dislike' => feature_enabled($conv->get_profile_owner(), 'dislike') ? $dislike : '', 'share' => $share, 'rawmid' => $item['mid'], 'plink' => get_plink($item), 'edpost' => $edpost, 'star' => feature_enabled($conv->get_profile_owner(), 'star_posts') ? $star : '', 'tagger' => feature_enabled($conv->get_profile_owner(), 'commtag') ? $tagger : '', 'filer' => feature_enabled($conv->get_profile_owner(), 'filing') ? $filer : '', 'bookmark' => $conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks ? t('Save Bookmarks') : '', 'addtocal' => $has_event ? t('Add to Calendar') : '', 'drop' => $drop, 'multidrop' => feature_enabled($conv->get_profile_owner(), 'multi_delete') ? $multidrop : '', 'unseen_comments' => $unseen_comments, 'comment_count' => $total_children, 'comment_count_txt' => $comment_count_txt, 'list_unseen_txt' => $list_unseen_txt, 'markseen' => t('Mark all seen'), 'responses' => $responses, 'my_responses' => $my_responses, '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' => feature_enabled($conv->get_profile_owner(), 'dislike') ? $dislike_count : '', 'dislike_list' => feature_enabled($conv->get_profile_owner(), 'dislike') ? $dislike_list : '', 'dislike_list_part' => feature_enabled($conv->get_profile_owner(), 'dislike') ? $dislike_list_part : '', 'dislike_button_label' => feature_enabled($conv->get_profile_owner(), 'dislike') ? $dislike_button_label : '', 'modal_dismiss' => t('Close'), 'showlike' => $showlike, 'showdislike' => $showdislike, 'comment' => $this->get_comment_box($indent), 'previewing' => $conv->is_preview() ? ' preview ' : '', 'wait' => t('Please wait'), 'submid' => substr($item['mid'], 0, 32), 'thread_level' => $thread_level); $arr = array('item' => $item, 'output' => $tmp_item); call_hooks('display_item', $arr); $result = $arr['output']; $result['children'] = array(); $nb_children = count($children); $visible_comments = get_config('system', 'expanded_comments'); if ($visible_comments === false) { $visible_comments = 3; } // needed for scroll to comment from notification but needs more work // as we do not want to open all comments unless there is actually an #item_xx anchor // and the url fragment is not sent to the server. // if(in_array(\App::$module,['display','update_display'])) // $visible_comments = 99999; if ($this->get_display_mode() === 'normal' && $nb_children > 0) { foreach ($children as $child) { $result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1); } // Collapse if ($nb_children > $visible_comments || $thread_level > 1) { $result['children'][0]['comment_firstcollapsed'] = true; $result['children'][0]['num_comments'] = $comment_count_txt; $result['children'][0]['hide_text'] = sprintf(t('%s show all'), '<i class="fa fa-chevron-down"></i>'); if ($thread_level > 1) { $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true; } else { $result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true; } } } $result['private'] = $item['item_private']; $result['toplevel'] = $this->is_toplevel() ? 'toplevel_item' : ''; if ($this->is_threaded()) { $result['flatten'] = false; $result['threaded'] = true; } else { $result['flatten'] = true; $result['threaded'] = false; } return $result; }
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 = ''; } } $privacy_role = x($_REQUEST, 'permissions_role') ? $_REQUEST['permissions_role'] : ""; $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); if (get_account_techlevel() < 4 && $privacy_role !== 'custom') { unset($perm_roles[t('Other')]); } $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), "*"); $role = array('permissions_role', t('Channel role and privacy'), $privacy_role ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>', $perm_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 <a href="import">import an existing channel</a> from another location.'), '$name' => $name, '$role' => $role, '$default_role' => $default_role, '$nickname' => $nickname, '$submit' => t('Create'), '$channel_usage_message' => $channel_usage_message)); return $o; }
function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) { call_hooks('bbcode_filter', $Text); // Hide all [noparse] contained bbtags by spacefying them if (strpos($Text, '[noparse]') !== false) { $Text = preg_replace_callback("/\\[noparse\\](.*?)\\[\\/noparse\\]/ism", 'bb_spacefy', $Text); } if (strpos($Text, '[nobb]') !== false) { $Text = preg_replace_callback("/\\[nobb\\](.*?)\\[\\/nobb\\]/ism", 'bb_spacefy', $Text); } if (strpos($Text, '[pre]') !== false) { $Text = preg_replace_callback("/\\[pre\\](.*?)\\[\\/pre\\]/ism", 'bb_spacefy', $Text); } // If we find any event code, turn it into an event. // After we're finished processing the bbcode we'll // replace all of the event code with a reformatted version. $ev = bbtoevent($Text); // process [observer] tags before we do anything else because we might // be stripping away stuff that then doesn't need to be worked on anymore if ($cache) { $observer = false; } else { $observer = App::get_observer(); } if (strpos($Text, '[/observer]') !== false || strpos($Text, '[/rpost]') !== false) { if ($observer) { $Text = preg_replace("/\\[observer\\=1\\](.*?)\\[\\/observer\\]/ism", '$1', $Text); $Text = preg_replace("/\\[observer\\=0\\].*?\\[\\/observer\\]/ism", '', $Text); $Text = preg_replace_callback("/\\[rpost(=(.*?))?\\](.*?)\\[\\/rpost\\]/ism", 'rpost_callback', $Text); } else { $Text = preg_replace("/\\[observer\\=1\\].*?\\[\\/observer\\]/ism", '', $Text); $Text = preg_replace("/\\[observer\\=0\\](.*?)\\[\\/observer\\]/ism", '$1', $Text); $Text = preg_replace("/\\[rpost(=.*?)?\\](.*?)\\[\\/rpost\\]/ism", '', $Text); } } if ($cache) { $channel = false; } else { $channel = App::get_channel(); } if (strpos($Text, '[/channel]') !== false) { if ($channel) { $Text = preg_replace("/\\[channel\\=1\\](.*?)\\[\\/channel\\]/ism", '$1', $Text); $Text = preg_replace("/\\[channel\\=0\\].*?\\[\\/channel\\]/ism", '', $Text); } else { $Text = preg_replace("/\\[channel\\=1\\].*?\\[\\/channel\\]/ism", '', $Text); $Text = preg_replace("/\\[channel\\=0\\](.*?)\\[\\/channel\\]/ism", '$1', $Text); } } $x = bb_extract_images($Text); $Text = $x['body']; $saved_images = $x['images']; $Text = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $Text); // Replace any html brackets with HTML Entities to prevent executing HTML or script // Don't use strip_tags here because it breaks [url] search by replacing & with amp $Text = str_replace("<", "<", $Text); $Text = str_replace(">", ">", $Text); // Check for [code] text here, before the linefeeds are messed with. // The highlighter will unescape and re-escape the content. if (strpos($Text, '[code=') !== false) { $Text = preg_replace_callback("/\\[code=(.*?)\\](.*?)\\[\\/code\\]/ism", 'bb_highlight', $Text); } $Text = preg_replace_callback("/\\[table\\](.*?)\\[\\/table\\]/ism", 'bb_fixtable_lf', $Text); // Convert new line chars to html <br /> tags // nlbr seems to be hopelessly messed up // $Text = nl2br($Text); // We'll emulate it. $Text = str_replace("\r\n", "\n", $Text); $Text = str_replace(array("\r", "\n"), array('<br />', '<br />'), $Text); if ($preserve_nl) { $Text = str_replace(array("\n", "\r"), array('', ''), $Text); } $Text = str_replace(array("\t", " "), array(" ", " "), $Text); // Set up the parameters for a URL search string $URLSearchString = "^\\[\\]"; // Set up the parameters for a MAIL search string $MAILSearchString = $URLSearchString; // replace [observer.baseurl] if ($observer) { $s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">'; $s2 = '</span>'; $obsBaseURL = $observer['xchan_connurl']; $obsBaseURL = preg_replace("/\\/poco\\/.*\$/", '', $obsBaseURL); $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); $Text = str_replace('[observer.url]', $observer['xchan_url'], $Text); $Text = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $Text); $Text = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $Text); $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $Text); $Text = str_replace('[observer.photo]', $s1 . '[zmg]' . $observer['xchan_photo_l'] . '[/zmg]' . $s2, $Text); } else { $Text = str_replace('[observer.baseurl]', '', $Text); $Text = str_replace('[observer.url]', '', $Text); $Text = str_replace('[observer.name]', '', $Text); $Text = str_replace('[observer.address]', '', $Text); $Text = str_replace('[observer.webname]', '', $Text); $Text = str_replace('[observer.photo]', '', $Text); } // Perform URL Search $urlchars = '[a-zA-Z0-9\\:\\/\\-\\?\\&\\;\\.\\=\\@\\_\\~\\#\\%\\$\\!\\+\\,\\@]'; if (strpos($Text, 'http') !== false) { if ($tryoembed) { $Text = preg_replace_callback("/([^\\]\\='" . '"' . "\\/]|^|\\#\\^)(https?\\:\\/\\/{$urlchars}+)/ism", 'tryoembed', $Text); } $Text = preg_replace("/([^\\]\\='" . '"' . "\\/]|^|\\#\\^)(https?\\:\\/\\/{$urlchars}+)/ism", '$1<a href="$2" target="_blank" >$2</a>', $Text); } if (strpos($Text, '[/share]') !== false) { $Text = preg_replace_callback("/\\[share(.*?)\\](.*?)\\[\\/share\\]/ism", 'bb_ShareAttributes', $Text); } if ($tryoembed) { if (strpos($Text, '[/url]') !== false) { $Text = preg_replace_callback("/[^\\^]\\[url\\]([{$URLSearchString}]*)\\[\\/url\\]/ism", 'tryoembed', $Text); } } if (strpos($Text, '[/url]') !== false) { $Text = preg_replace("/\\#\\^\\[url\\]([{$URLSearchString}]*)\\[\\/url\\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_blank" >$1</a>', $Text); $Text = preg_replace("/\\#\\^\\[url\\=([{$URLSearchString}]*)\\](.*?)\\[\\/url\\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_blank" >$2</a>', $Text); $Text = preg_replace("/\\[url\\]([{$URLSearchString}]*)\\[\\/url\\]/ism", '<a href="$1" target="_blank" >$1</a>', $Text); $Text = preg_replace("/\\[url\\=([{$URLSearchString}]*)\\](.*?)\\[\\/url\\]/ism", '<a href="$1" target="_blank" >$2</a>', $Text); } if (strpos($Text, '[/zrl]') !== false) { $Text = preg_replace("/\\#\\^\\[zrl\\]([{$URLSearchString}]*)\\[\\/zrl\\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_blank" >$1</a>', $Text); $Text = preg_replace("/\\#\\^\\[zrl\\=([{$URLSearchString}]*)\\](.*?)\\[\\/zrl\\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_blank" >$2</a>', $Text); $Text = preg_replace("/\\[zrl\\]([{$URLSearchString}]*)\\[\\/zrl\\]/ism", '<a class="zrl" href="$1" target="_blank" >$1</a>', $Text); $Text = preg_replace("/\\[zrl\\=([{$URLSearchString}]*)\\](.*?)\\[\\/zrl\\]/ism", '<a class="zrl" href="$1" target="_blank" >$2</a>', $Text); } if (get_account_techlevel() < 2) { $Text = str_replace('<span class="bookmark-identifier">#^</span>', '', $Text); } // Perform MAIL Search if (strpos($Text, '[/mail]') !== false) { $Text = preg_replace("/\\[mail\\]([{$MAILSearchString}]*)\\[\\/mail\\]/", '<a href="mailto:$1" target="_blank" >$1</a>', $Text); $Text = preg_replace("/\\[mail\\=([{$MAILSearchString}]*)\\](.*?)\\[\\/mail\\]/", '<a href="mailto:$1" target="_blank" >$2</a>', $Text); } // leave open the posibility of [map=something] // this is replaced in prepare_body() which has knowledge of the item location if (strpos($Text, '[/map]') !== false) { $Text = preg_replace_callback("/\\[map\\](.*?)\\[\\/map\\]/ism", 'bb_map_location', $Text); } if (strpos($Text, '[map=') !== false) { $Text = preg_replace_callback("/\\[map=(.*?)\\]/ism", 'bb_map_coords', $Text); } if (strpos($Text, '[map]') !== false) { $Text = preg_replace("/\\[map\\]/", '<div class="map"></div>', $Text); } // Check for bold text if (strpos($Text, '[b]') !== false) { $Text = preg_replace("(\\[b\\](.*?)\\[\\/b\\])ism", '<strong>$1</strong>', $Text); } // Check for Italics text if (strpos($Text, '[i]') !== false) { $Text = preg_replace("(\\[i\\](.*?)\\[\\/i\\])ism", '<em>$1</em>', $Text); } // Check for Underline text if (strpos($Text, '[u]') !== false) { $Text = preg_replace("(\\[u\\](.*?)\\[\\/u\\])ism", '<u>$1</u>', $Text); } // Check for strike-through text if (strpos($Text, '[s]') !== false) { $Text = preg_replace("(\\[s\\](.*?)\\[\\/s\\])ism", '<strike>$1</strike>', $Text); } // Check for over-line text if (strpos($Text, '[o]') !== false) { $Text = preg_replace("(\\[o\\](.*?)\\[\\/o\\])ism", '<span class="overline">$1</span>', $Text); } if (strpos($Text, '[sup]') !== false) { $Text = preg_replace("(\\[sup\\](.*?)\\[\\/sup\\])ism", '<sup>$1</sup>', $Text); } if (strpos($Text, '[sub]') !== false) { $Text = preg_replace("(\\[sub\\](.*?)\\[\\/sub\\])ism", '<sub>$1</sub>', $Text); } // Check for colored text if (strpos($Text, '[/color]') !== false) { $Text = preg_replace("(\\[color=(.*?)\\](.*?)\\[\\/color\\])ism", "<span style=\"color: \$1;\">\$2</span>", $Text); } // Check for sized text // [size=50] --> font-size: 50px (with the unit). if (strpos($Text, '[/size]') !== false) { $Text = preg_replace("(\\[size=(\\d*?)\\](.*?)\\[\\/size\\])ism", "<span style=\"font-size: \$1px;\">\$2</span>", $Text); $Text = preg_replace("(\\[size=(.*?)\\](.*?)\\[\\/size\\])ism", "<span style=\"font-size: \$1;\">\$2</span>", $Text); } // Check for h1 if (strpos($Text, '[h1]') !== false) { $Text = preg_replace("(\\[h1\\](.*?)\\[\\/h1\\])ism", '<h1>$1</h1>', $Text); } // Check for h2 if (strpos($Text, '[h2]') !== false) { $Text = preg_replace("(\\[h2\\](.*?)\\[\\/h2\\])ism", '<h2>$1</h2>', $Text); } // Check for h3 if (strpos($Text, '[h3]') !== false) { $Text = preg_replace("(\\[h3\\](.*?)\\[\\/h3\\])ism", '<h3>$1</h3>', $Text); } // Check for h4 if (strpos($Text, '[h4]') !== false) { $Text = preg_replace("(\\[h4\\](.*?)\\[\\/h4\\])ism", '<h4>$1</h4>', $Text); } // Check for h5 if (strpos($Text, '[h5]') !== false) { $Text = preg_replace("(\\[h5\\](.*?)\\[\\/h5\\])ism", '<h5>$1</h5>', $Text); } // Check for h6 if (strpos($Text, '[h6]') !== false) { $Text = preg_replace("(\\[h6\\](.*?)\\[\\/h6\\])ism", '<h6>$1</h6>', $Text); } // Check for table of content without params if (strpos($Text, '[toc]') !== false) { $Text = preg_replace("/\\[toc\\]/ism", '<ul id="toc"></ul>', $Text); } // Check for table of content with params if (strpos($Text, '[toc') !== false) { $Text = preg_replace("/\\[toc([^\\]]+?)\\]/ism", '<ul$1></ul>', $Text); } // Check for centered text if (strpos($Text, '[/center]') !== false) { $Text = preg_replace("(\\[center\\](.*?)\\[\\/center\\])ism", "<div style=\"text-align:center;\">\$1</div>", $Text); } // Check for footer if (strpos($Text, '[/footer]') !== false) { $Text = preg_replace("(\\[footer\\](.*?)\\[\\/footer\\])ism", "<div class=\"wall-item-footer\">\$1</div>", $Text); } // Check for list text $Text = str_replace("[*]", "<li>", $Text); $Text = str_replace("[]", "<li><input type=\"checkbox\" disabled=\"disabled\">", $Text); $Text = str_replace("[x]", "<li><input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\">", $Text); // handle nested lists $endlessloop = 0; while ((strpos($Text, "[/list]") !== false && strpos($Text, "[list") !== false || strpos($Text, "[/checklist]") !== false && strpos($Text, "[checklist]") !== false || strpos($Text, "[/ol]") !== false && strpos($Text, "[ol]") !== false || strpos($Text, "[/ul]") !== false && strpos($Text, "[ul]") !== false || strpos($Text, "[/dl]") !== false && strpos($Text, "[dl") !== false || strpos($Text, "[/li]") !== false && strpos($Text, "[li]") !== false) && ++$endlessloop < 20) { $Text = preg_replace("/\\[list\\](.*?)\\[\\/list\\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>', $Text); $Text = preg_replace("/\\[list=\\](.*?)\\[\\/list\\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $Text); $Text = preg_replace("/\\[list=1\\](.*?)\\[\\/list\\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text); $Text = preg_replace("/\\[list=((?-i)i)\\](.*?)\\[\\/list\\]/ism", '<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>', $Text); $Text = preg_replace("/\\[list=((?-i)I)\\](.*?)\\[\\/list\\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $Text); $Text = preg_replace("/\\[list=((?-i)a)\\](.*?)\\[\\/list\\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $Text); $Text = preg_replace("/\\[list=((?-i)A)\\](.*?)\\[\\/list\\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $Text); $Text = preg_replace("/\\[checklist\\](.*?)\\[\\/checklist\\]/ism", '<ul class="checklist" style="list-style-type: none;">$1</ul>', $Text); $Text = preg_replace("/\\[ul\\](.*?)\\[\\/ul\\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>', $Text); $Text = preg_replace("/\\[ol\\](.*?)\\[\\/ol\\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text); $Text = preg_replace("/\\[li\\](.*?)\\[\\/li\\]/ism", '<li>$1</li>', $Text); // [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large // etc. style may be specified for the "terms" in the definition list. The quotation marks // are also optional. The regex looks intimidating, but breaks down as: // "[dl" <optional-whitespace> <optional-termStyles> "]" <matchGroup2> "[/dl]" // where optional-termStyles are: "terms=" <optional-quote> <matchGroup1> <optional-quote> $Text = preg_replace_callback('/\\[dl[[:space:]]*(?:terms=(?:"|")?([a-zA-Z]+)(?:"|")?)?\\](.*?)\\[\\/dl\\]/ism', 'bb_definitionList', $Text); } if (strpos($Text, '[th]') !== false) { $Text = preg_replace("/\\[th\\](.*?)\\[\\/th\\]/sm", '<th>$1</th>', $Text); } if (strpos($Text, '[td]') !== false) { $Text = preg_replace("/\\[td\\](.*?)\\[\\/td\\]/sm", '<td>$1</td>', $Text); } if (strpos($Text, '[tr]') !== false) { $Text = preg_replace("/\\[tr\\](.*?)\\[\\/tr\\]/sm", '<tr>$1</tr>', $Text); } if (strpos($Text, '[/table]') !== false) { $Text = preg_replace("/\\[table\\](.*?)\\[\\/table\\]/sm", '<table>$1</table>', $Text); $Text = preg_replace("/\\[table border=1\\](.*?)\\[\\/table\\]/sm", '<table border="1" >$1</table>', $Text); $Text = preg_replace("/\\[table border=0\\](.*?)\\[\\/table\\]/sm", '<table border="0" >$1</table>', $Text); } $Text = str_replace('</tr><br /><tr>', "</tr>\n<tr>", $Text); $Text = str_replace('[hr]', '<hr />', $Text); // This is actually executed in prepare_body() $Text = str_replace('[nosmile]', '', $Text); // Check for font change text if (strpos($Text, '[/font]') !== false) { $Text = preg_replace("/\\[font=(.*?)\\](.*?)\\[\\/font\\]/sm", "<span style=\"font-family: \$1;\">\$2</span>", $Text); } // Check for [code] text if (strpos($Text, '[code]') !== false) { $Text = preg_replace_callback("/\\[code\\](.*?)\\[\\/code\\]/ism", 'bb_code', $Text); } // Check for [spoiler] text $endlessloop = 0; while (strpos($Text, "[/spoiler]") !== false and strpos($Text, "[spoiler]") !== false and ++$endlessloop < 20) { $Text = preg_replace_callback("/\\[spoiler\\](.*?)\\[\\/spoiler\\]/ism", 'bb_spoilertag', $Text); } // Check for [spoiler=Author] text $endlessloop = 0; while (strpos($Text, "[/spoiler]") !== false and strpos($Text, "[spoiler=") !== false and ++$endlessloop < 20) { $Text = preg_replace_callback("/\\[spoiler=(.*?)\\](.*?)\\[\\/spoiler\\]/ism", 'bb_spoilertag', $Text); } // Check for [open] text $endlessloop = 0; while (strpos($Text, "[/open]") !== false and strpos($Text, "[open]") !== false and ++$endlessloop < 20) { $Text = preg_replace_callback("/\\[open\\](.*?)\\[\\/open\\]/ism", 'bb_opentag', $Text); } // Check for [open=Title] text $endlessloop = 0; while (strpos($Text, "[/open]") !== false and strpos($Text, "[open=") !== false and ++$endlessloop < 20) { $Text = preg_replace_callback("/\\[open=(.*?)\\](.*?)\\[\\/open\\]/ism", 'bb_opentag', $Text); } // Declare the format for [quote] layout $QuoteLayout = '<blockquote>$1</blockquote>'; // Check for [quote] text // handle nested quotes $endlessloop = 0; while (strpos($Text, "[/quote]") !== false and strpos($Text, "[quote]") !== false and ++$endlessloop < 20) { $Text = preg_replace("/\\[quote\\](.*?)\\[\\/quote\\]/ism", "{$QuoteLayout}", $Text); } // Check for [quote=Author] text $t_wrote = t('$1 wrote:'); // handle nested quotes $endlessloop = 0; while (strpos($Text, "[/quote]") !== false and strpos($Text, "[quote=") !== false and ++$endlessloop < 20) { $Text = preg_replace("/\\[quote=[\"\\']*(.*?)[\"\\']*\\](.*?)\\[\\/quote\\]/ism", "<span class=" . '"bb-quote"' . ">" . $t_wrote . "</span><blockquote>\$2</blockquote>", $Text); } // Images // [img]pathtoimage[/img] if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img\\](.*?)\\[\\/img\\]/ism", '<img style="max-width=100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg\\](.*?)\\[\\/zmg\\]/ism", '<img class="zrl" style="max-width=100%;" src="$1" alt="' . t('Image/photo') . '" />', $Text); } // [img float={left, right}]pathtoimage[/img] if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img float=left\\](.*?)\\[\\/img\\]/ism", '<img style="max-width=100%;" src="$1" style="float: left;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img float=right\\](.*?)\\[\\/img\\]/ism", '<img style="max-width=100%;" src="$1" style="float: right;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg float=left\\](.*?)\\[\\/zmg\\]/ism", '<img style="max-width=100%;" class="zrl" src="$1" style="float: left;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg float=right\\](.*?)\\[\\/zmg\\]/ism", '<img style="max-width=100%;" class="zrl" src="$1" style="float: right;" alt="' . t('Image/photo') . '" />', $Text); } // [img=widthxheight]pathtoimage[/img] if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img\\=([0-9]*)x([0-9]*)\\](.*?)\\[\\/img\\]/ism", '<img src="$3" style="width: 100%; max-width: $1px;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg\\=([0-9]*)x([0-9]*)\\](.*?)\\[\\/zmg\\]/ism", '<img class="zrl" src="$3" style="width: 100%; max-width: $1px;" alt="' . t('Image/photo') . '" />', $Text); } // [img=widthxheight float={left, right}]pathtoimage[/img] if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img\\=([0-9]*)x([0-9]*) float=left\\](.*?)\\[\\/img\\]/ism", '<img src="$3" style="width: 100%; max-width: $1px; float: left;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/img]') !== false) { $Text = preg_replace("/\\[img\\=([0-9]*)x([0-9]*) float=right\\](.*?)\\[\\/img\\]/ism", '<img src="$3" style="width: 100%; max-width: $1px; float: right;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg\\=([0-9]*)x([0-9]*) float=left\\](.*?)\\[\\/zmg\\]/ism", '<img class="zrl" src="$3" style="width: 100%; max-width: $1px; float: left;" alt="' . t('Image/photo') . '" />', $Text); } if (strpos($Text, '[/zmg]') !== false) { $Text = preg_replace("/\\[zmg\\=([0-9]*)x([0-9]*) float=right\\](.*?)\\[\\/zmg\\]/ism", '<img class="zrl" src="$3" style="width: 100%; max-width: $1px; float: right;" alt="' . t('Image/photo') . '" />', $Text); } // style (sanitized) if (strpos($Text, '[/style]') !== false) { $Text = preg_replace_callback("(\\[style=(.*?)\\](.*?)\\[\\/style\\])ism", "bb_sanitize_style", $Text); } // crypt if (strpos($Text, '[/crypt]') !== false) { $x = random_string(); $Text = preg_replace("/\\[crypt\\](.*?)\\[\\/crypt\\]/ism", '<br /><div id="' . $x . '"><img src="' . z_root() . '/images/lock_icon.gif" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text); $Text = preg_replace_callback("/\\[crypt (.*?)\\](.*?)\\[\\/crypt\\]/ism", 'bb_parse_crypt', $Text); } if (strpos($Text, '[/app]') !== false) { $Text = preg_replace_callback("/\\[app\\](.*?)\\[\\/app\\]/ism", 'bb_parse_app', $Text); } if (strpos($Text, '[/element]') !== false) { $Text = preg_replace_callback("/\\[element\\](.*?)\\[\\/element\\]/ism", 'bb_parse_element', $Text); } // html5 video and audio if (strpos($Text, '[/video]') !== false) { $Text = preg_replace_callback("/\\[video\\](.*?\\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\\[\\/video\\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text, '[/audio]') !== false) { $Text = preg_replace_callback("/\\[audio\\](.*?\\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\\[\\/audio\\]/ism", 'tryzrlaudio', $Text); } if (strpos($Text, '[/zvideo]') !== false) { $Text = preg_replace_callback("/\\[zvideo\\](.*?\\.(ogg|ogv|oga|ogm|webm|mp4|mpeg|mpg))\\[\\/zvideo\\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text, '[/zaudio]') !== false) { $Text = preg_replace_callback("/\\[zaudio\\](.*?\\.(ogg|ogv|oga|ogm|webm|mp4|mp3|opus|m4a))\\[\\/zaudio\\]/ism", 'tryzrlaudio', $Text); } // Try to Oembed if ($tryoembed) { if (strpos($Text, '[/video]') !== false) { $Text = preg_replace_callback("/\\[video\\](.*?)\\[\\/video\\]/ism", 'tryoembed', $Text); } if (strpos($Text, '[/audio]') !== false) { $Text = preg_replace_callback("/\\[audio\\](.*?)\\[\\/audio\\]/ism", 'tryoembed', $Text); } if (strpos($Text, '[/zvideo]') !== false) { $Text = preg_replace_callback("/\\[zvideo\\](.*?)\\[\\/zvideo\\]/ism", 'tryoembed', $Text); } if (strpos($Text, '[/zaudio]') !== false) { $Text = preg_replace_callback("/\\[zaudio\\](.*?)\\[\\/zaudio\\]/ism", 'tryoembed', $Text); } } // if video couldn't be embedded, link to it instead. if (strpos($Text, '[/video]') !== false) { $Text = preg_replace("/\\[video\\](.*?)\\[\\/video\\]/", '<a href="$1" target="_blank" >$1</a>', $Text); } if (strpos($Text, '[/audio]') !== false) { $Text = preg_replace("/\\[audio\\](.*?)\\[\\/audio\\]/", '<a href="$1" target="_blank" >$1</a>', $Text); } if (strpos($Text, '[/zvideo]') !== false) { $Text = preg_replace("/\\[zvideo\\](.*?)\\[\\/zvideo\\]/", '<a class="zid" href="$1" target="_blank" >$1</a>', $Text); } if (strpos($Text, '[/zaudio]') !== false) { $Text = preg_replace("/\\[zaudio\\](.*?)\\[\\/zaudio\\]/", '<a class="zid" href="$1" target="_blank" >$1</a>', $Text); } if ($tryoembed) { if (strpos($Text, '[/iframe]') !== false) { $Text = preg_replace_callback("/\\[iframe\\](.*?)\\[\\/iframe\\]/ism", 'bb_iframe', $Text); } } else { if (strpos($Text, '[/iframe]') !== false) { $Text = preg_replace("/\\[iframe\\](.*?)\\[\\/iframe\\]/ism", '<a href="$1" target="_blank" >$1</a>', $Text); } } // oembed tag $Text = oembed_bbcode2html($Text); // Avoid triple linefeeds through oembed $Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text); // If we found an event earlier, strip out all the event code and replace with a reformatted version. // Replace the event-start section with the entire formatted event. The other bbcode is stripped. // Summary (e.g. title) is required, earlier revisions only required description (in addition to // start which is always required). Allow desc with a missing summary for compatibility. if ((x($ev, 'desc') || x($ev, 'summary')) && x($ev, 'start')) { $sub = format_event_html($ev); $sub = str_replace('$', "", $sub); $Text = preg_replace("/\\[event\\-start\\](.*?)\\[\\/event\\-start\\]/ism", $sub, $Text); $Text = preg_replace("/\\[event\\-summary\\](.*?)\\[\\/event\\-summary\\]/ism", '', $Text); $Text = preg_replace("/\\[event\\-description\\](.*?)\\[\\/event\\-description\\]/ism", '', $Text); $Text = preg_replace("/\\[event\\-finish\\](.*?)\\[\\/event\\-finish\\]/ism", '', $Text); $Text = preg_replace("/\\[event\\-id\\](.*?)\\[\\/event\\-id\\]/ism", '', $Text); $Text = preg_replace("/\\[event\\-location\\](.*?)\\[\\/event\\-location\\]/ism", '', $Text); $Text = preg_replace("/\\[event\\-adjust\\](.*?)\\[\\/event\\-adjust\\]/ism", '', $Text); $Text = str_replace("", '$', $Text); } // Unhide all [noparse] contained bbtags unspacefying them // and triming the [noparse] tag. if (strpos($Text, '[noparse]') !== false) { $Text = preg_replace_callback("/\\[noparse\\](.*?)\\[\\/noparse\\]/ism", 'bb_unspacefy_and_trim', $Text); } if (strpos($Text, '[nobb]') !== false) { $Text = preg_replace_callback("/\\[nobb\\](.*?)\\[\\/nobb\\]/ism", 'bb_unspacefy_and_trim', $Text); } if (strpos($Text, '[pre]') !== false) { $Text = preg_replace_callback("/\\[pre\\](.*?)\\[\\/pre\\]/ism", 'bb_unspacefy_and_trim', $Text); } $Text = preg_replace('/\\[\\&\\;([#a-z0-9]+)\\;\\]/', '&$1;', $Text); // fix any escaped ampersands that may have been converted into links if (strpos($Text, '&') !== false) { $Text = preg_replace("/\\<(.*?)(src|href)=(.*?)\\&\\;(.*?)\\>/ism", '<$1$2=$3&$4>', $Text); } // This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where // the scheme begins with z (zhttp), h (http(s)), f (ftp), m (mailto), and named anchors. $Text = preg_replace("/\\<(.*?)(src|href)=\"[^zhfm#](.*?)\\>/ism", '<$1$2="">', $Text); $Text = bb_replace_images($Text, $saved_images); call_hooks('bbcode', $Text); return $Text; }
/** @file */ function nav(&$a) { /** * * Build page header and site navigation bars * */ if (!x(App::$page, 'nav')) { App::$page['nav'] = ''; } $base = z_root(); App::$page['htmlhead'] .= <<<EOT <script>\$(document).ready(function() { \t\$("#nav-search-text").search_autocomplete('{$base}/acl'); }); </script> EOT; if (local_channel()) { $channel = App::get_channel(); $observer = App::get_observer(); $prof = q("select id from profile where uid = %d and is_default = 1", intval($channel['channel_id'])); $chans = q("select channel_name, channel_id from channel where channel_account_id = %d and channel_removed = 0 order by channel_name ", intval(get_account_id())); } elseif (remote_channel()) { $observer = App::get_observer(); } $myident = $channel ? $channel['xchan_addr'] : ''; $sitelocation = $myident ? $myident : App::get_hostname(); /** * * Provide a banner/logo/whatever * */ $banner = get_config('system', 'banner'); if ($banner === false) { $banner = get_config('system', 'sitename'); } App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array('$baseurl' => z_root(), '$sitelocation' => $sitelocation, '$banner' => $banner)); $server_role = get_config('system', 'server_role'); $basic = $server_role === 'basic' ? true : false; $techlevel = get_account_techlevel(); // nav links: array of array('href', 'text', 'extra css classes', 'title') $nav = array(); /** * Display login or logout */ $nav['usermenu'] = array(); $userinfo = null; $nav['loginmenu'] = array(); if (local_channel()) { if ($chans && count($chans) > 1 && feature_enabled(local_channel(), 'nav_channel_select') && !$basic) { $nav['channels'] = $chans; } $nav['logout'] = array('logout', t('Logout'), "", t('End this session'), 'logout_nav_btn'); // user menu $nav['usermenu'][] = array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations'), 'channel_nav_btn'); $nav['usermenu'][] = array('profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'), 'profile_nav_btn'); if (feature_enabled(local_channel(), 'multi_profiles') && !$basic) { $nav['usermenu'][] = array('profiles', t('Edit Profiles'), "", t('Manage/Edit profiles'), 'profiles_nav_btn'); } else { $nav['usermenu'][] = array('profiles/' . $prof[0]['id'], t('Edit Profile'), "", t('Edit your profile'), 'profiles_nav_btn'); } $nav['usermenu'][] = array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos'), 'photos_nav_btn'); $nav['usermenu'][] = array('cloud/' . $channel['channel_address'], t('Files'), "", t('Your files'), 'cloud_nav_btn'); if (!$basic && feature_enabled(local_channel(), 'ajaxchat')) { $nav['usermenu'][] = array('chat/' . $channel['channel_address'], t('Chat'), "", t('Your chatrooms'), 'chat_nav_btn'); } require_once 'include/menu.php'; $has_bookmarks = menu_list_count(local_channel(), '', MENU_BOOKMARK) + menu_list_count(local_channel(), '', MENU_SYSTEM | MENU_BOOKMARK); if ($has_bookmarks && !$basic) { $nav['usermenu'][] = array('bookmarks', t('Bookmarks'), "", t('Your bookmarks'), 'bookmarks_nav_btn'); } if (feature_enabled($channel['channel_id'], 'webpages') && !$basic) { $nav['usermenu'][] = array('webpages/' . $channel['channel_address'], t('Webpages'), "", t('Your webpages'), 'webpages_nav_btn'); } if (feature_enabled($channel['channel_id'], 'wiki') && !$basic) { $nav['usermenu'][] = array('wiki/' . $channel['channel_address'], t('Wiki'), "", t('Your wiki'), 'wiki_nav_btn'); } } else { if (!get_account_id()) { $nav['loginmenu'][] = array('login', t('Login'), '', t('Sign in'), 'login_nav_btn'); } else { $nav['alogout'] = array('logout', t('Logout'), "", t('End this session'), 'logout_nav_btn'); } } if ($observer) { $userinfo = array('icon' => $observer['xchan_photo_m'], 'name' => $observer['xchan_addr']); } if ($observer) { $nav['lock'] = array('logout', '', 'lock', sprintf(t('%s - click to logout'), $observer['xchan_addr'])); } elseif (!$_SESSION['authenticated']) { $nav['loginmenu'][] = array('rmagic', t('Remote authentication'), '', t('Click to authenticate to your home hub'), 'rmagic_nav_btn'); } /** * "Home" should also take you home from an authenticated remote profile connection */ $homelink = get_my_url(); if (!$homelink) { $observer = App::get_observer(); $homelink = $observer ? $observer['xchan_url'] : ''; } if (!local_channel()) { $nav['home'] = array($homelink, t('Home'), "", t('Home Page'), 'home_nav_btn'); } if ((get_config('system', 'register_policy') == REGISTER_OPEN || get_config('system', 'register_policy') == REGISTER_APPROVE) && !$_SESSION['authenticated']) { $nav['register'] = array('register', t('Register'), "", t('Create an account'), 'register_nav_btn'); } if (!get_config('system', 'hide_help')) { $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; $context_help = ''; $enable_context_help = intval(get_config('system', 'enable_context_help')) === 1 || get_config('system', 'enable_context_help') === false ? true : false; if ($enable_context_help === true) { require_once 'include/help.php'; $context_help = load_context_help(); //point directly to /help if $context_help is empty - this can be removed once we have context help for all modules $enable_context_help = $context_help ? true : false; } $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help); } if (!$basic) { $nav['apps'] = array('apps', t('Apps'), "", t('Applications, utilities, links, games'), 'apps_nav_btn'); } $nav['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content')); $nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'), 'directory_nav_btn'); /** * * The following nav links are only show to logged in users * */ if (local_channel()) { $nav['network'] = array('network', t('Grid'), "", t('Your grid'), 'network_nav_btn'); $nav['network']['mark'] = array('', t('Mark all grid notifications seen'), '', ''); $nav['home'] = array('channel/' . $channel['channel_address'], t('Channel Home'), "", t('Channel home'), 'home_nav_btn'); $nav['home']['mark'] = array('', t('Mark all channel notifications seen'), '', ''); $nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections'), 'connections_nav_btn'); $nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'), 'notifications_nav_btn'); $nav['notifications']['all'] = array('notifications/system', t('See all notifications'), "", ""); $nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '', ''); $nav['messages'] = array('mail/combined', t('Mail'), "", t('Private mail'), 'mail_nav_btn'); $nav['messages']['all'] = array('mail/combined', t('See all private messages'), "", ""); $nav['messages']['mark'] = array('', t('Mark all private messages seen'), '', ''); $nav['messages']['inbox'] = array('mail/inbox', t('Inbox'), "", t('Inbox')); $nav['messages']['outbox'] = array('mail/outbox', t('Outbox'), "", t('Outbox')); $nav['messages']['new'] = array('mail/new', t('New Message'), "", t('New Message')); $nav['all_events'] = array('events', t('Events'), "", t('Event Calendar'), 'events_nav_btn'); $nav['all_events']['all'] = array('events', t('See all events'), "", ""); $nav['all_events']['mark'] = array('', t('Mark all events seen'), '', ''); if (!$basic) { $nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels'), 'manage_nav_btn'); } $nav['settings'] = array('settings', t('Settings'), "", t('Account/Channel Settings'), 'settings_nav_btn'); } /** * Admin page */ if (is_site_admin()) { $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration'), 'admin_nav_btn'); } /** * * Provide a banner/logo/whatever * */ $banner = get_config('system', 'banner'); if ($banner === false) { $banner = get_config('system', 'sitename'); } $x = array('nav' => $nav, 'usermenu' => $userinfo); call_hooks('nav', $x); // Not sure the best place to put this on the page. So I'm implementing it but leaving it // turned off until somebody discovers this and figures out a good location for it. $powered_by = ''; // $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>'; $tpl = get_markup_template('nav.tpl'); App::$page['nav'] .= replace_macros($tpl, array('$baseurl' => z_root(), '$sitelocation' => $sitelocation, '$nav' => $x['nav'], '$banner' => $banner, '$emptynotifications' => t('Loading...'), '$userinfo' => $x['usermenu'], '$localuser' => local_channel(), '$sel' => App::$nav_sel, '$powered_by' => $powered_by, '$help' => t('@name, #tag, ?doc, content'), '$pleasewait' => t('Please wait...'))); if (x($_SESSION, 'reload_avatar') && $observer) { // The avatar has been changed on the server but the browser doesn't know that, // force the browser to reload the image from the server instead of its cache. $tpl = get_markup_template('force_image_reload.tpl'); App::$page['nav'] .= replace_macros($tpl, array('$imgUrl' => $observer['xchan_photo_m'])); unset($_SESSION['reload_avatar']); } call_hooks('page_header', App::$page['nav']); }
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))); } \Zotlabs\Daemon\Master::Summon(array('Notifier', '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\n\t\t\t\t\twhere 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']; } $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'] && get_account_techlevel() > 0 ? 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 <strong>may</strong> be able to respond from the sender's profile page."), '$mails' => $mails, '$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; }
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('<a href="pubsites">Register at another affiliated hub.</a>'); } $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; } } $privacy_role = x($_REQUEST, 'permissions_role') ? $_REQUEST['permissions_role'] : ""; $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); if (get_account_techlevel() < 4 && $privacy_role !== 'custom') { unset($perm_roles[t('Other')]); } // Configurable terms of service link $tosurl = get_config('system', 'tos_url'); if (!$tosurl) { $tosurl = z_root() . '/help/TermsOfService'; } $toslink = '<a href="' . $tosurl . '" target="_blank">' . t('Terms of Service') . '</a>'; // 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)); $role = array('permissions_role', t('Channel role and privacy'), $privacy_role ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>', $perm_roles); $tos = array('tos', $label_tos, '', '', array(t('no'), t('yes'))); $server_role = get_config('system', 'server_role'); $auto_create = $server_role == 'basic' || get_config('system', 'auto_channel_create') ? true : false; $default_role = $server_role == 'basic' ? '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' => 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; }
/** * @brief * * @param App $a * @param boolean $is_owner default false * @param string $nickname default null * @return void|string */ function profile_tabs($a, $is_owner = false, $nickname = null) { // Don't provide any profile tabs if we're running as the sys channel if (App::$is_sys) { return; } $channel = App::get_channel(); if (is_null($nickname)) { $nickname = $channel['channel_address']; } $uid = App::$profile['profile_uid'] ? App::$profile['profile_uid'] : local_channel(); $account_id = App::$profile['profile_uid'] ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']; if ($uid == local_channel()) { $cal_link = ''; } else { $cal_link = '/cal/' . $nickname; } if (get_pconfig($uid, 'system', 'noprofiletabs')) { return; } if (x($_GET, 'tab')) { $tab = notags(trim($_GET['tab'])); } $url = z_root() . '/channel/' . $nickname; $pr = z_root() . '/profile/' . $nickname; $tabs = array(array('label' => t('Channel'), 'url' => $url, 'sel' => argv(0) == 'channel' ? 'active' : '', 'title' => t('Status Messages and Posts'), 'id' => 'status-tab')); $p = get_all_perms($uid, get_observer_hash()); if ($p['view_profile']) { $tabs[] = array('label' => t('About'), 'url' => $pr, 'sel' => argv(0) == 'profile' ? 'active' : '', 'title' => t('Profile Details'), 'id' => 'profile-tab'); } if ($p['view_storage']) { $tabs[] = array('label' => t('Photos'), 'url' => z_root() . '/photos/' . $nickname, 'sel' => argv(0) == 'photos' ? 'active' : '', 'title' => t('Photo Albums'), 'id' => 'photo-tab'); $tabs[] = array('label' => t('Files'), 'url' => z_root() . '/cloud/' . $nickname, 'sel' => argv(0) == 'cloud' || argv(0) == 'sharedwithme' ? 'active' : '', 'title' => t('Files and Storage'), 'id' => 'files-tab'); } if ($p['view_stream'] && $cal_link) { $tabs[] = array('label' => t('Events'), 'url' => z_root() . $cal_link, 'sel' => argv(0) == 'cal' || argv(0) == 'events' ? 'active' : '', 'title' => t('Events'), 'id' => 'event-tab'); } if ($p['chat'] && feature_enabled($uid, 'ajaxchat')) { $has_chats = Zotlabs\Lib\Chatroom::list_count($uid); if ($has_chats) { $tabs[] = array('label' => t('Chatrooms'), 'url' => z_root() . '/chat/' . $nickname, 'sel' => argv(0) == 'chat' ? 'active' : '', 'title' => t('Chatrooms'), 'id' => 'chat-tab'); } } require_once 'include/menu.php'; $has_bookmarks = menu_list_count(local_channel(), '', MENU_BOOKMARK) + menu_list_count(local_channel(), '', MENU_SYSTEM | MENU_BOOKMARK); if ($is_owner && $has_bookmarks) { $tabs[] = array('label' => t('Bookmarks'), 'url' => z_root() . '/bookmarks', 'sel' => argv(0) == 'bookmarks' ? 'active' : '', 'title' => t('Saved Bookmarks'), 'id' => 'bookmarks-tab'); } if ($p['write_pages'] && feature_enabled($uid, 'webpages')) { $tabs[] = array('label' => t('Webpages'), 'url' => z_root() . '/webpages/' . $nickname, 'sel' => argv(0) == 'webpages' ? 'active' : '', 'title' => t('Manage Webpages'), 'id' => 'webpages-tab'); } if (feature_enabled($uid, 'wiki') && get_account_techlevel($account_id) > 3) { $tabs[] = array('label' => t('Wiki'), 'url' => z_root() . '/wiki/' . $nickname, 'sel' => argv(0) == 'wiki' ? 'active' : '', 'title' => t('Wiki'), 'id' => 'wiki-tab'); } $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $tab ? $tab : false, 'tabs' => $tabs); call_hooks('profile_tabs', $arr); $tpl = get_markup_template('common_tabs.tpl'); return replace_macros($tpl, array('$tabs' => $arr['tabs'])); }
function widget_settings_menu($arr) { if (!local_channel()) { return; } $channel = App::get_channel(); $abook_self_id = 0; // Retrieve the 'self' address book entry for use in the auto-permissions link $role = get_pconfig(local_channel(), 'system', 'permissions_role'); $abk = q("select abook_id from abook where abook_channel = %d and abook_self = 1 limit 1", intval(local_channel())); if ($abk) { $abook_self_id = $abk[0]['abook_id']; } $hublocs = q("select count(*) as total from hubloc where hubloc_hash = '%s'", dbesc($channel['channel_hash'])); $hublocs = $hublocs[0]['total'] > 1 ? true : false; $tabs = array(array('label' => t('Account settings'), 'url' => z_root() . '/settings/account', 'selected' => argv(1) === 'account' ? 'active' : ''), array('label' => t('Channel settings'), 'url' => z_root() . '/settings/channel', 'selected' => argv(1) === 'channel' ? 'active' : '')); if (get_account_techlevel() > 0 && get_features()) { $tabs[] = array('label' => t('Additional features'), 'url' => z_root() . '/settings/features', 'selected' => argv(1) === 'features' ? 'active' : ''); } $tabs[] = array('label' => t('Feature/Addon settings'), 'url' => z_root() . '/settings/featured', 'selected' => argv(1) === 'featured' ? 'active' : ''); $tabs[] = array('label' => t('Display settings'), 'url' => z_root() . '/settings/display', 'selected' => argv(1) === 'display' ? 'active' : ''); if ($hublocs) { $tabs[] = array('label' => t('Manage locations'), 'url' => z_root() . '/locs', 'selected' => argv(1) === 'locs' ? 'active' : ''); } $tabs[] = array('label' => t('Export channel'), 'url' => z_root() . '/uexport', 'selected' => ''); $tabs[] = array('label' => t('Connected apps'), 'url' => z_root() . '/settings/oauth', 'selected' => argv(1) === 'oauth' ? 'active' : ''); if (get_account_techlevel() > 2) { $tabs[] = array('label' => t('Guest Access Tokens'), 'url' => z_root() . '/settings/tokens', 'selected' => argv(1) === 'tokens' ? 'active' : ''); } if ($role === false || $role === 'custom') { $tabs[] = array('label' => t('Connection Default Permissions'), 'url' => z_root() . '/connedit/' . $abook_self_id, 'selected' => ''); } if (feature_enabled(local_channel(), 'premium_channel')) { $tabs[] = array('label' => t('Premium Channel Settings'), 'url' => z_root() . '/connect/' . $channel['channel_address'], 'selected' => ''); } if (feature_enabled(local_channel(), 'channel_sources')) { $tabs[] = array('label' => t('Channel Sources'), 'url' => z_root() . '/sources', 'selected' => ''); } $tabtpl = get_markup_template("generic_links_widget.tpl"); return replace_macros($tabtpl, array('$title' => t('Settings'), '$class' => 'settings-widget', '$items' => $tabs)); }