Пример #1
0
 /**
  * Add a field to the form.
  *
  * @param string $section The name of the section to add this field to.
  * @param string $id The name of the field.
  * @param mixed $renderCallback The function to call that will return the field's HTML.
  * @param mixed $processCallback The function to call that will process the field's input.
  * @param mixed $position The position to put this field relative to other fields.
  * @see addArrayToString
  * @return void
  */
 public function addField($section, $id, $renderCallback, $processCallback, $position = false)
 {
     if (!isset($this->fields[$section])) {
         $this->fields[$section] = array();
     }
     addToArrayString($this->fields[$section], $id, array("renderCallback" => $renderCallback, "processCallback" => $processCallback), $position);
 }
Пример #2
0
 /**
  * Add an event handler to the "getEditControls" method of the conversation controller to add BBCode
  * formatting buttons to the edit controls.
  *
  * @return void
  */
 public function handler_conversationController_getEditControls($sender, &$controls, $id)
 {
     addToArrayString($controls, "fixed", "<a href='javascript:BBCode.fixed(\"{$id}\");void(0)' title='" . T("Fixed") . "' class='bbcode-fixed'><span>" . T("Fixed") . "</span></a>", 0);
     addToArrayString($controls, "image", "<a href='javascript:BBCode.image(\"{$id}\");void(0)' title='" . T("Image") . "' class='bbcode-img'><span>" . T("Image") . "</span></a>", 0);
     addToArrayString($controls, "link", "<a href='javascript:BBCode.link(\"{$id}\");void(0)' title='" . T("Link") . "' class='bbcode-link'><span>" . T("Link") . "</span></a>", 0);
     addToArrayString($controls, "strike", "<a href='javascript:BBCode.strikethrough(\"{$id}\");void(0)' title='" . T("Strike") . "' class='bbcode-s'><span>" . T("Strike") . "</span></a>", 0);
     addToArrayString($controls, "header", "<a href='javascript:BBCode.header(\"{$id}\");void(0)' title='" . T("Header") . "' class='bbcode-h'><span>" . T("Header") . "</span></a>", 0);
     addToArrayString($controls, "italic", "<a href='javascript:BBCode.italic(\"{$id}\");void(0)' title='" . T("Italic") . "' class='bbcode-i'><span>" . T("Italic") . "</span></a>", 0);
     addToArrayString($controls, "bold", "<a href='javascript:BBCode.bold(\"{$id}\");void(0)' title='" . T("Bold") . "' class='bbcode-b'><span>" . T("Bold") . "</span></a>", 0);
 }
Пример #3
0
 /**
  * Add an event handler to the "getEditControls" method of the conversation controller to add BBCode
  * formatting buttons to the edit controls.
  *
  * @return void
  */
 public function handler_conversationController_getEditControls($sender, &$controls, $id)
 {
     addToArrayString($controls, "fixed", "<a href='javascript:BBCode.fixed(\"{$id}\");void(0)' title='" . T("Code") . "' class='control-fixed'><i class='icon-code'></i></a>", 0);
     addToArrayString($controls, "image", "<a href='javascript:BBCode.image(\"{$id}\");void(0)' title='" . T("Image") . "' class='control-img'><i class='icon-picture'></i></a>", 0);
     addToArrayString($controls, "link", "<a href='javascript:BBCode.link(\"{$id}\");void(0)' title='" . T("Link") . "' class='control-link'><i class='icon-link'></i></a>", 0);
     addToArrayString($controls, "strike", "<a href='javascript:BBCode.strikethrough(\"{$id}\");void(0)' title='" . T("Strike") . "' class='control-s'><i class='icon-strikethrough'></i></a>", 0);
     addToArrayString($controls, "header", "<a href='javascript:BBCode.header(\"{$id}\");void(0)' title='" . T("Header") . "' class='control-h'><i class='icon-h-sign'></i></a>", 0);
     addToArrayString($controls, "italic", "<a href='javascript:BBCode.italic(\"{$id}\");void(0)' title='" . T("Italic") . "' class='control-i'><i class='icon-italic'></i></a>", 0);
     addToArrayString($controls, "bold", "<a href='javascript:BBCode.bold(\"{$id}\");void(0)' title='" . T("Bold") . "' class='control-b'><i class='icon-bold'></i></a>", 0);
 }
