/** * This is the ending point of the page library. * * @access public * @param null * @return null */ public function end($options = array()) { // Initialize required dependencies. FD::document()->init($options); $processStylesheets = isset($options['processStylesheets']) ? $options['processStylesheets'] : true; // @task: Process any scripts that needs to be injected into the head. if ($processStylesheets) { $this->processStylesheets(); } // @task: Process any scripts that needs to be injected into the head. $this->processScripts(); // @task: Process the document title. $this->processTitle(); // @task: Process opengraph tags FD::opengraph()->render(); // @task: Trigger profiler's end. if ($this->config->get('general.profiler')) { FD::profiler()->end(); } // Additional triggers to be processed when the page starts. // $dispatcher = FD::dispatcher(); // Trigger: onComponentStart // $dispatcher->trigger('user', 'onComponentEnd', array()); }
/** * Formats a stream item with the necessary data. * * Example: * <code> * </code> * * @since 1.0 * @access public * @param Array * */ public function format($items, $context = 'all', $viewer = null, $loadCoreAction = true, $defaultEvent = 'onPrepareStream', $options = array()) { // Get the current user $my = is_null($viewer) ? FD::user() : FD::user($viewer); // Basic display options $commentLink = isset($options['commentLink']) && $options['commentLink'] || !isset($options['commentLink']) ? true : false; $commentForm = isset($options['commentForm']) && $options['commentForm'] || !isset($options['commentForm']) ? true : false; // Default the event to onPrepareStream if (!$defaultEvent) { $defaultEvent = 'onPrepareStream'; } // Determines if this is a stream $isStream = false; if ($defaultEvent == 'onPrepareStream') { $isStream = true; } // If there's no items, skip formatting this because it's pointless to run after this. if (!$items) { return $items; } // Prepare default data $data = array(); $activeUser = FD::user(); // Get stream model $model = FD::model('Stream'); //current user being view. $targetUser = JRequest::getInt('id', ''); if (empty($targetUser)) { $targetUser = $my->id; } if ($targetUser && strpos($targetUser, ':')) { $tmp = explode(':', $targetUser); $targetUser = $tmp[0]; } // Get template configuration $templateConfig = FD::themes()->getConfig(); // Get the site configuration $config = FD::config(); // Link options // We only have to do this once instead of putting inside the loop. $linkOptions = array('target' => '_blank'); if ($config->get('stream.content.nofollow')) { $linkOptions['rel'] = 'nofollow'; } // Format items with appropriate objects. foreach ($items as &$row) { // Get the uid $uid = $row->id; // Get the last updated time $lastupdate = $row->modified; // Determines if this is a cluster $isCluster = $row->cluster_id ? true : false; // Obtain related activities for aggregation. $relatedActivities = null; if ($isStream) { $relatedActivities = $model->getRelatedActivities($uid, $row->context_type, $viewer); } else { $relatedActivities = $model->getActivityItem($uid); } $aggregatedData = $this->buildAggregatedData($relatedActivities); // Get the stream item. $streamItem = new SocialStreamItem(); if (isset($row->isNew)) { $streamItem->isNew = $row->isNew; } // Set the state $streamItem->state = $row->state; // Set the actors (Aggregated actors ) $streamItem->actors = $aggregatedData->actors; // Set the edited value $streamItem->edited = isset($row->edited) ? $row->edited : false; // Set the content $streamItem->content = $row->content; $streamItem->content_raw = $row->content; // Set the title of the stream item. $streamItem->title = $row->title; // Set the targets (Aggregated targets ) $streamItem->targets = $aggregatedData->targets; // Set the aggregated items here so 3rd party can manipulate the data. $streamItem->aggregatedItems = $relatedActivities; $streamItem->contextIds = $aggregatedData->contextIds; // Set the context params. ( Aggregated params ) $streamItem->contextParams = $aggregatedData->params; // main stream params $streamItem->params = $row->params; // Set the stream uid / activity id. $streamItem->uid = $uid; // Set stream lapsed time $streamItem->lapsed = FD::date($row->created)->toLapsed(); $streamItem->created = FD::date($row->created); // Set the actor with the user object. $streamItem->actor = FD::user($row->actor_id); // Set the context id. $streamItem->contextId = $aggregatedData->contextIds[0]; // Set the verb for this item. $streamItem->verb = $aggregatedData->verbs[0]; // Set the context type. $streamItem->context = $row->context_type; // stream display type $streamItem->display = $row->stream_type; // stream cluster_id $streamItem->cluster_id = $row->cluster_id; // stream cluster_type $streamItem->cluster_type = $row->cluster_type; // stream cluster_type $streamItem->cluster_access = $row->cluster_access; // stream privacy access $streamItem->access = $row->access; // stream privacy access $streamItem->custom_access = $row->custom_access; // Define an empty color $streamItem->color = ''; // Define an empty favicon $streamItem->icon = ''; // Always enable labels $streamItem->label = true; $streamItem->custom_label = ''; $streamItem->opengraph = FD::opengraph(); // Determines if this stream item has been bookmarked by the viewer $streamItem->bookmarked = false; if ($row->bookmarked) { $streamItem->bookmarked = true; } // Determines if this stream item has been bookmarked by the viewer $streamItem->sticky = false; if ($row->sticky) { $streamItem->sticky = true; } // @TODO: Since our stream has a unique favi on for each item. We need to get it here. // Each application is responsible to override this favicon, or stream wil use the context type. $streamItem->favicon = $row->context_type; $streamItem->type = $row->context_type; $streamDateDisplay = $templateConfig->get('stream_datestyle'); $streamItem->friendlyDate = $streamItem->lapsed; if ($streamDateDisplay == 'datetime') { $streamItem->friendlyDate = $streamItem->created->toFormat($templateConfig->get('stream_dateformat_format', 'Y-m-d H:i')); } // getting the the with and mention tagging for the stream, only if the item is a stream. $streamItem->with = array(); $streamItem->mention = array(); if ($isStream) { $streamItem->with = $this->getStreamTagWith($uid); $streamItem->tags = $this->getTags($uid); } // Format the mood if (!empty($row->mood_id)) { $mood = FD::table('Mood'); $mood->id = $row->md_id; $mood->namespace = $row->md_namespace; $mood->namespace_uid = $row->md_namespace_uid; $mood->icon = $row->md_icon; $mood->verb = $row->md_verb; $mood->subject = $row->md_subject; $mood->custom = $row->md_custom; $mood->text = $row->md_text; $mood->user_id = $row->md_user_id; $mood->created = $row->md_created; $streamItem->mood = $mood; } // Format the users that are tagged in this stream. if (!empty($row->location_id)) { $location = FD::table('Location'); //$location->load( $row->location_id ); // lets assign the values into location jtable. $location->id = $row->loc_id; $location->uid = $row->loc_uid; $location->type = $row->loc_type; $location->user_id = $row->loc_user_id; $location->created = $row->loc_created; $location->short_address = $row->loc_short_address; $location->address = $row->loc_address; $location->latitude = $row->loc_latitude; $location->longitude = $row->loc_longitude; $location->params = $row->loc_params; $streamItem->location = $location; } // target user. this target user is different from the targets. this is the user who are being viewed currently. $streamItem->targetUser = $targetUser; // privacy $streamItem->privacy = null; // Check if the content is not empty. We need to perform some formatings if (isset($streamItem->content) && !empty($streamItem->content)) { $content = $streamItem->content; // Format mentions $content = $this->formatMentions($streamItem); // Apply e-mail replacements $content = FD::string()->replaceEmails($content); // Apply bbcode $content = FD::string()->parseBBCode($content, array('escape' => false, 'links' => true, 'code' => true)); // Some app might want the raw contents $streamItem->content_raw = $streamItem->content; $streamItem->content = $content; } // Stream meta $streamItem->meta = ''; if (!empty($streamItem->with) || !empty($streamItem->location) || !empty($streamItem->mood)) { $theme = FD::themes(); $theme->set('stream', $streamItem); $streamItem->meta = $theme->output('site/stream/meta'); } // Determines if the stream item is deleteable $streamItem->deleteable = false; // Determines if the stream item is editable $streamItem->editable = false; // Group stream should allow cluster admins to delete if ($streamItem->cluster_id) { $cluster = FD::cluster($streamItem->cluster_type, $streamItem->cluster_id); if ($cluster->isAdmin() || FD::user()->isSiteAdmin() || FD::user()->getAccess()->allowed('stream.delete', false) && FD::user()->id == $streamItem->actor->id) { $streamItem->deleteable = true; } } else { if (FD::user()->getAccess()->allowed('stream.delete', false) && FD::user()->id == $streamItem->actor->id) { $streamItem->deleteable = true; } } if (FD::user()->isSiteAdmin()) { $streamItem->deleteable = true; } // streams actions. $streamItem->comments = $defaultEvent == 'onPrepareStream' ? true : false; $streamItem->likes = $defaultEvent == 'onPrepareStream' ? true : false; $streamItem->repost = $defaultEvent == 'onPrepareStream' ? true : false; // @trigger onPrepareStream / onPrepareActivity $includePrivacy = $isCluster ? false : true; $result = $this->{$defaultEvent}($streamItem, $includePrivacy); // Allow app to stop loading / generating the stream and // if there is still no title, we need to skip this stream altogether. if ($result === false || !$streamItem->title) { continue; } // Set the plain content here. if (empty($streamItem->opengraph->properties['description'])) { $streamItem->opengraph->addDescription(strip_tags($streamItem->content)); } // This mean the plugin did not set any privacy. lets use the stream / activity. if (is_null($streamItem->privacy) && !$isCluster) { $privacyObj = FD::privacy($activeUser->id); $privacy = isset($row->privacy) ? $row->privacy : null; $pUid = $uid; $tmpStreamId = $defaultEvent == 'onPrepareActivityLog' ? $row->uid : $row->id; $sModel = FD::model('Stream'); $aItem = $sModel->getActivityItem($tmpStreamId, 'uid'); if (count($streamItem->contextIds) == 1 && is_null($privacy)) { if ($aItem) { $pUid = $aItem[0]->id; } } if (!$privacyObj->validate('core.view', $pUid, SOCIAL_TYPE_ACTIVITY, $streamItem->actor->id)) { continue; } $tmpStreamId = $streamItem->aggregatedItems[0]->uid; if ($defaultEvent == 'onPrepareActivityLog') { $tmpStreamId = count($aItem) > 1 ? '' : $tmpStreamId; } $streamItem->privacy = $privacyObj->form($pUid, SOCIAL_TYPE_ACTIVITY, $streamItem->actor->id, null, false, $tmpStreamId); } $itemGroup = $streamItem->cluster_id ? $streamItem->cluster_type : SOCIAL_APPS_GROUP_USER; if ($streamItem->display != SOCIAL_STREAM_DISPLAY_MINI) { $canComment = true; // comments if (isset($streamItem->comments) && $streamItem->comments) { if (!$streamItem->comments instanceof SocialCommentBlock) { $streamItem->comments = FD::comments($streamItem->contextId, $streamItem->context, $streamItem->verb, $itemGroup, array('url' => FRoute::stream(array('layout' => 'item', 'id' => $streamItem->uid))), $streamItem->uid); } // for comments, we need to check against the actor privacy and see if the current viewer allow to // post comments on their stream items or not. if (!$isCluster) { $privacyObj = FD::privacy($activeUser->id); if (!$privacyObj->validate('story.post.comment', $streamItem->actor->id, SOCIAL_TYPE_USER)) { $canComment = false; } } } // Set comment option the streamid if ($streamItem->comments) { $streamItem->comments->setOption('streamid', $streamItem->uid); } // If comments link is meant to be disabled, hide it if (!$commentLink) { $streamItem->commentLink = false; } // If comments is meant to be disabled, hide it. if ($streamItem->comments && (isset($streamItem->commentForm) && !$streamItem->commentForm || !$commentForm || !$canComment)) { $streamItem->comments->setOption('hideForm', true); } //likes if (isset($streamItem->likes) && $streamItem->likes) { if (!$streamItem->likes instanceof SocialLikes) { $likes = FD::likes(); $likes->get($streamItem->contextId, $streamItem->context, $streamItem->verb, $itemGroup, $streamItem->uid); $streamItem->likes = $likes; } } //set likes option the streamid if ($streamItem->likes) { $streamItem->likes->setOption('streamid', $streamItem->uid); } // Build repost links if (isset($streamItem->repost) && $streamItem->repost) { if (!$streamItem->repost instanceof SocialRepost) { $repost = FD::get('Repost', $streamItem->uid, SOCIAL_TYPE_STREAM, $itemGroup); $streamItem->repost = $repost; } } // set cluseter into repost if ($isCluster && $streamItem->repost) { $streamItem->repost->setCluster($streamItem->cluster_id, $streamItem->cluster_type); } // Enable sharing on the stream if ($config->get('stream.sharing.enabled')) { if (!isset($streamItem->sharing) || isset($streamItem->sharing) && $streamItem->sharing !== false && !$streamItem->sharing instanceof SocialSharing) { $sharing = FD::get('Sharing', array('url' => FRoute::stream(array('layout' => 'item', 'id' => $streamItem->uid, 'external' => true), true), 'display' => 'dialog', 'text' => JText::_('COM_EASYSOCIAL_STREAM_SOCIAL'), 'css' => 'fd-small')); $streamItem->sharing = $sharing; } } // Now we have all the appropriate data, populate the actions $streamItem->actions = $this->getActions($streamItem); } else { $streamItem->comments = false; $streamItem->likes = false; $streamItem->repost = false; $streamItem->actions = ''; } // Re-assign stream item to the result list. $data[] = $streamItem; } // here we know, the result from queries contain some records but it might return empty data due to privacy. // if that is the case, then we return TRUE so that the library will go retrieve the next set of data. if (count($data) <= 0) { return true; } return $data; }
/** * Default method to display the group entry page. * * @since 1.2 * @access public * @author Mark Lee <*****@*****.**> */ public function item($tpl = null) { // Check if this feature is enabled. $this->checkFeature(); // Check for user profile completeness FD::checkCompleteProfile(); $id = $this->input->get('id', 0, 'int'); $group = FD::group($id); // Check if the group is valid if (!$id || !$group->id) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_GROUPS_GROUP_NOT_FOUND')); } // Ensure that the group is published if (!$group->isPublished()) { $this->setMessage(JText::_('COM_EASYSOCIAL_GROUPS_UNAVAILABLE'), SOCIAL_MSG_ERROR); FD::info()->set($this->getMessage()); return $this->redirect(FRoute::dashboard(array(), false)); } // Check if the group is accessible if ($group->isInviteOnly() && !$group->isMember() && !$group->isInvited() && !$this->my->isSiteAdmin()) { $this->setMessage(JText::_('COM_EASYSOCIAL_GROUPS_NOT_ALLOWED'), SOCIAL_MSG_ERROR); FD::info()->set($this->getMessage()); return $this->redirect(FRoute::dashboard(array(), false)); } // If the user is not the owner and the user has been blocked by the group creator if ($this->my->id != $group->creator_uid && $this->my->isBlockedBy($group->creator_uid)) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_GROUPS_GROUP_NOT_FOUND')); } // Set the page title. $this->page->title($group->getName()); // Set the breadcrumbs for the group $this->page->breadcrumb(JText::_('COM_EASYSOCIAL_GROUPS_PAGE_TITLE'), FRoute::groups()); $this->page->breadcrumb($group->getName()); $this->set('group', $group); if (($group->isInviteOnly() || $group->isClosed()) && !$group->isMember() && !$this->my->isSiteAdmin()) { // Display private group contents; return parent::display('site/groups/restricted'); } // Update the hit counter $group->hit(); // Get the start limit $startlimit = $this->input->get('limitstart', 0, 'int'); // Get the context $context = $this->input->get('app', '', 'cmd'); // Get group's filter for this logged in user. $filters = $group->getFilters($this->my->id); // Get a list of application filters $streamModel = FD::model('Stream'); $appFilters = $streamModel->getAppFilters(SOCIAL_TYPE_GROUP); $this->set('context', $context); $this->set('filters', $filters); $this->set('appFilters', $appFilters); // Load list of apps for this group $model = FD::model('Apps'); // Retrieve apps $apps = $model->getGroupApps($group->id); // We need to load the app's own css file. foreach ($apps as $app) { $app->loadCss(); } $this->set('apps', $apps); $appId = $this->input->get('appId', 0, 'int'); $contents = ''; $isAppView = false; if ($appId) { // Load the application. $app = FD::table('App'); $app->load($appId); $app->loadCss(); FD::page()->title($group->getName() . ' - ' . $app->get('title')); FD::page()->breadcrumb($app->get('title')); // Load the library. $lib = FD::apps(); $contents = $lib->renderView(SOCIAL_APPS_VIEW_TYPE_EMBED, 'groups', $app, array('groupId' => $group->id)); $isAppView = true; } $this->set('appId', $appId); // Determines if we should display the custom content based on type. $type = $this->input->get('type', '', 'cmd'); if (!$isAppView && empty($type)) { $type = FD::config()->get('groups.item.display', 'timeline'); } $filterId = $this->input->get('filterId', 0, 'int'); if ($type == 'filterForm') { $theme = FD::themes(); $streamFilter = FD::table('StreamFilter'); if ($filterId) { $streamFilter->load($filterId); } $theme->set('controller', 'groups'); $theme->set('filter', $streamFilter); $theme->set('uid', $group->id); $contents = $theme->output('site/stream/form.edit'); } if ($type == 'info') { FD::language()->loadAdmin(); $currentStep = JRequest::getInt('step', 1); $steps = FD::model('Steps')->getSteps($group->category_id, SOCIAL_TYPE_CLUSTERS, SOCIAL_GROUPS_VIEW_DISPLAY); $fieldsLib = FD::fields(); $fieldsLib->init(array('privacy' => false)); $fieldsModel = FD::model('Fields'); $index = 1; foreach ($steps as $step) { $step->fields = $fieldsModel->getCustomFields(array('step_id' => $step->id, 'data' => true, 'dataId' => $group->id, 'dataType' => SOCIAL_TYPE_GROUP, 'visible' => SOCIAL_GROUPS_VIEW_DISPLAY)); if (!empty($step->fields)) { $args = array($group); $fieldsLib->trigger('onDisplay', SOCIAL_FIELDS_GROUP_GROUP, $step->fields, $args); } $step->hide = true; foreach ($step->fields as $field) { // As long as one of the field in the step has an output, then this step shouldn't be hidden // If step has been marked false, then no point marking it as false again // We don't break from the loop here because there is other checking going on if (!empty($field->output) && $step->hide === true) { $step->hide = false; } } if ($index === 1) { $step->url = FRoute::groups(array('layout' => 'item', 'id' => $group->getAlias(), 'type' => 'info'), false); } else { $step->url = FRoute::groups(array('layout' => 'item', 'id' => $group->getAlias(), 'type' => 'info', 'infostep' => $index), false); } $step->title = $step->get('title'); $step->active = !$step->hide && $currentStep == $index; if ($step->active) { $theme = FD::themes(); $theme->set('fields', $step->fields); $contents = $theme->output('site/groups/item.info'); } $step->index = $index; $index++; } $this->set('infoSteps', $steps); } $this->set('type', $type); $this->set('filterId', $filterId); $this->set('contents', $contents); if (!empty($contents)) { return parent::display('site/groups/item'); } // If no content, only we get the stream. No point getting stream and contents at the same time. // Retrieve group's stream $stream = FD::stream(); // Determine if the current request is for "tags" $hashtag = $this->input->get('tag', 0); $hashtagAlias = $this->input->get('tag'); // If there's a hash tag, try to get the actual title to display on the site if ($hashtag) { $tag = $stream->getHashTag($hashtag); $hashtag = $tag->title; } // Retrieve story form for group $story = FD::get('Story', SOCIAL_TYPE_GROUP); $story->setCluster($group->id, SOCIAL_TYPE_GROUP); $story->showPrivacy(false); if ($hashtag) { $story->setHashtags(array($hashtag)); } // Only group members allowed to post story updates on group page. if ($group->isMember() || $this->my->isSiteAdmin()) { // Set the story data on the stream $stream->story = $story; // Get the group params $params = $group->getParams(); // Ensure that the user has permissions to see the story form $permissions = $params->get('stream_permissions', null); // If permissions has been configured before. if (!is_null($permissions)) { // If the user is not an admin, ensure that permissions has member if (!$group->isAdmin() && !in_array('member', $permissions)) { unset($stream->story); } // If the user is an admin, ensure that permissions has admin if ($group->isAdmin() && !in_array('admin', $permissions) && !$group->isOwner()) { unset($stream->story); } } } //lets get the sticky posts 1st $stickies = $stream->getStickies(array('clusterId' => $group->id, 'clusterType' => SOCIAL_TYPE_GROUP, 'limit' => 0)); if ($stickies) { $stream->stickies = $stickies; } // lets get stream items for this group $options = array('clusterId' => $group->id, 'clusterType' => SOCIAL_TYPE_GROUP, 'nosticky' => true); // stream filter id $filterId = $this->input->get('filterId', 0, 'int'); if ($filterId) { $sfilter = FD::table('StreamFilter'); $sfilter->load($filterId); $hashtags = $sfilter->getHashTag(); $tags = explode(',', $hashtags); if ($tags) { $options['tag'] = $tags; } } // we only wan streams thats has this hashtag associated. if ($hashtag) { $options['tag'] = array($hashtag); } $options['startlimit'] = $startlimit; // Filter stream item by specific context type if ($context) { $options['context'] = $context; } if ($type == 'moderation') { $options['onlyModerated'] = true; unset($stream->story); } $stream->get($options); // Apply opengraph tags for the group. FD::opengraph()->addGroup($group); $this->set('context', $context); $this->set('stream', $stream); $this->set('hashtag', $hashtag); $this->set('hashtagAlias', $hashtagAlias); parent::display('site/groups/item'); }
/** * Displays a user profile to a 3rd person perspective. * * @since 1.0 * @access public * @param null * @return null **/ public function display($tpl = null) { // Get the user's id. $id = $this->input->get('id', 0, 'int'); // The current logged in user might be viewing their own profile. if ($id == 0) { $id = FD::user()->id; } // When the user tries to view his own profile but if he isn't logged in, throw a login page. if ($id == 0) { return FD::requireLogin(); } // Check for user profile completeness FD::checkCompleteProfile(); // Get the user's object. $user = FD::user($id); // If the user still don't exist, throw a 404 if (!$user->id) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } if (Foundry::user()->id != $user->id) { if (FD::user()->isBlockedBy($user->id)) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } } if ($user->isBlock()) { FD::info()->set(JText::sprintf('COM_EASYSOCIAL_PROFILE_USER_NOT_EXIST', $user->getName()), SOCIAL_MSG_ERROR); return $this->redirect(FRoute::dashboard(array(), false)); } // Set the page title FD::page()->title(FD::string()->escape($user->getName())); // Set the page breadcrumb FD::page()->breadcrumb(FD::string()->escape($user->getName())); // Apply opengraph tags. FD::opengraph()->addProfile($user); // Get the current logged in user's object. $my = FD::user(); // Do not assign badge if i view myself. if ($user->id != $my->id && $my->id) { // @badge: profile.view $badge = FD::badges(); $badge->log('com_easysocial', 'profile.view', $my->id, JText::_('COM_EASYSOCIAL_PROFILE_VIEWED_A_PROFILE')); } $startlimit = JRequest::getInt('limitstart', 0); // Determine if the current request is to load an app $appId = JRequest::getInt('appId'); // Get site configuration $config = FD::config(); // Get the apps library. $appsLib = FD::apps(); $contents = ''; if ($appId) { // Load the app $app = FD::table('App'); $app->load($appId); // Check if the user has access to this app if (!$app->accessible($user->id)) { FD::info()->set(null, JText::_('COM_EASYSOCIAL_PROFILE_APP_IS_NOT_INSTALLED_BY_USER'), SOCIAL_MSG_ERROR); return $this->redirect(FRoute::profile(array('id' => $user->getAlias()), false)); } // Set the page title FD::page()->title(FD::string()->escape($user->getName()) . ' - ' . $app->get('title')); $contents = $appsLib->renderView(SOCIAL_APPS_VIEW_TYPE_EMBED, 'profile', $app, array('userId' => $user->id)); } $layout = JRequest::getCmd('layout'); // @since 1.3.7 // If layout is empty, means we want to get the default view // Previously timeline is always the default if (empty($appId) && empty($layout)) { $defaultDisplay = FD::config()->get('users.profile.display', 'timeline'); $layout = $defaultDisplay; } if ($layout === 'about') { FD::language()->loadAdmin(); $currentStep = JRequest::getInt('step', 1); $steps = FD::model('Steps')->getSteps($user->profile_id, SOCIAL_TYPE_PROFILES, SOCIAL_PROFILES_VIEW_DISPLAY); $fieldsLib = FD::fields(); $fieldsModel = FD::model('Fields'); $index = 1; foreach ($steps as $step) { $step->fields = $fieldsModel->getCustomFields(array('step_id' => $step->id, 'data' => true, 'dataId' => $user->id, 'dataType' => SOCIAL_TYPE_USER, 'visible' => SOCIAL_PROFILES_VIEW_DISPLAY)); if (!empty($step->fields)) { $args = array($user); $fieldsLib->trigger('onDisplay', SOCIAL_FIELDS_GROUP_USER, $step->fields, $args); } $step->hide = true; foreach ($step->fields as $field) { // As long as one of the field in the step has an output, then this step shouldn't be hidden // If step has been marked false, then no point marking it as false again // We don't break from the loop here because there is other checking going on if (!empty($field->output) && $step->hide === true) { $step->hide = false; } } if ($index === 1) { $step->url = FRoute::profile(array('id' => $user->getAlias(), 'layout' => 'about'), false); } else { $step->url = FRoute::profile(array('id' => $user->getAlias(), 'layout' => 'about', 'step' => $index), false); } $step->title = $step->get('title'); $step->active = !$step->hide && $currentStep == $index; if ($step->active) { $theme = FD::themes(); $theme->set('fields', $step->fields); $contents = $theme->output('site/events/item.info'); } $step->index = $index; $index++; } $this->set('infoSteps', $steps); } // If contents is still empty at this point, then we just get the stream items as the content if (empty($contents)) { // Mark timeline item as the active one $this->set('timeline', true); // Retrieve user's stream $theme = FD::themes(); // Get story $story = FD::get('Story', SOCIAL_TYPE_USER); $story->target = $user->id; $stream = FD::stream(); $stream->get(array('userId' => $user->id, 'startlimit' => $startlimit)); if (FD::user()->id) { // only logged in user can submit story. $stream->story = $story; } // Set stream to theme $theme->set('stream', $stream); $contents = $theme->output('site/profile/default.stream'); } $this->set('contents', $contents); $privacy = $my->getPrivacy(); // Let's test if the current viewer is allowed to view this profile. if ($my->id != $user->id) { if (!$privacy->validate('profiles.view', $user->id, SOCIAL_TYPE_USER)) { $this->set('user', $user); parent::display('site/profile/restricted'); return; } } // Get user's cover object $cover = $user->getCoverData(); $this->set('cover', $cover); // If we're setting a cover $coverId = JRequest::getInt('cover_id', null); if ($coverId) { // Load cover photo $newCover = FD::table('Photo'); $newCover->load($coverId); // If the cover photo belongs to the user if ($newCover->isMine()) { // Then allow replacement of cover $this->set('newCover', $newCover); } } $photosModel = FD::model('Photos'); $photos = array(); // $photos = $photosModel->getPhotos( array( 'uid' => $user->id ) ); // not using? it seems like no one is referencing this photos. $totalPhotos = 0; // Retrieve list of apps for this user $appsModel = FD::model('Apps'); $options = array('view' => 'profile', 'uid' => $user->id, 'key' => SOCIAL_TYPE_USER); $apps = $appsModel->getApps($options); // Set the apps lib $this->set('appsLib', $appsLib); $this->set('totalPhotos', $totalPhotos); $this->set('photos', $photos); $this->set('apps', $apps); $this->set('activeApp', $appId); $this->set('privacy', $privacy); $this->set('user', $user); // Load the output of the profile. echo parent::display('site/profile/default'); }
/** * Displays the photo item * * @since 1.0 * @access public */ public function item() { // Check if photos is enabled $this->checkFeature(); // Check for user profile completeness FD::checkCompleteProfile(); // Get current user $my = FD::user(); // Get the owner id and type $uid = JRequest::getInt('uid'); $type = JRequest::getWord('type'); // Get photo library $id = JRequest::getInt('id', null); $lib = FD::photo($uid, $type, $id); if ($lib->isblocked()) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PHOTOS_DELETED')); } // If id is not given or photo does not exist if (!$id || !$lib->data->id) { return $this->deleted($lib); } // Set the opengraph data for this photo FD::opengraph()->addImage($lib->data->getSource()); // Get the album's library $album = $lib->album(); // Set the page title. $title = $lib->getPageTitle($this->getLayout()); FD::page()->title($title); // Set the breadcrumbs $lib->setBreadcrumbs($this->getLayout()); // Determines if the photo is viewable or not. if (!$lib->viewable()) { return $this->restricted($lib); } // Assign a badge for the user $lib->data->assignBadge('photos.browse', $my->id); // Render options $options = array('viewer' => $my->id, 'size' => SOCIAL_PHOTOS_LARGE, 'showNavigation' => true); // We want to display the comments. $options['showResponse'] = true; $options['resizeUsingCss'] = false; $options['resizeMode'] = 'contain'; // Render the photo output $output = $lib->renderItem($options); return $this->output($lib, $output); }
/** * Displays a user profile to a 3rd person perspective. * * @since 1.0 * @access public * @param null * @return null **/ public function display($tpl = null) { // Get the user's id. $id = $this->input->get('id', 0, 'int'); // Check if there is any stream filtering or not. $filter = $this->input->get('type', '', 'word'); // The current logged in user might be viewing their own profile. if ($id == 0) { $id = FD::user()->id; } // When the user tries to view his own profile but if he isn't logged in, throw a login page. if ($id == 0) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } // Check for user profile completeness FD::checkCompleteProfile(); // Get the user's object. $user = FD::user($id); // If the user doesn't exist throw an error if (!$user->id) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } // If the user is blocked or the user doesn't have community access if ($this->my->id != $user->id && $this->my->isBlockedBy($user->id) || !$user->hasCommunityAccess()) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } // If the user is blocked, they should not be accessible if ($user->isBlock()) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_PROFILE_INVALID_USER')); } // Set the page properties $this->page->title($this->string->escape($user->getName())); $this->page->breadcrumb($this->string->escape($user->getName())); // Get the current user's privacy object $privacy = $this->my->getPrivacy(); // Let's test if the current viewer is allowed to view this profile. if ($this->my->id != $user->id && !$privacy->validate('profiles.view', $user->id, SOCIAL_TYPE_USER)) { $this->set('user', $user); return parent::display('site/profile/restricted'); } // Apply opengraph tags. FD::opengraph()->addProfile($user); // Do not assign badge if i view myself. if ($user->id != $this->my->id && $this->my->id) { // @badge: profile.view $badge = FD::badges(); $badge->log('com_easysocial', 'profile.view', $this->my->id, JText::_('COM_EASYSOCIAL_PROFILE_VIEWED_A_PROFILE')); } // Get the limit start $startLimit = $this->input->get('limitstart', 0, 'int'); // Determine if the current request is to load an app $appId = $this->input->get('appId', 0, 'int'); // Get the apps library. $appsLib = FD::apps(); // Default contents $contents = ''; // Load the app when necessary if ($appId) { $app = FD::table('App'); $app->load($appId); // Check if the user has access to this app if (!$app->accessible($user->id)) { FD::info()->set(false, JText::_('COM_EASYSOCIAL_PROFILE_APP_IS_NOT_INSTALLED_BY_USER'), SOCIAL_MSG_ERROR); $redirect = FRoute::profile(array('id' => $user->getAlias()), false); return $this->redirect($redirect); } // Set the page title $this->page->title(FD::string()->escape($user->getName()) . ' - ' . $app->get('title')); // Render the app contents $contents = $appsLib->renderView(SOCIAL_APPS_VIEW_TYPE_EMBED, 'profile', $app, array('userId' => $user->id)); } // Get the layout $layout = $this->input->get('layout', '', 'cmd'); // @since 1.3.7 // If layout is empty, means we want to get the default view // Previously timeline is always the default if (empty($appId) && empty($layout) && $filter != 'appFilter') { $defaultDisplay = $this->config->get('users.profile.display', 'timeline'); $layout = $defaultDisplay; } // Default variables $timeline = null; $newCover = false; // Viewing info of a user. if ($layout === 'about') { $showTimeline = false; $usersModel = FD::model('Users'); $steps = $usersModel->getAbout($user); // We should generate a canonical link if user is viewing the about section and the default page is about if ($this->config->get('users.profile.display') == 'about') { $this->page->canonical($user->getPermalink(false, true)); } if ($steps) { foreach ($steps as $step) { if ($step->active) { $theme = FD::themes(); $theme->set('fields', $step->fields); $contents = $theme->output('site/events/item.info'); } } } $this->set('infoSteps', $steps); } // Should we filter stream items by specific app types $appType = $this->input->get('filterid', '', 'string'); // If contents is still empty at this point, then we just get the stream items as the content if (empty($contents) || $filter == 'appFilter') { // Should the timeline be active $timeline = true; // Retrieve user's stream $theme = FD::themes(); // Get story $story = FD::story(SOCIAL_TYPE_USER); $story->target = $user->id; // Get the stream $stream = FD::stream(); //lets get the sticky posts 1st $stickies = $stream->getStickies(array('userId' => $user->id, 'limit' => 0)); if ($stickies) { $stream->stickies = $stickies; } $streamOptions = array('userId' => $user->id, 'nosticky' => true, 'startlimit' => $startLimit); if ($filter == 'appFilter') { $timeline = false; $streamOptions['actorId'] = $user->id; } if ($appType) { $streamOptions['context'] = $appType; // Should this be set now or later $stream->filter = 'custom'; } $stream->get($streamOptions); // Only registered users can access the story form if (!$this->my->guest) { $stream->story = $story; } // Set stream to theme $theme->set('stream', $stream); $contents = $theme->output('site/profile/default.stream'); } // Get user's cover object $cover = $user->getCoverData(); // If we're setting a cover $coverId = $this->input->get('cover_id', 0, 'int'); // Load cover photo if ($coverId) { $coverTable = FD::table('Photo'); $coverTable->load($coverId); // If the cover photo belongs to the user if ($coverTable->isMine()) { $newCover = $coverTable; } } $streamModel = FD::model('Stream'); // Get a list of application filters $appFilters = $streamModel->getAppFilters(SOCIAL_TYPE_USER); // Retrieve list of apps for this user $appsModel = FD::model('Apps'); $options = array('view' => 'profile', 'uid' => $user->id, 'key' => SOCIAL_TYPE_USER); $apps = $appsModel->getApps($options); $this->set('appFilters', $appFilters); $this->set('filterId', $appType); $this->set('timeline', $timeline); $this->set('newCover', $newCover); $this->set('cover', $cover); $this->set('contents', $contents); $this->set('appsLib', $appsLib); $this->set('apps', $apps); $this->set('activeApp', $appId); $this->set('privacy', $privacy); $this->set('user', $user); // Load the output of the profile. return parent::display('site/profile/default'); }
/** * Displays the event item page. * * @author Jason Rey <*****@*****.**> * @since 1.3 * @access public */ public function item() { // Check if events is enabled. $this->checkFeature(); // Check for profile completeness FD::checkCompleteProfile(); // Get the event id $id = $this->input->get('id', 0, 'int'); // Load up the event $event = FD::event($id); // Set the default redirect url $defaultRedirect = FRoute::events(array(), false); if (empty($event) || empty($event->id)) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_EVENTS_INVALID_EVENT_ID')); } if (!$event->isPublished()) { FD::info()->set(false, JText::_('COM_EASYSOCIAL_EVENTS_EVENT_UNAVAILABLE'), SOCIAL_MSG_ERROR); return $this->redirect($defaultRedirect); } // Determines if the current user is a guest of this event $guest = $event->getGuest($this->my->id); if (!$this->my->isSiteAdmin() && $event->isInviteOnly() && !$guest->isParticipant()) { FD::info()->set(false, JText::_('COM_EASYSOCIAL_EVENTS_NO_ACCESS_TO_EVENT'), SOCIAL_MSG_ERROR); return $this->redirect($defaultRedirect); } // check if the current logged in user blocked by the event creator or not. if ($this->my->id != $event->creator_uid) { if (FD::user()->isBlockedBy($event->creator_uid)) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_EVENTS_EVENT_UNAVAILABLE')); } } // Support for group event // If user is not a group member, then redirect to group page if ($event->isGroupEvent()) { $group = FD::group($event->getMeta('group_id')); if (!$this->my->isSiteAdmin() && !$group->isMember()) { FD::info()->set(false, JText::_('COM_EASYSOCIAL_GROUPS_EVENTS_NO_PERMISSION_TO_VIEW_EVENT'), SOCIAL_MSG_ERROR); return $this->redirect($group->getPermalink()); } $this->set('group', $group); } // Append additional opengraph details $opengraph = FD::opengraph(); $opengraph->addUrl($event->getPermalink(true, true)); $opengraph->addType('article'); $opengraph->addTitle($event->getName()); $opengraph->addDescription($event->getDescription()); $opengraph->addImage($event->getAvatar()); // render the meta tags here. $opengraph->render(); // Set the page title FD::page()->title($event->getName()); // Set the breadcrumbs FD::page()->breadcrumb(JText::_('COM_EASYSOCIAL_PAGE_TITLE_EVENTS'), FRoute::events()); FD::page()->breadcrumb($event->getName()); $this->set('guest', $guest); $this->set('event', $event); if (!$this->my->isSiteAdmin() && !$event->isOpen() && !$guest->isGuest() && (!$event->isGroupEvent() || $event->isGroupEvent() && !$event->getGroup()->isMember())) { return parent::display('site/events/restricted'); } // Increment the hit counter $event->hit(); // stream pagination $startlimit = JRequest::getInt('limitstart', 0); // Filter stream item by specific context type $context = $this->input->get('app', '', 'cmd'); $this->set('context', $context); // Get a list of filters $filters = $event->getFilters($this->my->id); $this->set('filters', $filters); // Load up the stream model $streamModel = FD::model('Stream'); $appFilters = $streamModel->getAppFilters(SOCIAL_TYPE_EVENT); $this->set('appFilters', $appFilters); // Get all apps for the event $appsModel = FD::model('Apps'); $apps = $appsModel->getEventApps($event->id); // Load css files for the apps foreach ($apps as $app) { $app->loadCss(); } $contents = ''; $isAppView = false; // Determines if the current page is loading a specific app item $appId = $this->input->get('appId', 0, 'int'); if ($appId) { $app = FD::table('App'); $app->load($appId); $app->loadCss(); FD::page()->title($event->getName() . ' - ' . $app->get('title')); $appsLib = FD::apps(); $contents = $appsLib->renderView(SOCIAL_APPS_VIEW_TYPE_EMBED, 'events', $app, array('eventId' => $event->id)); $isAppView = true; } // Type can be info or timeline // If type is info, then we load the info tab first instead of showing timleine first $type = $this->input->get('type', '', 'cmd'); // @since 1.3.7 // If type is empty, means we want to get the default view // Previously timeline is always the default if (!$isAppView && empty($type)) { $type = FD::config()->get('events.item.display', 'timeline'); } // Determines if the current request is to filter specific items $filterId = $this->input->get('filterId', 0, 'int'); // Load Stream filter table $streamFilter = FD::table('StreamFilter'); if ($filterId) { $streamFilter->load($filterId); } $this->set('filterId', $filterId); // If the current view is to display filters form if ($type == 'filterForm' && $guest->isGuest()) { $theme = FD::themes(); $theme->set('controller', 'events'); $theme->set('filter', $streamFilter); $theme->set('uid', $event->id); $contents = $theme->output('site/stream/form.edit'); } if ($type == 'info') { FD::language()->loadAdmin(); $currentStep = JRequest::getInt('step', 1); $steps = FD::model('Steps')->getSteps($event->category_id, SOCIAL_TYPE_CLUSTERS, SOCIAL_EVENT_VIEW_DISPLAY); $fieldsLib = FD::fields(); $fieldsLib->init(array('privacy' => false)); $fieldsModel = FD::model('Fields'); $index = 1; foreach ($steps as $step) { $step->fields = $fieldsModel->getCustomFields(array('step_id' => $step->id, 'data' => true, 'dataId' => $event->id, 'dataType' => SOCIAL_TYPE_EVENT, 'visible' => SOCIAL_EVENT_VIEW_DISPLAY)); if (!empty($step->fields)) { $args = array($event); $fieldsLib->trigger('onDisplay', SOCIAL_FIELDS_GROUP_EVENT, $step->fields, $args); } $step->hide = true; foreach ($step->fields as $field) { // As long as one of the field in the step has an output, then this step shouldn't be hidden // If step has been marked false, then no point marking it as false again // We don't break from the loop here because there is other checking going on if (!empty($field->output) && $step->hide === true) { $step->hide = false; } } if ($index === 1) { $step->url = FRoute::events(array('layout' => 'item', 'id' => $event->getAlias(), 'type' => 'info'), false); } else { $step->url = FRoute::events(array('layout' => 'item', 'id' => $event->getAlias(), 'type' => 'info', 'infostep' => $index), false); } $step->title = $step->get('title'); $step->active = !$step->hide && $currentStep == $index; if ($step->active) { $theme = FD::themes(); $theme->set('fields', $step->fields); $contents = $theme->output('site/events/item.info'); } $step->index = $index; $index++; } $this->set('infoSteps', $steps); } $this->set('appId', $appId); $this->set('apps', $apps); $this->set('type', $type); $this->set('contents', $contents); if (!empty($contents)) { return parent::display('site/events/item'); } // If no content then only we proceed to get the stream $stream = FD::stream(); //lets get the sticky posts 1st $stickies = $stream->getStickies(array('clusterId' => $event->id, 'clusterType' => $event->cluster_type, 'limit' => 0)); if ($stickies) { $stream->stickies = $stickies; } $streamOptions = array('clusterId' => $event->id, 'clusterType' => $event->cluster_type, 'nosticky' => true); // Load the story $story = FD::story($event->cluster_type); $story->setCluster($event->id, $event->cluster_type); $story->showPrivacy(false); // Determines if this is a hashtag $hashtag = $this->input->get('tag', 0, 'int'); $hashtagAlias = $this->input->get('tag', '', 'default'); if (!empty($hashtag)) { $tag = $stream->getHashTag($hashtag); if (!empty($tag->id)) { $this->set('hashtag', $tag->title); $this->set('hashtagAlias', $hashtagAlias); $story->setHashtags(array($tag->title)); $streamOptions['tag'] = array($tag->title); } } if (!empty($streamFilter->id)) { $tags = $streamFilter->getHashtag(); $tags = explode(',', $tags); $streamOptions['tag'] = $tags; } if ($guest->isGuest()) { $stream->story = $story; } $streamOptions['startlimit'] = $startlimit; if ($context) { $streamOptions['context'] = $context; } $stream->get($streamOptions); $this->set('stream', $stream); parent::display('site/events/item'); }
/** * Displays the album item * * @since 1.0 * @access public */ public function item() { // Check for user profile completeness FD::checkCompleteProfile(); // Check if photos is enabled $this->checkFeature(); // Retrieve the album from request $id = $this->input->get('id', 0, 'int'); // Get the unique id and type $uid = $this->input->get('uid', 0, 'int'); $type = $this->input->get('type', SOCIAL_TYPE_USER, 'string'); // If id is provided but UID is not provided, probably they created a menu that links to a single album if ($id && !$uid) { $album = FD::table('Album'); $album->load($id); if (!$album->id) { return $this->deleted(); } $uid = $album->uid; $type = $album->type; } if ($type == SOCIAL_TYPE_USER && $uid) { if (FD::user()->id != $uid) { if (FD::user()->isBlockedBy($uid)) { return JError::raiseError(404, JText::_('COM_EASYSOCIAL_ALBUMS_INVALID_USER_PROVIDED')); } } } // Load up the albums library $lib = FD::albums($uid, $type, $id); // Determines if the viewer is trying to view albums for a valid node. if (!$lib->isValidNode()) { $this->setMessage($lib->getError(), SOCIAL_MSG_ERROR); $this->info->set($this->getMessage()); $this->redirect(FRoute::dashboard(array(), false)); $this->close(); } // Empty id or invalid id is not allowed. if (!$id || !$lib->data->id) { return $this->deleted(); } // Check if the album is viewable $viewable = $lib->viewable(); if (!$viewable) { return $this->restricted($lib->data->uid, $lib->data->type); } // Increment the hit of the album $lib->data->addHit(); // Get a list of photos within this album $photos = $lib->getPhotos($lib->data->id); $photos = $photos['photos']; // Set the opengraph data for photos within this album if ($photos) { foreach ($photos as $photo) { FD::opengraph()->addImage($photo->getSource()); } } // Set page title $title = $lib->getPageTitle($this->getLayout()); FD::page()->title($title); // Set the breadcrumbs $lib->setBreadcrumbs($this->getLayout()); // Render options $options = array('viewer' => $this->my->id); // Render item $output = $lib->renderItem($options); return $this->output($uid, $type, $output, $lib->data); }
/** * Wraps the provided album * * @since 1.0 * @access public */ public function renderItem($options = array()) { $album = $this->data; // Determine if album is passed in options if (isset($options['album'])) { $album = $options['album']; } // Set the default settings for opening photos in a popup $config = FD::config(); $this->renderItemOptions['photoItem']['openInPopup'] = $config->get('photos.popup.default'); // Built preset options $presetOptions = array('canUpload' => $this->canUpload()); // Normalize render options $options = array_merge($this->renderItemOptions, $presetOptions, $options); if (!empty($options['photoItem'])) { $options['photoItem'] = array_merge($this->renderItemOptions['photoItem'], $options['photoItem']); } // Inherit photo item's viewer from album if it is not given if (empty($options['photoItem']['viewer'])) { $options['photoItem']['viewer'] = $options['viewer']; } // Set the layout for the photo $options['photoItem']['layout'] = $options['layout']; // Photos cannot be uploaded to core albums if ($album->core) { $options['canUpload'] = false; } // Get album privacy // @TODO: Get proper album privacy $privacy = FD::privacy(); // Get album creator $creator = FD::user($album->user_id); // Get album viewer $viewer = FD::user($options['viewer']); // Get the photo options $photoOptions = array(); if ($options['limit'] !== 'auto') { $photoOptions['limit'] = $options['limit']; } //privacy if (isset($options['privacy'])) { $photoOptions['privacy'] = $options['privacy']; } // Get album phtoos $photos = $album->getPhotos($photoOptions); // // Add opengraph data for each photos if ($photos['photos']) { foreach ($photos['photos'] as $photo) { FD::opengraph()->addImage($photo->getSource()); } } // Get album likes $likes = FD::likes($album->id, SOCIAL_TYPE_ALBUM, 'create', SOCIAL_APPS_GROUP_USER); // Get album shares $shares = FD::get('Repost', $album->id, SOCIAL_TYPE_ALBUM, SOCIAL_APPS_GROUP_USER); // Get album comments $comments = FD::comments($album->id, SOCIAL_TYPE_ALBUM, 'create', SOCIAL_APPS_GROUP_USER, array('url' => $album->getPermalink())); // Get a list of tags from this album $tags = $album->getTags(true); // Build the user alias $userAlias = $creator->getAlias(); // Generate item layout $theme = FD::themes(); // Determines if the current document is RTL $rtl = $this->doc->getDirection() == 'rtl' ? true : false; $theme->set('rtl', $rtl); $theme->set('lib', $this); $theme->set('options', $options); $theme->set('userAlias', $userAlias); $theme->set('album', $album); $theme->set('tags', $tags); $theme->set('creator', $creator); $theme->set('privacy', $privacy); $theme->set('likes', $likes); $theme->set('shares', $shares); $theme->set('comments', $comments); $theme->set('photos', $photos['photos']); $theme->set('nextStart', $photos['nextStart']); return $theme->output('site/albums/item'); }