/** * Assign a stream to be associated with category * @default is 'Uncategorized'; * @param mixed category is the identifier of the category * @param int $stream_id is the id of the stream to be assigned to */ public function assign($category, $stream_id) { $table = $this->load(array('category' => $category)); $this->id = $table->id; $this->stream_id = JXUtility::csvInsert($table->stream_id, $stream_id); return $this->store(); }
/** * Basic message read permission */ public function allowRead($userid) { // If private, only the group member can access if ($this->data->access) { $my = JXFactory::getUser(); $userGroups = $my->getParam('groups_member'); // added condition to allow also siteadmin and superuser to read the private group content return JXUtility::csvExist($userGroups, $this->data->group_id) || $my->isAdmin(); } return true; }
public function display($cachable = false, $urlparams = false) { // Only admin can use this function to invite guests $jxConfig = new JXConfig(); $mainframe = JFactory::getApplication(); $my = JXFactory::getUser(); $email = JRequest::getVar('email', ''); $token = JRequest::getString('token', ''); $code = JRequest::getString('code', ''); $userInviteTable = JTable::getInstance('usersInvite', 'AccountTable'); $userInviteTable->load(array('invite_email' => $email, 'status' => AccountTableUsersInvite::PENDING, 'token' => $token)); if ($userInviteTable->id) { if ($_POST) { $name = JRequest::getVar('name', ''); $username = JRequest::getVar('username', ''); $password1 = JRequest::getString('password', ''); $password2 = JRequest::getString('confirm_password', ''); $data = array('name' => $name, 'username' => $username, 'password' => $password1, 'conf_pass' => $password2, 'email' => $email, 'group_limited' => $userInviteTable->group_limited); $model = RegisterFactory::getModel('registration'); if ($userid = $model->registerUser($data)) { $userInviteTable->status = AccountTableUsersInvite::REGISTERED; $userInviteTable->store(); // If user is invited to a certain group only, add the user into the group if ($userInviteTable->group_limited) { // Include tables JTable::addIncludePath(JPATH_ROOT . DS . 'components' . DS . 'com_stream' . DS . 'tables'); $groups = explode(',', $userInviteTable->group_limited); $user = JXFactory::getUser($userid); foreach ($groups as $group_id) { $group = $group = JTable::getInstance('Group', 'StreamTable'); $group->load($group_id); // If you join, you'd also follow it $group->members = JXUtility::csvInsert($group->members, $user->id); $group->followers = JXUtility::csvInsert($group->followers, $user->id); $group->store(); // Store user cache $groupList = $user->getParam('groups_member'); $groupList = JXUtility::csvInsert($groupList, $group->id); $user->setParam('groups_member', $groupList); $user->save(); } } $mainframe->redirect(JURI::base(), JText::_('COM_REGISTER_MSG_REGISTRATION_SUCCESSFUL')); } else { $mainframe->enqueueMessage($model->getError(), 'error'); } } parent::display(); } else { $mainframe->redirect(JURI::base(), JText::_('COM_REGISTER_ERRMSG_NO_VALID_INVITATION'), 'error'); } }
public function getTrending($group = null) { $db = JFactory::getDbo(); $my = JXFactory::getUser(); $groupModel = StreamFactory::getModel('groups'); $now = new JXDate(); $nowDate = $now->format('Y-m-d'); // Get the week's top trending tags //$where = 'WHERE YEARWEEK(' . $db->nameQuote('occurrence_date') . ') = YEARWEEK(' . $db->Quote($nowDate) . ')' . ' ' // Get the trending tags for the past n weeks $where = 'WHERE ' . $db->nameQuote('occurrence_date') . ' BETWEEN DATE_SUB(' . $db->Quote($nowDate) . ', INTERVAL 2 WEEK) AND ' . $db->Quote($nowDate) . ' ' . ' AND ' . $db->nameQuote('frequency') . ' > 0' . ' '; // Filter tags in group if (!is_null($group)) { $where .= 'AND ' . $db->nameQuote('group_id') . ' = ' . $db->Quote($group->id) . ' '; } else { // Get the groups joined (including private ones) $groupIJoinCsv = $my->getParam('groups_member', '-1'); // Get the other public groups $otherGroups = $groupModel->getGroups(array('!id' => $groupIJoinCsv, 'access' => 0), 100); $otherGroupsCsv = '0'; if (count($otherGroups)) { foreach ($otherGroups as $group) { $otherGroupsCsv = JXUtility::csvInsert($otherGroupsCsv, $group->id); } } else { $otherGroupsCsv = '-1'; } $myGroupsCsv = JXUtility::csvMerge($otherGroupsCsv, $groupIJoinCsv); $where .= 'AND ' . $db->nameQuote('group_id') . ' IN (' . $myGroupsCsv . ')' . ' '; } // Build the query $query = 'SELECT * FROM ' . $db->nameQuote('#__stream_tags_trend') . ' ' . $where . 'GROUP BY ' . $db->nameQuote('tag') . ' ' . 'ORDER BY ' . $db->nameQuote('frequency') . ' DESC, ' . $db->nameQuote('tag') . ' ASC' . ' ' . 'LIMIT 10'; $db->setQuery($query); $result = $db->loadObjectList(); return $result; }
/** * Delete a message */ public function delete() { $my = JXFactory::getUser(); $message_id = JRequest::getVar('message_id'); $stream = JTable::getInstance('Stream', 'StreamTable'); $stream->load($message_id); if (!$my->authorise('stream.message.delete', $stream)) { // No reason this code would ever get here! exit; } // Remove trending tags data $tagsTrend = new StreamTag(); $rawData = json_decode($stream->raw); $rawData->tags = isset($rawData->tags) ? $rawData->tags : ''; $tagsArray = explode(',', trim($rawData->tags, ',')); foreach ($tagsArray as $tag) { // trim hashes $tag = trim($tag, '#'); // remove trending data $tagsTrend->updateTrending($tag, $stream->group_id, false); } $stream->delete(); // Delete related comments StreamComment::deleteComments($message_id); // Unattach all files $user = JXFactory::getUser($stream->user_id); $links = StreamMessage::getLinks($stream->message); if (!empty($links)) { $userLinks = $user->getParam('links'); foreach ($links as $row) { $link = JTable::getInstance('Link', 'StreamTable'); $link->load(array('link' => $row)); $link->removeUser($user->id); $link->store(); $userLinks = JXUtility::csvRemove($userLinks, $link->id); } $user->setParam('links', $userLinks); $user->save(); } // @todo: delete attachments // Upgrade group stats if necessary if (JRequest::getVar('group_id')) { $group = JTable::getInstance('Group', 'StreamTable'); $group->load(JRequest::getVar('group_id')); $group->setParam('message_count', $streamModel->countStream(array('group_id' => $group->id))); $group->setParam($stream->type . '_count', $streamModel->countStream(array('group_id' => $group->id, 'type' => $stream->type))); $group->store(); } $data = array(); $data['id'] = $message_id; header('Content-Type: text/json'); echo json_encode($data); exit; }
public static function sendDirectMessageNew() { $funcArgs = func_get_args(); // Get notification type from caller $notificationType = $funcArgs[0]; // Get the group table object from passed in parameter $groupTable = $funcArgs[1]; // Get the stream object from passed in parameter $streamTable = $funcArgs[2]; // Get actor (current login user) $actor = JXFactory::getUser(); if ($groupTable instanceof JTable) { if (self::sentNotificationCheck($notificationType, $actor->id, $streamTable->id) === false) { // Process Members and Followers to merged into UserList $groupMembers = $groupTable->get('members'); $groupFollowers = $groupTable->get('followers'); $processUserList = explode(',', JXUtility::csvMerge($groupMembers, $groupFollowers)); $userList = self::groupUserByLanguage($processUserList, $actor->id, $notificationType); $messageUrl = '#'; $arrParam = array('streamMessage' => $streamTable, 'sender' => $actor); $jConfig = new JConfig(); foreach ($userList as $lang => $bccEmail) { self::loadLanguage($lang); $subject = JText::sprintf('COM_STREAM_NOTIFICATION_PROFILE_POST_DIRECT_SUBJECT', $actor->name); $bodyContent = self::getHeaderContent(JText::_('COM_STREAM_NOTIFICATION_DIRECT_POST_TITLE'), $messageUrl); $bodyContent .= self::getBodyContent('notification.direct', $arrParam); $bodyContent .= self::getFooterContent(); self::sendMail($jConfig->mailfrom, $jConfig->fromname, $jConfig->mailfrom, $subject, $bodyContent, $bccEmail); } } } }
<?php if ($group->isMember($my->id) || $my->isAdmin()) { if ($group->archived) { ?> <div class="alert-message block-message warning group-filter"> <p>This group has been archived. You can no longer leave a message in this group. An achived group simply mean that this group is no longer active and has either completed its objectives</p> </div> <?php } else { // Allow only group members to see the stream.post box $userGroups = $my->getParam('groups_member'); if (JXUtility::csvExist($userGroups, $group->id)) { if (JRequest::getVar('template') != 'mobile') { $tmpl = new StreamTemplate(); echo $tmpl->set('title', "title")->set('group_id', $group->id)->fetch('stream.post'); } } } } ?> <script type="text/javascript"> $(function() { /* Follow group */ $('a[href="#followGroup"]').click(function() { $.ajax({ type: "POST", url: S.path['group.follow'], data: $('form[name="group-actions"]').serialize(), dataType: 'json',
public function notification() { $my = JXFactory::getUser(); $data = array(); // No notification for guest. Trigger a logout in user's browser if (!$my->id) { $data['logout'] = true; echo json_encode($data); exit; } include_once JPATH_LIBRARIES . DS . 'joomla' . DS . 'html' . DS . 'html' . DS . 'string.php'; $phash = JRequest::getVar('pHash'); // public data cache hash $data['notification'] = array(); $data['comments'] = array(); $data['updates'] = array(); // Get my groups $streamModel = StreamFactory::getModel('stream'); $groupsModel = StreamFactory::getModel('groups'); $groupIJoin = $my->getParam('groups_member'); $groupIFollow = $my->getParam('groups_follow'); $myGroups = JXUtility::csvMerge($groupIFollow, $groupIJoin); $myGroups = $groupsModel->getGroups(array('id' => $myGroups)); // Get public notices $lastMessageRead = $my->getParam('message_last_read'); $publicCount = StreamMessage::countMessageSince($lastMessageRead); $data['notification']['company_updates'] = $publicCount; // we can merge this request with the group request so that template are fetched on the same loop but the group content is unique to each group // @todo: optimize the whole request $publicMessageContents = $streamModel->getStream(array('group_id' => 0), $publicCount); $publicMessagesHTML = '<ul>'; foreach ($publicMessageContents as $row) { $tmpl = new StreamTemplate(); $tmpl->set('stream', $row); $publicMessagesHTML .= $tmpl->fetch('notification.message'); $data['updates'][0]['message_id'][] = $row->id; } $publicMessagesHTML .= '</ul>'; $data['data_content'][0] = $publicMessagesHTML; $data['updates'][0]['name'] = 'public'; $data['updates'][0]['notification'] = $publicCount; $data['updates'][0]['content'] = $publicMessagesHTML; // @todo: this is kinda heavy. Optimize further. Otherwise the live update // will kill us $updatedGroups = array(); $updatedGroupsComment = array(); foreach ($myGroups as $group) { $lastReadId = $my->getParam('group_' . $group->id . '_read'); $lastCommentId = $my->getParam('group_' . $group->id . '_comment'); $groupLastMsg = $group->getParam('last_message'); $groupLastComment = $group->getParam('last_comment'); $groupNewMsg = $streamModel->countStream(array('!user_id' => $my->id, 'id_more' => $lastReadId, 'group_id' => $group->id)); $groupNewComment = $streamModel->countComments(array('group_id' => $group->id, 'id_more' => $lastCommentId)); // // the array key is the same as html id element of the <span> that // will take this value $data['notification']['groups_' . $group->id] = intval($groupNewMsg); // rand ( 0 , 20 ); $data['comments']['groups_' . $group->id] = intval($groupNewComment); // rand ( 0 , 20 ); $data['updates'][$group->id]['name'] = $group->name; $data['updates'][$group->id]['notification'] = intval($groupNewMsg); $data['updates'][$group->id]['comments'] = intval($groupNewComment); // Add popover data if ($groupNewMsg > 0) { $updatedGroups[] = $group; } if ($groupNewComment > 0) { $updatedGroupsComment[] = $group; } } // Get the popover data if necessary // This is done saperately to give opportunity for caching if (md5(serialize($data['notification']) . serialize($data['comments'])) != $phash) { if (!empty($updatedGroups)) { foreach ($updatedGroups as $group) { $limit = $data['notification']['groups_' . $group->id]; $newMessages = $streamModel->getStream(array('group_id' => $group->id), $limit); $newMessagesHTML = '<ul>'; foreach ($newMessages as $row) { $tmpl = new StreamTemplate(); $tmpl->set('stream', $row); $newMessagesHTML .= $tmpl->fetch('notification.message'); } $newMessagesHTML .= '</ul>'; $data['data_content']['#groups_' . $group->id . '_link'] = $newMessagesHTML; $data['updates'][$group->id]['content'] = $newMessagesHTML; } } /* if(!empty($updatedGroupsComment)){ foreach($updatedGroupsComment as $group) { $data['data_comment']['#groups_'.$group->id.'_link'] = ''; } } */ } if ($phash == md5(serialize($data['notification']) . serialize($data['comments']))) { $data['data_content'] = array(); $data['notification'] = array(); $data['comments'] = array(); $data['updates'] = array(); } $data['pHash'] = md5(serialize($data['notification']) . serialize($data['comments'])); header('Content-Type: text/json'); echo json_encode($data); exit; }
}*/ ?> <?php foreach ($rows as $stream) { $my = JXFactory::getUser(); $user = JXFactory::getUser($stream->user_id); $data = json_decode($stream->raw); $date = new JDate($stream->created); $members = array(); if (!empty($stream->group_id)) { $group = $stream->getGroup(); // Message sent to $memberIds = $group->members; $memberIds = explode(',', trim($memberIds, ',')); $memberCount = JXUtility::csvCount($group->members); if ($memberCount > 1) { foreach ($memberIds as $id) { if (intval($id) > 0 && $id != $group->creator) { $member = JXFactory::getUser($id); $members[] = '<a href="' . $member->getURL() . '">' . $this->escape($member->name) . '</a>'; } } } else { $members[] = 'Yourself'; } } ?> <li class="direct-list-item"> <div class="direct-avatar"> <a href="<?php
/** * Return true if the user is allowed to download it */ public function allowDownload($userid) { // If this is a group, and the group is private, only members can download it $my = JXFactory::getUser($userid); $limitGroup = $my->getParam('groups_member_limited'); if ($limitGroup) { return JXUtility::csvExist($limitGroup, $this->group_id); } if ($this->group_id) { $group = JTable::getInstance('Group', 'StreamTable'); $group->load($this->group_id); // People need to be able to read the group if (!$my->authorise('stream.group.read', $group)) { return false; } } return !empty($userid); }
// Only show list of groups if there is any if (!empty($myGroups)) { ?> <ul> <?php foreach ($myGroups as $group) { ?> <li class="<?php if ($group_id == $group->id) { echo 'active'; } ?> "> <?php $lastReadId = $my->getParam('group_' . $group->id . '_read'); $statusClass = JXUtility::csvExist($groupIJoin, $group->id) ? 'joined' : 'followed'; $groupLastMsg = $group->getParam('last_message'); $groupNewMsg = 0; // Only calculate if there is a diff here if ($lastReadId != $groupLastMsg) { $groupNewMsg = $streamModel->countStream(array('!user_id' => $my->id, 'id_more' => $lastReadId, 'group_id' => $group->id)); } $styleHide = ''; ?> <a class="<?php echo $statusClass; ?> " id="groups_<?php echo $group->id; ?>
function display($tpl = null) { include_once JPATH_LIBRARIES . DS . 'joomla' . DS . 'html' . DS . 'html' . DS . 'string.php'; $name = JRequest::getString('user'); $userId = JUserHelper::getUserId($name); $user = JXFactory::getUser($userId); $my = JXFactory::getUser(); $lastStatus = $user->getStatus(); $task = JRequest::getVar('task', 'activities'); $this->addPathway(JText::_('NAVIGATOR_LABEL_PEOPLE'), JRoute::_('index.php?option=com_people&view=members')); $this->addPathway($user->name); $doc = JFactory::getDocument(); // Add attachment script $doc->addScript(JURI::root() . 'media/uploader/fileuploader.js'); $doc->addStyleSheet(JURI::root() . 'media/uploader/fileuploader.css'); $groupsView = StreamFactory::getView('groups'); // $html = $groupsView->getUserGroupsHTML($userId); // JXModule::addBuffer('right', $html ); // this section is to get the group_type to set the twitter button's toggle $validGroupType = JAnalytics::getGroupType(); $analyticsGroupBy = JRequest::getVar('group_type', 'day'); $analyticIndex = array_search($analyticsGroupBy, $validGroupType); $analyticIndex = $analyticIndex === false ? 1 : $analyticIndex; $this->assignRef('user', $user); $this->assignRef('my', $my); $this->assignRef('analyticIndex', $analyticIndex); $this->assignRef('analyticType', $validGroupType); $this->assign('lastStatus', $lastStatus[0]->message); $this->assign('analyticHtml', $this->generateAnalytics($user)); switch ($task) { case 'activities': $companyView = StreamFactory::getView('company'); $filter = array(); $filter['user_id'] = $user->id; // Show only the user's stream $options = array(); $options['filter'] = 'stream.filter.profile'; $activities = $companyView->getStreamDataHTML($filter, $options); $this->assignRef('activities', $activities); break; case 'bio': // Bio JForm::addFieldPath(JPATH_COMPONENT . DS . 'models' . DS . 'fields'); $form = JForm::getInstance('form', JPATH_ROOT . DS . 'components' . DS . 'com_profile' . DS . 'models' . DS . 'forms' . DS . 'details.xml'); $detailModel = ProfileFactory::getModel('detail'); $form->bind(array('params' => $detailModel->getDetails($user->id))); $this->assignRef('form', $form); $this->assignRef('user', $user); break; case 'content': $this->assignRef('user', $user); $streamModel = StreamFactory::getModel('stream'); $blogs = $streamModel->getStream(array('type' => 'page', 'user_id' => $user->id), 10); $this->assign('blogs', $blogs); $this->assign('blogCount', $streamModel->countStream(array('type' => 'page', 'user_id' => $user->id))); $links = $user->getParam('links', ''); $linkModel = StreamFactory::getModel('links'); $links = $linkModel->getLinks(array('id' => $links, '!link' => ''), 10); $this->assignRef('links', $links); $this->assign('linkCount', JXUtility::csvCount($user->getParam('links'))); $fileModel = StreamFactory::getModel('files'); $files = $fileModel->getFiles(array('user_id' => $user->id), 10); $fileView = StreamFactory::getView('files'); $this->assignRef('fileView', $fileView); $this->assignRef('files', $files); $this->assign('fileCount', $fileModel->countFiles(array('user_id' => $user->id))); break; } //$document = JFactory::getDocument(); // $document->setTitle(JText::_('COM_PROFILE_LABEL_PROFILE_PAGE').': '.$user->name); $groupView = StreamFactory::getView('groups'); JXModule::addBuffer('right', $groupView->getUserActiveGroupsHTML($user->id)); // development $fileView = StreamFactory::getView('files'); JXModule::addBuffer('right', $fileView->modUserFilesHTML($user)); parent::display($tpl); }
/** * If it is private group, you can read, if you're a member */ public function allowRead($userid) { // If the user is limited by group, do not allow them to access group // beyond their assigned group $user = JXFactory::getUser($userid); $limitGroup = $user->getParam('groups_member_limited'); if ($limitGroup) { return JXUtility::csvExist($limitGroup, $this->id); } if (!$this->access) { return true; } $userGroups = $user->getParam('groups_member'); return JXUtility::csvExist($userGroups, $this->id); }
public function attachMessage($message_id) { $this->message_ids = JXUtility::csvInsert($this->message_ids, $message_id); }
function offiria_list_groups($groups, $title, $groupIJoin, $groupIFollow) { $group_id = JRequest::getVar('group_id'); $my = JXFactory::getUser(); $streamModel = StreamFactory::getModel('stream'); ?> <div class="groups-listing followed"> <h3><?php echo $title; ?> </h3> <?php // Only show list of groups if there is any if (!empty($groups)) { ?> <ul> <?php foreach ($groups as $group) { ?> <li class="groups <?php if ($group_id == $group->id) { echo 'active'; } ?> "> <?php $lastReadId = $my->getParam('group_' . $group->id . '_read'); $statusClass = JXUtility::csvExist($groupIJoin, $group->id) ? 'joined' : 'followed'; $groupLastMsg = $group->getParam('last_message'); $groupNewMsg = 0; // Only calculate if there is a diff here if ($lastReadId != $groupLastMsg) { $groupNewMsg = $streamModel->countStream(array('!user_id' => $my->id, 'id_more' => $lastReadId, 'group_id' => $group->id)); } $styleHide = ''; ?> <a class="<?php echo $statusClass; ?> " id="groups_<?php echo $group->id; ?> _link" href="<?php echo JRoute::_('index.php?option=com_stream&view=groups&task=show&group_id=' . $group->id); ?> "><?php echo StreamTemplate::escape($group->name); ?> </a> <?php if (intval($groupNewMsg) == 0) { $styleHide = 'display:none'; } echo '<span style="' . $styleHide . '" class="navigator-notice" id="groups_' . $group->id . '">' . intval($groupNewMsg) . '</span>'; ?> <!-- <span class="navigator-notice"></span> --> </li> <?php } ?> </ul> <?php } ?> </div> <?php }
public function getTaskCount() { $todoIds = $this->data->getParam('todo'); return JXUtility::csvCount($todoIds); }
/** * Return true if the user can set the todo item as 'done' */ public function allowDone($userid) { // If the userid is the stream owner, allow it if ($this->data->user_id == $userid) { return true; } // If stream belong to a group and userid is a member of the group // allow it if (!empty($this->data->group_id)) { $user = JXFactory::getUser($userid); $userGroups = $user->getParam('groups_member'); return JXUtility::csvExist($userGroups, $this->data->group_id); } return false; }
public function removeUser($userid) { $this->user_ids = JXUtility::csvRemove($this->user_ids, $userid); }
/** * Show popup list of all followers */ public function followers() { $group = JTable::getInstance('Group', 'StreamTable'); $group->load(JRequest::getVar('group_id')); $followers = array(); $html = '<p>No one is following the group</p>'; $followers = JXUtility::csvDiff($group->followers, $group->members); if (JXUtility::csvCount($followers) > 0) { $html = '<ul>'; foreach ($items = explode(',', $followers) as $id) { $user = JXFactory::getUser($id); $html .= '<li>' . $user->name . '</li>'; } $html .= '</ul>'; } $data = array(); $data['html'] = $html; header('Content-Type: text/json'); echo json_encode($data); exit; }
<div class="group-module-members"> <span class="count-members"><strong><?php echo JXUtility::csvCount($group->members); ?> </strong> <?php echo JText::_('COM_STREAM_LABEL_MEMBERS'); ?> </span> <span class="count-followers"><a data-group_id="<?php echo $group->id; ?> " data-content="<?php echo StreamTemplate::escape($followersHtml); ?> " href="#showFollowers"><strong><?php echo JXUtility::csvCount(JXUtility::csvDiff($group->followers, $group->members)); ?> </strong> <?php echo JText::_('COM_STREAM_LABEL_FOLLOWERS'); ?> </a></span> </div> </div> <?php /*?> <div class="group-module-actions"> <form name="group-actions"> <?php if(!$group->isMember($my->id)) { ?> <?php if(!$group->isFollower($my->id)) { ?>
/** * Get the user joined and followed group IDs * @return string Comma-separated group IDs */ public function getMergedGroupIDs() { $groupIJoin = $this->getParam('groups_member'); $groupIFollow = $this->getParam('groups_follow'); return JXUtility::csvMerge($groupIFollow, $groupIJoin); }
/** * To mark the message as when advance action is applied * Blog: viewed * Video: viewed * Link: cliked * File: downloaded * @param int $user_id * @param int $item_id the id of the read item, for example files/message */ public function actionIsTaken($user_id = NULL, $item_id = NULL) { $jxuser = JXFactory::getUser(); $my = !$user_id ? $jxuser->id : $user_id; $items = json_decode($this->getParam('action_by_user'), true); // placeholder for previous value $readers = array(); // since the implementation of individual tracking comes later convert the previous int to json string if (!is_array($items)) { // store the previous data $readers[0] = $items; // because of array_merge, make sure we always provide and array to merge $items = array(); } // to enable tracking per unique item, (!IMPORTANT: id of 0 is general to the message) $params = $item_id ? $item_id : 0; $addUserToItem = isset($items[$params]) ? JXUtility::csvInsert($items[$params], $my) : $my; $readers[$params] = $addUserToItem; $readers = array_merge($items, $readers); // store the array of the reader based on item return $this->setParam('action_by_user', json_encode($readers)); }