Пример #4
0
 /**
  * Add an event handler to the "getEditControls" method of the conversation controller to add BBCode
  * formatting buttons to the edit controls.
  *
  * @return void
  */
 public function handler_conversationController_getEditControls($sender, &$controls, $id)
 {
     addToArrayString($controls, "smileys", "<a href='javascript:EmoticonAdv.showDropDown(\"{$id}\");void(0)' title='" . T("Smileys") . "' class='control-smile'><i class='icon-smile'></i></a>", 0);
 }
Пример #5
0
 function addFieldset($fieldset, $legend, $position = false)
 {
     return addToArrayString($this->form, $fieldset, array("legend" => $legend), $position);
 }
Пример #6
0
 public function handler_conversationsController_constructGambitsMenu($sender, &$gambits)
 {
     addToArrayString($gambits["replies"], T("gambit.order by views"), array("gambit-orderByViews", "icon-eye-open"));
 }
 /**
  * Display a list of conversations, optionally filtered by channel(s) and a search string.
  *
  * @return void
  */
 public function action_index($channelSlug = false)
 {
     if (!$this->allowed()) {
         return;
     }
     list($channelInfo, $currentChannels, $channelIds, $includeDescendants) = $this->getSelectedChannels($channelSlug);
     // Now we need to construct some arrays to determine which channel "tabs" to show in the view.
     // $channels is a list of channels with the same parent as the current selected channel(s).
     // $path is a breadcrumb trail to the depth of the currently selected channel(s).
     $channels = array();
     $path = array();
     // Work out what channel we will use as the "parent" channel. This will be the last item in $path,
     // and its children will be in $channels.
     $curChannel = false;
     // If channels have been selected, use the first of them.
     if (count($currentChannels)) {
         $curChannel = $channelInfo[$currentChannels[0]];
     }
     // If the currently selected channel has no children, or if we're not including descendants, use
     // its parent as the parent channel.
     if ($curChannel and $curChannel["lft"] >= $curChannel["rgt"] - 1 or !$includeDescendants) {
         $curChannel = @$channelInfo[$curChannel["parentId"]];
     }
     // If no channel is selected, make a faux parent channel.
     if (!$curChannel) {
         $curChannel = array("lft" => 0, "rgt" => PHP_INT_MAX, "depth" => -1);
     }
     // Now, finally, go through all the channels and add ancestors of the "parent" channel to the $path,
     // and direct children to the list of $channels. Make sure we don't include any channels which
     // the user has unsubscribed to.
     foreach ($channelInfo as $channel) {
         if ($channel["lft"] > $curChannel["lft"] and $channel["rgt"] < $curChannel["rgt"] and $channel["depth"] == $curChannel["depth"] + 1 and empty($channel["unsubscribed"])) {
             $channels[] = $channel;
         } elseif ($channel["lft"] <= $curChannel["lft"] and $channel["rgt"] >= $curChannel["rgt"]) {
             $path[] = $channel;
         }
     }
     // Store the currently selected channel in the session, so that it can be automatically selected
     // if "New conversation" is clicked.
     if (!empty($currentChannels)) {
         ET::$session->store("searchChannelId", $currentChannels[0]);
     }
     // Get the search string request value.
     $searchString = R("search");
     // Last, but definitely not least... perform the search!
     $search = ET::searchModel();
     $conversationIDs = $search->getConversationIDs($channelIds, $searchString, count($currentChannels) or !ET::$session->userId);
     // If this page was originally accessed at conversations/markAsRead/all?search=whatever (the
     // markAsRead method simply calls the index method), then mark the results as read.
     if ($this->controllerMethod == "markasread" and ET::$session->userId) {
         ET::conversationModel()->markAsRead($conversationIDs, ET::$session->userId);
     }
     $results = $search->getResults($conversationIDs);
     // Were there any errors? Show them as messages.
     if ($search->errorCount()) {
         $this->messages($search->errors(), "warning dismissable");
     } else {
         $this->highlight($search->fulltext);
     }
     // Pass on a bunch of data to the view.
     $this->data("results", $results);
     $this->data("limit", $search->limit);
     $this->data("showViewMoreLink", $search->areMoreResults());
     $this->data("channelPath", $path);
     $this->data("channelTabs", $channels);
     $this->data("currentChannels", $currentChannels);
     $this->data("channelInfo", $channelInfo);
     $this->data("channelSlug", $channelSlug = $channelSlug ? $channelSlug : "all");
     $this->data("searchString", $searchString);
     $this->data("fulltextString", implode(" ", $search->fulltext));
     // Construct a canonical URL and add to the breadcrumb stack.
     $slugs = array();
     foreach ($currentChannels as $channel) {
         $slugs[] = $channelInfo[$channel]["slug"];
     }
     $url = "conversations/" . urlencode(($k = implode(" ", $slugs)) ? $k : "all") . ($searchString ? "?search=" . urlencode($searchString) : "");
     $this->pushNavigation("conversations", "search", URL($url));
     $this->canonicalURL = URL($url, true);
     // If we're loading the page in full...
     if ($this->responseType === RESPONSE_TYPE_DEFAULT) {
         // Update the user's last action.
         ET::memberModel()->updateLastAction("search");
         // Add a link to the RSS feed in the bar.
         // $this->addToMenu("meta", "feed", "<a href='".URL(str_replace("conversations/", "conversations/index.atom/", $url))."' id='feed'>".T("Feed")."</a>");
         $controls = ETFactory::make("menu");
         // Mark as read controls
         if (ET::$session->user) {
             $controls->add("markAllAsRead", "<a href='" . URL("conversations/markAllAsRead/?token=" . ET::$session->token . "' id='control-markAllAsRead'><i class='icon-check'></i> " . T("Mark all as read") . "</a>"));
             $controls->add("markListedAsRead", "<a href='" . URL("conversations/{$channelSlug}/?search=" . urlencode($searchString) . "&markAsRead=1&token=" . ET::$session->token . "' id='control-markListedAsRead'><i class='icon-list'></i> " . T("Mark listed as read") . "</a>"));
         }
         // Add the default gambits to the gambit cloud: gambit text => css class to apply.
         $gambits = array("main" => array(T("gambit.sticky") => array("gambit-sticky", "icon-pushpin")), "time" => array(T("gambit.order by newest") => array("gambit-orderByNewest", "icon-list-ol"), T("gambit.active last ? hours") => array("gambit-activeLastHours", "icon-time"), T("gambit.active last ? days") => array("gambit-activeLastDays", "icon-calendar"), T("gambit.active today") => array("gambit-activeToday", "icon-asterisk"), T("gambit.dead") => array("gambit-dead", "icon-remove"), T("gambit.locked") => array("gambit-locked", "icon-lock")), "member" => array(T("gambit.author:") . T("gambit.member") => array("gambit-author", "icon-user"), T("gambit.contributor:") . T("gambit.member") => array("gambit-contributor", "icon-user")), "replies" => array(T("gambit.has replies") => array("gambit-hasReplies", "icon-comment"), T("gambit.has >10 replies") => array("gambit-replies", "icon-comments"), T("gambit.order by replies") => array("gambit-orderByReplies", "icon-list-ol")), "text" => array(T("gambit.title:") . " ?" => array("gambit-title", "icon-font")), "misc" => array(T("gambit.random") => array("gambit-random", "icon-random"), T("gambit.reverse") => array("gambit-reverse", "icon-exchange")));
         // Add some more personal gambits if there is a user logged in.
         if (ET::$session->user) {
             addToArrayString($gambits["main"], T("gambit.private"), array("gambit-private", "icon-envelope-alt"), 1);
             addToArrayString($gambits["main"], T("gambit.starred"), array("gambit-starred", "icon-star"), 2);
             addToArrayString($gambits["main"], T("gambit.draft"), array("gambit-draft", "icon-pencil"), 3);
             addToArrayString($gambits["main"], T("gambit.ignored"), array("gambit-ignored", "icon-eye-close"), 4);
             addToArrayString($gambits["time"], T("gambit.unread"), array("gambit-unread", "icon-inbox"), 0);
             addToArrayString($gambits["member"], T("gambit.author:") . T("gambit.myself"), array("gambit-authorMyself", "icon-smile"), 0);
             addToArrayString($gambits["member"], T("gambit.contributor:") . T("gambit.myself"), array("gambit-contributorMyself", "icon-smile"), 2);
         }
         $this->trigger("constructGambitsMenu", array(&$gambits));
         // Construct the gambits menu based on the above arrays.
         $gambitsMenu = ETFactory::make("menu");
         $linkPrefix = "conversations/" . $channelSlug . "/?search=" . urlencode(!empty($searchString) ? $searchString . " + " : "");
         foreach ($gambits as $section => $items) {
             foreach ($items as $gambit => $classes) {
                 $gambitsMenu->add($classes[0], "<a href='" . URL($linkPrefix . urlencode("#" . $gambit)) . "' class='{$classes[0]}' data-gambit='{$gambit}'>" . (!empty($classes[1]) ? "<i class='{$classes[1]}'></i> " : "") . "{$gambit}</a>");
             }
             end($gambits);
             if ($section !== key($gambits)) {
                 $gambitsMenu->separator();
             }
         }
         $this->data("controlsMenu", $controls);
         $this->data("gambitsMenu", $gambitsMenu);
         // Construct a list of keywords to use in the meta tags.
         $keywords = array();
         foreach ($channelInfo as $c) {
             if ($c["depth"] == 0) {
                 $keywords[] = strtolower($c["title"]);
             }
         }
         // Add meta tags to the header.
         $this->addToHead("<meta name='keywords' content='" . sanitizeHTML(($k = C("esoTalk.meta.keywords")) ? $k : implode(",", $keywords)) . "'>");
         $lastKeyword = reset(array_splice($keywords, count($keywords) - 1, 1));
         $this->addToHead("<meta name='description' content='" . sanitizeHTML(($d = C("esoTalk.meta.description")) ? $d : sprintf(T("forumDescription"), C("esoTalk.forumTitle"), implode(", ", $keywords), $lastKeyword)) . "'>");
         // If this is not technically the homepage (if it's a search page) the we don't want it to be indexed.
         if ($searchString) {
             $this->addToHead("<meta name='robots' content='noindex, noarchive'>");
         }
         // Add JavaScript language definitions and variables.
         $this->addJSLanguage("Starred", "Unstarred", "gambit.member", "gambit.more results", "Filter conversations", "Jump to last");
         $this->addJSVar("searchUpdateInterval", C("esoTalk.search.updateInterval"));
         $this->addJSVar("currentSearch", $searchString);
         $this->addJSVar("currentChannels", $currentChannels);
         $this->addJSFile("core/js/lib/jquery.cookie.js");
         $this->addJSFile("core/js/autocomplete.js");
         $this->addJSFile("core/js/search.js");
         // Add an array of channels in the form slug => id for the JavaScript to use.
         $channels = array();
         foreach ($channelInfo as $id => $c) {
             $channels[$id] = $c["slug"];
         }
         $this->addJSVar("channels", $channels);
         // Get a bunch of statistics...
         $queries = array("post" => ET::SQL()->select("COUNT(*)")->from("post")->get(), "conversation" => ET::SQL()->select("COUNT(*)")->from("conversation")->get(), "member" => ET::SQL()->select("COUNT(*)")->from("member")->get());
         $sql = ET::SQL();
         foreach ($queries as $k => $query) {
             $sql->select("({$query}) AS {$k}");
         }
         $stats = $sql->exec()->firstRow();
         // ...and show them in the footer.
         foreach ($stats as $k => $v) {
             $stat = Ts("statistic.{$k}", "statistic.{$k}.plural", number_format($v));
             if ($k == "member" and (C("esoTalk.members.visibleToGuests") or ET::$session->user)) {
                 $stat = "<a href='" . URL("members") . "'>{$stat}</a>";
             }
             $this->addToMenu("statistics", "statistic-{$k}", $stat, array("before" => "statistic-online"));
         }
         $this->render("conversations/index");
     } elseif ($this->responseType === RESPONSE_TYPE_VIEW) {
         $this->render("conversations/results");
     } elseif ($this->responseType === RESPONSE_TYPE_AJAX) {
         $this->json("channels", $this->getViewContents("channels/tabs", $this->data));
         $this->render("conversations/results");
     } elseif ($this->responseType === RESPONSE_TYPE_JSON) {
         $this->json("results", $results);
         $this->render();
     }
 }
