diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-04-10 12:13:42 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-04-10 12:13:42 -0400 |
commit | 2eadfb22912d94e76a479b694070735fbb0298f1 (patch) | |
tree | 4280c1bc33851da2188f4bc0aa49310a5923e021 /app | |
parent | 7b74f55a285d2785f83be148abdeab95e2b4a7c6 (diff) |
Refactor ProjectActivity model to use Filter and Formatter interface
Diffstat (limited to 'app')
-rw-r--r-- | app/Api/Me.php | 2 | ||||
-rw-r--r-- | app/Api/Project.php | 4 | ||||
-rw-r--r-- | app/Controller/Activity.php | 4 | ||||
-rw-r--r-- | app/Controller/App.php | 2 | ||||
-rw-r--r-- | app/Controller/Feed.php | 4 | ||||
-rw-r--r-- | app/Controller/ProjectOverview.php | 2 | ||||
-rw-r--r-- | app/Core/Base.php | 2 | ||||
-rw-r--r-- | app/Core/Helper.php | 1 | ||||
-rw-r--r-- | app/Filter/ProjectActivityProjectIdFilter.php | 38 | ||||
-rw-r--r-- | app/Filter/ProjectActivityProjectIdsFilter.php | 43 | ||||
-rw-r--r-- | app/Filter/ProjectActivityTaskIdFilter.php | 38 | ||||
-rw-r--r-- | app/Filter/ProjectActivityTaskTitleFilter.php | 38 | ||||
-rw-r--r-- | app/Formatter/ProjectActivityEventFormatter.php | 61 | ||||
-rw-r--r-- | app/Helper/ProjectActivityHelper.php | 78 | ||||
-rw-r--r-- | app/Model/ProjectActivity.php | 151 | ||||
-rw-r--r-- | app/ServiceProvider/FilterProvider.php | 42 | ||||
-rw-r--r-- | app/ServiceProvider/HelperProvider.php | 1 |
17 files changed, 362 insertions, 149 deletions
diff --git a/app/Api/Me.php b/app/Api/Me.php index ccc809ed..3d08626a 100644 --- a/app/Api/Me.php +++ b/app/Api/Me.php @@ -33,7 +33,7 @@ class Me extends Base public function getMyActivityStream() { $project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId()); - return $this->projectActivity->getProjects($project_ids, 100); + return $this->helper->projectActivity->getProjectsEvents($project_ids, 100); } public function createMyPrivateProject($name, $description = null) diff --git a/app/Api/Project.php b/app/Api/Project.php index 8e311f7f..846d7046 100644 --- a/app/Api/Project.php +++ b/app/Api/Project.php @@ -53,13 +53,13 @@ class Project extends Base public function getProjectActivities(array $project_ids) { - return $this->projectActivity->getProjects($project_ids); + return $this->helper->projectActivity->getProjectsEvents($project_ids); } public function getProjectActivity($project_id) { $this->checkProjectPermission($project_id); - return $this->projectActivity->getProject($project_id); + return $this->helper->projectActivity->getProjectEvents($project_id); } public function createProject($name, $description = null) diff --git a/app/Controller/Activity.php b/app/Controller/Activity.php index e455b1da..47a66e0a 100644 --- a/app/Controller/Activity.php +++ b/app/Controller/Activity.php @@ -20,7 +20,7 @@ class Activity extends Base $project = $this->getProject(); $this->response->html($this->helper->layout->app('activity/project', array( - 'events' => $this->projectActivity->getProject($project['id']), + 'events' => $this->helper->projectActivity->getProjectEvents($project['id']), 'project' => $project, 'title' => t('%s\'s activity', $project['name']) ))); @@ -39,7 +39,7 @@ class Activity extends Base 'title' => $task['title'], 'task' => $task, 'project' => $this->project->getById($task['project_id']), - 'events' => $this->projectActivity->getTask($task['id']), + 'events' => $this->helper->projectActivity->getTaskEvents($task['id']), ))); } } diff --git a/app/Controller/App.php b/app/Controller/App.php index df1d3c90..01f733ff 100644 --- a/app/Controller/App.php +++ b/app/Controller/App.php @@ -157,7 +157,7 @@ class App extends Base $this->response->html($this->helper->layout->dashboard('app/activity', array( 'title' => t('My activity stream'), - 'events' => $this->projectActivity->getProjects($this->projectPermission->getActiveProjectIds($user['id']), 100), + 'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermission->getActiveProjectIds($user['id']), 100), 'user' => $user, ))); } diff --git a/app/Controller/Feed.php b/app/Controller/Feed.php index 8457c383..f8b3d320 100644 --- a/app/Controller/Feed.php +++ b/app/Controller/Feed.php @@ -26,7 +26,7 @@ class Feed extends Base } $this->response->xml($this->template->render('feed/user', array( - 'events' => $this->projectActivity->getProjects($this->projectPermission->getActiveProjectIds($user['id'])), + 'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermission->getActiveProjectIds($user['id'])), 'user' => $user, ))); } @@ -47,7 +47,7 @@ class Feed extends Base } $this->response->xml($this->template->render('feed/project', array( - 'events' => $this->projectActivity->getProject($project['id']), + 'events' => $this->helper->projectActivity->getProjectEvents($project['id']), 'project' => $project, ))); } diff --git a/app/Controller/ProjectOverview.php b/app/Controller/ProjectOverview.php index 04645804..b2bb33d6 100644 --- a/app/Controller/ProjectOverview.php +++ b/app/Controller/ProjectOverview.php @@ -24,7 +24,7 @@ class ProjectOverview extends Base 'description' => $this->helper->projectHeader->getDescription($project), 'users' => $this->projectUserRole->getAllUsersGroupedByRole($project['id']), 'roles' => $this->role->getProjectRoles(), - 'events' => $this->projectActivity->getProject($project['id'], 10), + 'events' => $this->helper->projectActivity->getProjectEvents($project['id'], 10), 'images' => $this->projectFile->getAllImages($project['id']), 'files' => $this->projectFile->getAllDocuments($project['id']), ))); diff --git a/app/Core/Base.php b/app/Core/Base.php index 8c6b7620..2b619af5 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -129,10 +129,12 @@ use Pimple\Container; * @property \Kanboard\Export\TransitionExport $transitionExport * @property \Kanboard\Core\Filter\QueryBuilder $projectGroupRoleQuery * @property \Kanboard\Core\Filter\QueryBuilder $projectUserRoleQuery + * @property \Kanboard\Core\Filter\QueryBuilder $projectActivityQuery * @property \Kanboard\Core\Filter\QueryBuilder $userQuery * @property \Kanboard\Core\Filter\QueryBuilder $projectQuery * @property \Kanboard\Core\Filter\QueryBuilder $taskQuery * @property \Kanboard\Core\Filter\LexerBuilder $taskLexer + * @property \Kanboard\Core\Filter\LexerBuilder $projectActivityLexer * @property \Psr\Log\LoggerInterface $logger * @property \PicoDb\Database $db * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher diff --git a/app/Core/Helper.php b/app/Core/Helper.php index ab1f8f76..66f8d429 100644 --- a/app/Core/Helper.php +++ b/app/Core/Helper.php @@ -26,6 +26,7 @@ use Pimple\Container; * @property \Kanboard\Helper\UserHelper $user * @property \Kanboard\Helper\LayoutHelper $layout * @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader + * @property \Kanboard\Helper\ProjectActivityHelper $projectActivity */ class Helper { diff --git a/app/Filter/ProjectActivityProjectIdFilter.php b/app/Filter/ProjectActivityProjectIdFilter.php new file mode 100644 index 00000000..bb4d8bd1 --- /dev/null +++ b/app/Filter/ProjectActivityProjectIdFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\ProjectActivity; + +/** + * Filter activity events by projectId + * + * @package filter + * @author Frederic Guillot + */ +class ProjectActivityProjectIdFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('project_id'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(ProjectActivity::TABLE.'.project_id', $this->value); + return $this; + } +} diff --git a/app/Filter/ProjectActivityProjectIdsFilter.php b/app/Filter/ProjectActivityProjectIdsFilter.php new file mode 100644 index 00000000..4d7c9028 --- /dev/null +++ b/app/Filter/ProjectActivityProjectIdsFilter.php @@ -0,0 +1,43 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\ProjectActivity; + +/** + * Filter activity events by projectIds + * + * @package filter + * @author Frederic Guillot + */ +class ProjectActivityProjectIdsFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('project_ids'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (empty($this->value)) { + $this->query->eq(ProjectActivity::TABLE.'.project_id', 0); + } else { + $this->query->in(ProjectActivity::TABLE.'.project_id', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/ProjectActivityTaskIdFilter.php b/app/Filter/ProjectActivityTaskIdFilter.php new file mode 100644 index 00000000..e99efe09 --- /dev/null +++ b/app/Filter/ProjectActivityTaskIdFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\ProjectActivity; + +/** + * Filter activity events by taskId + * + * @package filter + * @author Frederic Guillot + */ +class ProjectActivityTaskIdFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('task_id'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(ProjectActivity::TABLE.'.task_id', $this->value); + return $this; + } +} diff --git a/app/Filter/ProjectActivityTaskTitleFilter.php b/app/Filter/ProjectActivityTaskTitleFilter.php new file mode 100644 index 00000000..ed3f36d6 --- /dev/null +++ b/app/Filter/ProjectActivityTaskTitleFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter activity events by task title + * + * @package filter + * @author Frederic Guillot + */ +class ProjectActivityTaskTitleFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('title'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->ilike(Task::TABLE.'.title', '%'.$this->value.'%'); + return $this; + } +} diff --git a/app/Formatter/ProjectActivityEventFormatter.php b/app/Formatter/ProjectActivityEventFormatter.php new file mode 100644 index 00000000..ae80e5e7 --- /dev/null +++ b/app/Formatter/ProjectActivityEventFormatter.php @@ -0,0 +1,61 @@ +<?php + +namespace Kanboard\Formatter; + +use Kanboard\Core\Filter\FormatterInterface; + +class ProjectActivityEventFormatter extends BaseFormatter implements FormatterInterface +{ + /** + * Apply formatter + * + * @access public + * @return array + */ + public function format() + { + $events = $this->query->findAll(); + + foreach ($events as &$event) { + $event += $this->unserializeEvent($event['data']); + unset($event['data']); + + $event['author'] = $event['author_name'] ?: $event['author_username']; + $event['event_title'] = $this->notification->getTitleWithAuthor($event['author'], $event['event_name'], $event); + $event['event_content'] = $this->renderEvent($event); + } + + return $events; + } + + /** + * Decode event data, supports unserialize() and json_decode() + * + * @access protected + * @param string $data Serialized data + * @return array + */ + protected function unserializeEvent($data) + { + if ($data{0} === 'a') { + return unserialize($data); + } + + return json_decode($data, true) ?: array(); + } + + /** + * Get the event html content + * + * @access protected + * @param array $params Event properties + * @return string + */ + protected function renderEvent(array $params) + { + return $this->template->render( + 'event/'.str_replace('.', '_', $params['event_name']), + $params + ); + } +} diff --git a/app/Helper/ProjectActivityHelper.php b/app/Helper/ProjectActivityHelper.php new file mode 100644 index 00000000..738fec66 --- /dev/null +++ b/app/Helper/ProjectActivityHelper.php @@ -0,0 +1,78 @@ +<?php + +namespace Kanboard\Helper; + +use Kanboard\Core\Base; +use Kanboard\Filter\ProjectActivityProjectIdFilter; +use Kanboard\Filter\ProjectActivityProjectIdsFilter; +use Kanboard\Filter\ProjectActivityTaskIdFilter; +use Kanboard\Formatter\ProjectActivityEventFormatter; +use Kanboard\Model\ProjectActivity; + +/** + * Project Activity Helper + * + * @package helper + * @author Frederic Guillot + */ +class ProjectActivityHelper extends Base +{ + /** + * Get project activity events + * + * @access public + * @param integer $project_id + * @param int $limit + * @return array + */ + public function getProjectEvents($project_id, $limit = 50) + { + $queryBuilder = $this->projectActivityQuery + ->withFilter(new ProjectActivityProjectIdFilter($project_id)); + + $queryBuilder->getQuery() + ->desc(ProjectActivity::TABLE.'.id') + ->limit($limit) + ; + + return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); + } + + /** + * Get projects activity events + * + * @access public + * @param int[] $project_ids + * @param int $limit + * @return array + */ + public function getProjectsEvents(array $project_ids, $limit = 50) + { + $queryBuilder = $this->projectActivityQuery + ->withFilter(new ProjectActivityProjectIdsFilter($project_ids)); + + $queryBuilder->getQuery() + ->desc(ProjectActivity::TABLE.'.id') + ->limit($limit) + ; + + return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); + } + + /** + * Get task activity events + * + * @access public + * @param integer $task_id + * @return array + */ + public function getTaskEvents($task_id) + { + $queryBuilder = $this->projectActivityQuery + ->withFilter(new ProjectActivityTaskIdFilter($task_id)); + + $queryBuilder->getQuery()->desc(ProjectActivity::TABLE.'.id'); + + return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); + } +} diff --git a/app/Model/ProjectActivity.php b/app/Model/ProjectActivity.php index 34893f0b..31cee113 100644 --- a/app/Model/ProjectActivity.php +++ b/app/Model/ProjectActivity.php @@ -53,115 +53,25 @@ class ProjectActivity extends Base } /** - * Get all events for the given project + * Get query * * @access public - * @param integer $project_id Project id - * @param integer $limit Maximum events number - * @param integer $start Timestamp of earliest activity - * @param integer $end Timestamp of latest activity - * @return array - */ - public function getProject($project_id, $limit = 50, $start = null, $end = null) - { - return $this->getProjects(array($project_id), $limit, $start, $end); - } - - /** - * Get all events for the given projects list - * - * @access public - * @param integer[] $project_ids Projects id - * @param integer $limit Maximum events number - * @param integer $start Timestamp of earliest activity - * @param integer $end Timestamp of latest activity - * @return array - */ - public function getProjects(array $project_ids, $limit = 50, $start = null, $end = null) - { - if (empty($project_ids)) { - return array(); - } - - $query = $this - ->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.*', - User::TABLE.'.username AS author_username', - User::TABLE.'.name AS author_name', - User::TABLE.'.email', - User::TABLE.'.avatar_path' - ) - ->in('project_id', $project_ids) - ->join(User::TABLE, 'id', 'creator_id') - ->desc(self::TABLE.'.id') - ->limit($limit); - - return $this->getEvents($query, $start, $end); - } - - /** - * Get all events for the given task - * - * @access public - * @param integer $task_id Task id - * @param integer $limit Maximum events number - * @param integer $start Timestamp of earliest activity - * @param integer $end Timestamp of latest activity - * @return array - */ - public function getTask($task_id, $limit = 50, $start = null, $end = null) - { - $query = $this - ->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.*', - User::TABLE.'.username AS author_username', - User::TABLE.'.name AS author_name', - User::TABLE.'.email', - User::TABLE.'.avatar_path' - ) - ->eq('task_id', $task_id) - ->join(User::TABLE, 'id', 'creator_id') - ->desc(self::TABLE.'.id') - ->limit($limit); - - return $this->getEvents($query, $start, $end); - } - - /** - * Common function to return events - * - * @access public - * @param Table $query PicoDb Query - * @param integer $start Timestamp of earliest activity - * @param integer $end Timestamp of latest activity - * @return array + * @return Table */ - private function getEvents(Table $query, $start, $end) + public function getQuery() { - if (! is_null($start)) { - $query->gte('date_creation', $start); - } - - if (! is_null($end)) { - $query->lte('date_creation', $end); - } - - $events = $query->findAll(); - - foreach ($events as &$event) { - $event += $this->decode($event['data']); - unset($event['data']); - - $event['author'] = $event['author_name'] ?: $event['author_username']; - $event['event_title'] = $this->notification->getTitleWithAuthor($event['author'], $event['event_name'], $event); - $event['event_content'] = $this->getContent($event); - } - - return $events; + return $this + ->db + ->table(ProjectActivity::TABLE) + ->columns( + ProjectActivity::TABLE.'.*', + 'uc.username AS author_username', + 'uc.name AS author_name', + 'uc.email', + 'uc.avatar_path' + ) + ->join(Task::TABLE, 'id', 'task_id') + ->left(User::TABLE, 'uc', 'id', ProjectActivity::TABLE, 'creator_id'); } /** @@ -179,35 +89,4 @@ class ProjectActivity extends Base $this->db->table(self::TABLE)->in('id', $ids)->remove(); } } - - /** - * Get the event html content - * - * @access public - * @param array $params Event properties - * @return string - */ - public function getContent(array $params) - { - return $this->template->render( - 'event/'.str_replace('.', '_', $params['event_name']), - $params - ); - } - - /** - * Decode event data, supports unserialize() and json_decode() - * - * @access public - * @param string $data Serialized data - * @return array - */ - public function decode($data) - { - if ($data{0} === 'a') { - return unserialize($data); - } - - return json_decode($data, true) ?: array(); - } } diff --git a/app/ServiceProvider/FilterProvider.php b/app/ServiceProvider/FilterProvider.php index 3100ae7e..4b4dbd2d 100644 --- a/app/ServiceProvider/FilterProvider.php +++ b/app/ServiceProvider/FilterProvider.php @@ -4,6 +4,7 @@ namespace Kanboard\ServiceProvider; use Kanboard\Core\Filter\LexerBuilder; use Kanboard\Core\Filter\QueryBuilder; +use Kanboard\Filter\ProjectActivityTaskTitleFilter; use Kanboard\Filter\TaskAssigneeFilter; use Kanboard\Filter\TaskCategoryFilter; use Kanboard\Filter\TaskColorFilter; @@ -46,6 +47,25 @@ class FilterProvider implements ServiceProviderInterface */ public function register(Container $container) { + $this->createUserFilter($container); + $this->createProjectFilter($container); + $this->createTaskFilter($container); + return $container; + } + + public function createUserFilter(Container $container) + { + $container['userQuery'] = $container->factory(function ($c) { + $builder = new QueryBuilder(); + $builder->withQuery($c['db']->table(User::TABLE)); + return $builder; + }); + + return $container; + } + + public function createProjectFilter(Container $container) + { $container['projectGroupRoleQuery'] = $container->factory(function ($c) { $builder = new QueryBuilder(); $builder->withQuery($c['db']->table(ProjectGroupRole::TABLE)); @@ -58,18 +78,32 @@ class FilterProvider implements ServiceProviderInterface return $builder; }); - $container['userQuery'] = $container->factory(function ($c) { + $container['projectQuery'] = $container->factory(function ($c) { $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(User::TABLE)); + $builder->withQuery($c['db']->table(Project::TABLE)); return $builder; }); - $container['projectQuery'] = $container->factory(function ($c) { + $container['projectActivityLexer'] = $container->factory(function ($c) { + $builder = new LexerBuilder(); + $builder->withQuery($c['projectActivity']->getQuery()); + $builder->withFilter(new ProjectActivityTaskTitleFilter()); + + return $builder; + }); + + $container['projectActivityQuery'] = $container->factory(function ($c) { $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(Project::TABLE)); + $builder->withQuery($c['projectActivity']->getQuery()); + return $builder; }); + return $container; + } + + public function createTaskFilter(Container $container) + { $container['taskQuery'] = $container->factory(function ($c) { $builder = new QueryBuilder(); $builder->withQuery($c['taskFinder']->getExtendedQuery()); diff --git a/app/ServiceProvider/HelperProvider.php b/app/ServiceProvider/HelperProvider.php index 3590afa5..bf3956a2 100644 --- a/app/ServiceProvider/HelperProvider.php +++ b/app/ServiceProvider/HelperProvider.php @@ -30,6 +30,7 @@ class HelperProvider implements ServiceProviderInterface $container['helper']->register('user', '\Kanboard\Helper\UserHelper'); $container['helper']->register('avatar', '\Kanboard\Helper\AvatarHelper'); $container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper'); + $container['helper']->register('projectActivity', '\Kanboard\Helper\ProjectActivityHelper'); $container['template'] = new Template($container['helper']); |