diff options
Diffstat (limited to 'app/controllers/activityfeed.php')
| -rw-r--r-- | app/controllers/activityfeed.php | 193 |
1 files changed, 191 insertions, 2 deletions
diff --git a/app/controllers/activityfeed.php b/app/controllers/activityfeed.php index 2f93aa1..ee83826 100644 --- a/app/controllers/activityfeed.php +++ b/app/controllers/activityfeed.php @@ -53,7 +53,7 @@ class ActivityfeedController extends AuthenticatedController unset($modules[Context::INSTITUTE]['participants']); unset($modules[Context::INSTITUTE]['schedule']); - $standard_plugins = PluginManager::getInstance()->getPlugins("StandardPlugin"); + $standard_plugins = PluginManager::getInstance()->getPlugins(StandardPlugin::class); foreach ($standard_plugins as $plugin) { if ($plugin instanceof ActivityProvider) { $modules[Context::COURSE][$plugin->getPluginName()] = $plugin->getPluginName(); @@ -67,7 +67,7 @@ class ActivityfeedController extends AuthenticatedController 'blubber' => _('Blubber'), ]; - $homepage_plugins = PluginEngine::getPlugins('HomepagePlugin'); + $homepage_plugins = PluginEngine::getPlugins(HomepagePlugin::class); foreach ($homepage_plugins as $plugin) { if ($plugin->isActivated($GLOBALS['user']->id, 'user')) { if ($plugin instanceof ActivityProvider) { @@ -92,4 +92,193 @@ class ActivityfeedController extends AuthenticatedController PageLayout::setTitle(_('Aktivitäten konfigurieren')); } + + public function load_action(): void + { + $user = User::findCurrent(); + + // failsafe einbauen - falls es keine älteren Aktivitäten mehr im System gibt, Abbruch! + + $oldest_activity = \Studip\Activity\Activity::getOldestActivity(); + $max_age = $oldest_activity ? $oldest_activity->mkdate : time(); + + + $contexts = []; + + // create system context + $system_context = new \Studip\Activity\SystemContext($user); + $contexts[] = $system_context; + + $contexts[] = new \Studip\Activity\UserContext($user, $user); + $user->contacts->each(function ($another_user) use (&$contexts, $user) { + $contexts[] = new \Studip\Activity\UserContext($another_user, $user); + }); + + if (!in_array($user->perms, ['admin','root'])) { + // create courses and institutes context + foreach (\Course::findMany($user->course_memberships->pluck('seminar_id')) as $course) { + $contexts[] = new \Studip\Activity\CourseContext($course, $user); + } + foreach (\Institute::findMany($user->institute_memberships->pluck('institut_id')) as $institute) { + $contexts[] = new \Studip\Activity\InstituteContext($institute, $user); + } + } + + + // add filters + $filter = new \Studip\Activity\Filter(); + + $start = Request::int('start', strtotime('yesterday')); + $end = Request::int('end', time()); + + + $scrollfrom = Request::int('scrollfrom', false); + $filtertype = Request::get('filtertype', ''); + + $objectType = Request::get('object_type'); + $filter->setObjectType($objectType); + + $objectId = Request::get('object_id'); + $filter->setObjectId($objectId); + + $context = Request::get('context_type'); + $filter->setContext($context); + + $contextId = Request::get('context_id'); + $filter->setContextId($contextId); + + if (!empty($filtertype)) { + $filter->setType(json_decode($filtertype)); + } + + if ($scrollfrom) { + // shorten "watch-window" by one second to prevent duplication of activities + $scrollfrom -= 1; + + if ($scrollfrom > $max_age){ + $end = $scrollfrom; + $start = strtotime('yesterday', $end); + $data = []; + + $backtrack = 1; + + while (empty($data)) { + $filter->setStartDate($start); + $filter->setEndDate($end); + + $data = $this->getStreamData($contexts, $filter); + + if ($start < $max_age) { + break; + } + + // move "watch-window" back one day at a time + $end = $start - 1; + $start = strtotime("-{$backtrack} days", $start); + + // enforce maximum "watch-window", currently 2 weeks + $backtrack = min(14, $backtrack + 1); + } + } else { + $data = false; + } + } else { + $filter->setStartDate($start); + $filter->setEndDate($end); + $data = $this->getStreamData($contexts, $filter); + } + + // set etag for preventing resending the same stuff over and over again + $etag = md5(serialize($data)); + $this->response->add_header('ETag', '"' . $etag . '"'); + if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $this->etagMatches($etag, $_SERVER['HTTP_IF_NONE_MATCH'])) { + $this->set_status(304); + $this->render_nothing(); + return; + } + if (isset($_SERVER['HTTP_IF_MATCH']) && !$this->etagMatches($etag, $_SERVER['HTTP_IF_MATCH'])) { + $this->set_status(412); + $this->render_nothing(); + return; + } + + $this->render_json($data); + } + + /** + * private helper function to get stream data for given contexts and filter + * + * @param $contexts + * @param $filter + * @return array + */ + + private function getStreamData($contexts, $filter): array + { + $stream = new Studip\Activity\Stream($contexts, $filter); + $data = $stream->toArray(); + + foreach ($data as $key => $act) { + $actor = [ + 'type' => $act['actor_type'], + 'id' => $act['actor_id'], + ]; + + if ($act['actor_type'] == 'user') { + $a_user = \User::findFull($act['actor_id']); + $actor['details'] = $this->getMiniUser($a_user ?: new \User()); + } elseif ($act['actor_type'] === 'anonymous') { + $actor['details'] = [ + 'name' => _('Anonym'), + ]; + } + + unset($data[$key]['actor_type']); + unset($data[$key]['actor_id']); + + $data[$key]['actor'] = $actor; + } + + return $data; + } + + private function getMiniUser(User $user): array + { + $avatar = \Avatar::getAvatar($user->id); + + return [ + 'id' => $user->id, + 'name' => $this->getNamesOfUser($user), + 'avatar_small' => $avatar->getURL(\Avatar::SMALL), + 'avatar_medium' => $avatar->getURL(\Avatar::MEDIUM), + 'avatar_normal' => $avatar->getURL(\Avatar::NORMAL), + 'avatar_original' => $avatar->getURL(\Avatar::NORMAL) + ]; + } + + private function getNamesOfUser(User $user): array + { + return [ + 'username' => $user->username, + 'formatted' => $user->getFullName(), + 'family' => $user->nachname, + 'given' => $user->vorname, + 'prefix' => $user->title_front, + 'suffix' => $user->title_rear, + ]; + } + + // Helper method checking if a ETag value list includes the current ETag. + private function etagMatches(string $etag, string $list) + { + if ($list === '*') { + return true; + } + + return in_array( + $etag, + preg_split('/\s*,\s*/', $list) + ); + } + } |