Пример #8
0
 public function handler_membersController_constructGambitsMenu($controller, &$gambits)
 {
     $model = ET::getInstance("profileFieldModel");
     $fields = $model->get(array("searchable" => 1));
     $gambits["profile"] = array();
     foreach ($fields as $field) {
         addToArrayString($gambits["profile"], mb_strtolower($field["name"], "UTF-8") . ": ?", array("gambit-profile-" . $field["fieldId"]), 1);
     }
 }
Пример #9
0
 /**
  * Add a separator item to this menu collection.
  *
  * @param mixed $position The position to put the menu item, relative to other menu items.
  * @see addToArrayString
  * @return void
  */
 public function separator($position = false)
 {
     addToArrayString($this->items, count($this->items) + 1, "separator", $position);
 }
 /**
  * Show the member list page.
  *
  * @param string $orderBy What to sort the members by.
  * @param mixed $start Where to start the results from. This can be:
  * 		- An integer, in which case it will be used as a numerical offset.
  * 		- pX, where X is the "page" number.
  * 		- A letter to start from, if $orderBy is "name".
  * @return void
  */
 public function action_index($orderBy = false, $start = 0)
 {
     if (!$this->allowed("esoTalk.members.visibleToGuests")) {
         return;
     }
     // Begin constructing a query to fetch results.
     $sql = ET::SQL()->from("member m");
     // If we've limited results by a search string...
     if ($searchString = R("search")) {
         // Explode separate terms by the plus character.
         $terms = explode("+", $searchString);
         // Get an array of all groups which we can possibly filter by.
         $groups = ET::groupModel()->getAll();
         $groups[GROUP_ID_ADMINISTRATOR] = array("name" => ACCOUNT_ADMINISTRATOR);
         $groups[GROUP_ID_MEMBER] = array("name" => ACCOUNT_MEMBER);
         $groups[GROUP_ID_GUEST] = array("name" => ACCOUNT_SUSPENDED);
         $conditions = array();
         $this->trigger("parseTerms", array(&$terms, $sql, &$conditions));
         foreach ($terms as $k => $term) {
             $term = mb_strtolower(trim($term), "UTF-8");
             if (!$term) {
                 continue;
             }
             $thisCondition = array();
             // If the search string matches the start of any group names, then we'll filter members by their account/group.
             $group = false;
             foreach ($groups as $id => $g) {
                 $name = $g["name"];
                 if (strpos(mb_strtolower(T("group.{$name}", $name), "UTF-8"), $term) === 0 or strpos(mb_strtolower(T("group.{$name}.plural", $name), "UTF-8"), $term) === 0) {
                     $group = $id;
                     break;
                 }
             }
             // Did we find any matching groups just before? If so, add a WHERE condition to the query to filter by group.
             if ($group !== false) {
                 if ($group < 0) {
                     $thisCondition[] = "account=:account{$k}";
                     $sql->bind(":account{$k}", $groups[$group]["name"]);
                 } elseif (!$groups[$group]["private"] or ET::groupModel()->groupIdsAllowedInGroupIds(ET::$session->getGroupIds(), $group, true)) {
                     $sql->from("member_group mg", "mg.memberId=m.memberId", "left");
                     $thisCondition[] = "mg.groupId=:group{$k}";
                     $sql->bind(":group{$k}", $group);
                 }
             }
             // Also perform a normal LIKE search.
             $thisCondition[] = "username LIKE :search{$k}";
             $sql->bind(":search{$k}", "%" . $term . "%");
             $conditions[] = "(" . implode(" OR ", $thisCondition) . ")";
         }
         $sql->where(implode(" AND ", $conditions));
     }
     // Create a query to get the total number of results. Clone the results one to retain the same WHERE conditions.
     $count = clone $sql;
     $count = $count->select("COUNT(m.memberId)")->exec()->result();
     // Make an array of possible orders for the list.
     $orders = array("name" => array(T("Name"), "username ASC"), "posts" => array(T("Posts"), "countPosts DESC"), "activity" => array(T("Last active"), "lastActionTime DESC"));
     // If an invalid orderBy key was provided, just use the first one.
     if (!isset($orders[$orderBy])) {
         $orderBy = reset(array_keys($orders));
     }
     // Work out where to start the results from.
     $page = 0;
     if ($start) {
         // If we're ordering by name and the start argument is a single letter...
         if ($orderBy == "name" and strlen($start) == 1 and ctype_alpha($start)) {
             // Run a query to get the position of the first member starting with this letter.
             $start = ET::SQL()->select("COUNT(memberId)", "position")->from("member")->where("STRCMP(username, :username) = -1")->bind(":username", $start)->exec()->result();
             $start = min($count - C("esoTalk.members.membersPerPage"), $start);
         } elseif ($start[0] == "p") {
             $page = ltrim($start, "p");
             $start = C("esoTalk.members.membersPerPage") * ($page - 1);
         } else {
             $start = (int) $start;
             $page = round($start / C("esoTalk.members.membersPerPage"));
         }
         // Apply the offset to the query.
         $start = max(0, $start);
         $sql->offset($start);
     }
     // Finish constructing the query. We want to get a list of member IDs to show as the results.
     $ids = $sql->select("m.memberId")->limit(C("esoTalk.members.membersPerPage"))->orderBy($orders[$orderBy][1])->exec()->allRows();
     foreach ($ids as &$id) {
         $id = $id["memberId"];
     }
     // Finally, fetch the member data for the members with these IDs.
     if ($ids) {
         $members = ET::memberModel()->getByIds($ids);
     } else {
         $members = array();
     }
     // If we're ordering by last active, filter out members who have opted out of being displayed on the online list.
     if ($orderBy == "activity") {
         foreach ($members as $k => $member) {
             if (!empty($member["preferences"]["hideOnline"])) {
                 unset($members[$k]);
             }
         }
     }
     // If we're doing a normal page load...
     if ($this->responseType === RESPONSE_TYPE_DEFAULT) {
         // Set the title and make sure this page isn't indexed.
         $this->title = T("Member List");
         $this->addToHead("<meta name='robots' content='noindex, noarchive'/>");
         // Work out the canonical URL for this page.
         $url = "members/{$orderBy}/p{$page}";
         $this->canonicalURL = URL($url, true);
         $this->pushNavigation("members", "members", URL($url));
         // Add JavaScript files and variables for the page to use.
         $this->addJSFile("core/js/scrubber.js");
         $this->addJSFile("core/js/members.js");
         $this->addJSVar("membersPerPage", C("esoTalk.members.membersPerPage"));
         $this->addJSVar("countMembers", $count);
         $this->addJSVar("startFrom", $start);
         $this->addJSVar("searchString", $searchString);
         $this->addJSVar("orderBy", $orderBy);
         $this->addJSLanguage("Sort By");
         // Add the default gambits to the gambit cloud: gambit text => css class to apply.
         $gambits = array("groups" => array(T("group.administrator.plural") => array("gambit-group-administrator", "icon-wrench"), T("group.member.plural") => array("gambit-group-member", "icon-user"), T("group.suspended") => array("gambit-group-suspended", "icon-shield")));
         $groups = ET::groupModel()->getAll();
         foreach ($groups as $group) {
             if ($group["private"]) {
                 continue;
             }
             $name = $group["name"];
             addToArrayString($gambits["groups"], T("group.{$name}.plural", ucfirst($name)), array("gambit-group-{$name}", "icon-tag"), 1);
         }
         $this->trigger("constructGambitsMenu", array(&$gambits));
         // Construct the gambits menu based on the above arrays.
         $gambitsMenu = ETFactory::make("menu");
         $linkPrefix = "members/" . $orderBy . "/?search=";
         foreach ($gambits as $section => $items) {
             foreach ($items as $gambit => $classes) {
                 $gambitsMenu->add($classes[0], "<a href='" . URL($linkPrefix . urlencode($gambit)) . "' class='{$classes[0]}' data-gambit='{$gambit}'>" . (!empty($classes[1]) ? "<i class='{$classes[1]}'></i> " : "") . "{$gambit}</a>");
             }
             end($gambits);
             if ($section !== key($gambits)) {
                 $gambitsMenu->separator();
             }
         }
         $this->data("gambitsMenu", $gambitsMenu);
     }
     // Pass data to the view.
     $this->data("members", $members);
     $this->data("countMembers", $count);
     $this->data("startFrom", $start);
     $this->data("searchString", $searchString);
     $this->data("orders", $orders);
     $this->data("orderBy", $orderBy);
     // On an AJAX request, just render the list, and also pass back the startFrom position.
     if ($this->responseType === RESPONSE_TYPE_AJAX) {
         $this->json("startFrom", $start);
         $this->render("members/list");
     } else {
         $this->render("members/index");
     }
 }
Пример #11
0
 public function handler_conversationsController_constructGambitsMenu($sender, &$gambits)
 {
     if (!ET::$session->user) {
         return;
     }
     addToArrayString($gambits["main"], T("gambit.bookmarked"), array("gambit-bookmarked", "icon-bookmark"));
 }