From 4f46550cdc7342c5e0bcf59127835805ce5b1063 Mon Sep 17 00:00:00 2001 From: Rafal Kanski Date: Sun, 26 Apr 2015 12:20:14 +0200 Subject: [PATCH] fetching data for one article --- src/SaHackathon/Home/Api/Entity/Article.php | 98 ++++++++++++- .../Home/Api/Repository/ArticleRepository.php | 129 +++++++++++++++++- .../Api/Service/Event/EventDbSaverService.php | 24 ++++ .../Home/Data/DataControllerProvider.php | 41 ++++-- .../Home/HomeControllerProvider.php | 15 +- src/SaHackathon/Home/views/article.html.twig | 80 +++++------ src/SaHackathon/Home/views/index.html.twig | 7 +- web/css/style.css | 17 ++- 8 files changed, 333 insertions(+), 78 deletions(-) diff --git a/src/SaHackathon/Home/Api/Entity/Article.php b/src/SaHackathon/Home/Api/Entity/Article.php index e99e42c..7d1ab22 100644 --- a/src/SaHackathon/Home/Api/Entity/Article.php +++ b/src/SaHackathon/Home/Api/Entity/Article.php @@ -25,7 +25,7 @@ class Article { private $decision; /** - * @var int + * @var float */ private $time; @@ -49,6 +49,45 @@ class Article { */ private $dislikes; + /** + * @var int + */ + private $skips; + + /** + * @return int + */ + public function getSkips() + { + return $this->skips; + } + + /** + * @param int $skips + * @return $this + */ + public function setSkips($skips) + { + $this->skips = $skips; + + return $this; + } + + /** + * @var float + */ + private $timeLikes; + + /** + * @var float + */ + private $timeDislikes; + + /** + * @var float + */ + private $timeSkip; + /** * Sets default date for article */ @@ -229,4 +268,61 @@ public function setDislikes($dislikes) return $this; } + /** + * @return mixed + */ + public function getTimeDislikes() + { + return $this->timeDislikes; + } + + /** + * @param mixed $timeDislikes + * @return $this + */ + public function setTimeDislikes($timeDislikes) + { + $this->timeDislikes = $timeDislikes; + + return $this; + } + + /** + * @return mixed + */ + public function getTimeLikes() + { + return $this->timeLikes; + } + + /** + * @param mixed $timeLikes + * @return $this + */ + public function setTimeLikes($timeLikes) + { + $this->timeLikes = $timeLikes; + + return $this; + } + + /** + * @return float + */ + public function getTimeSkip() + { + return $this->timeSkip; + } + + /** + * @param float $timeSkip + * @return $this + */ + public function setTimeSkip($timeSkip) + { + $this->timeSkip = $timeSkip; + + return $this; + } + } diff --git a/src/SaHackathon/Home/Api/Repository/ArticleRepository.php b/src/SaHackathon/Home/Api/Repository/ArticleRepository.php index ab532f4..3f4228e 100644 --- a/src/SaHackathon/Home/Api/Repository/ArticleRepository.php +++ b/src/SaHackathon/Home/Api/Repository/ArticleRepository.php @@ -67,7 +67,7 @@ public function save(Article $article) } /** - * Returns unique articles from datasource + * Returns unique articles from entity * @return Article[] */ public function getUniqueArticles() @@ -88,7 +88,11 @@ public function getUniqueArticles() ( SELECT count(*) FROM article as article_double WHERE article.hash=article_double.hash - AND article_double.decision=\'dislike\') as articleDislikes + AND article_double.decision=\'dislike\') as articleDislikes, + ( SELECT count(*) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'skip\') as articleSkips ' ) ->from(self::ARTICLE_TABLE_NAME) @@ -109,6 +113,7 @@ public function getUniqueArticles() ->setDecision($article['decision']) ->setDate($article['date']) ->setLikes($article['articleLikes']) + ->setSkips($article['articleSkips']) ->setDislikes($article['articleDislikes']); } @@ -117,4 +122,124 @@ public function getUniqueArticles() } + /** + * Returns article by hash from entity + * @param $hash string + * @return Article + */ + public function getArticleByHash($hash) + { + + $query = $this + ->getConnection() + ->createQueryBuilder() + ->select( + ' + *, + ( SELECT count(*) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'like\') as articleLikes, + ( SELECT count(*) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'dislike\') as articleDislikes, + ( SELECT count(*) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'skip\') as articleSkips + ' + ) + ->from(self::ARTICLE_TABLE_NAME) + ->where("hash='".$hash."'") + ->groupBy('hash') + ->execute(); + + if ($articleFetched = $query->fetch()) { + $article = new Article(); + $article + ->setId($articleFetched['id']) + ->setTitle($articleFetched['title']) + ->setTime($articleFetched['time']) + ->setHash($articleFetched['hash']) + ->setUser($articleFetched['user']) + ->setDecision($articleFetched['decision']) + ->setDate($articleFetched['date']) + ->setLikes($articleFetched['articleLikes']) + ->setSkips($articleFetched['articleSkips']) + ->setDislikes($articleFetched['articleDislikes']); + + return $article; + + } + + return null; + + } + + /** + * Returns statistics from entity + * @param $hash + * @return null + */ + public function getArticleStatistics($hash) + { + + $query = $this + ->getConnection() + ->createQueryBuilder() + ->select( + ' + *, + ( + SELECT if (sum(time) IS NULL,0,sum(time)) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'like\' + AND date > CURRENT_TIMESTAMP() - INTERVAL 30 second + ) as timeLikes, + ( + SELECT if (sum(time) IS NULL,0,sum(time)) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'dislike\' + AND date > CURRENT_TIMESTAMP() - INTERVAL 5 second + ) as timeDislikes, + ( + SELECT if (sum(time) IS NULL,0,sum(time)) + FROM article as article_double + WHERE article.hash=article_double.hash + AND article_double.decision=\'skip\' + AND date > CURRENT_TIMESTAMP() - INTERVAL 5 second + ) as timeSkip + ' + ) + ->from(self::ARTICLE_TABLE_NAME) + ->where("hash='".$hash."'") + ->andWhere('date > CURRENT_TIMESTAMP() - INTERVAL 5 second') + ->groupBy('hash') + ->execute(); + + if ($articleFetched = $query->fetch()) { + + $article = new Article(); + $article + ->setId($articleFetched['id']) + ->setTitle($articleFetched['title']) + ->setTime($articleFetched['time']) + ->setHash($articleFetched['hash']) + ->setUser($articleFetched['user']) + ->setDecision($articleFetched['decision']) + ->setDate($articleFetched['date']) + ->setTimeLikes($articleFetched['timeLikes']) + ->setTimeDislikes($articleFetched['timeDislikes']) + ->setTimeSkip($articleFetched['timeSkip']); + + return $article; + + } + + return null; + } + } diff --git a/src/SaHackathon/Home/Api/Service/Event/EventDbSaverService.php b/src/SaHackathon/Home/Api/Service/Event/EventDbSaverService.php index 1e94d2a..a86d909 100644 --- a/src/SaHackathon/Home/Api/Service/Event/EventDbSaverService.php +++ b/src/SaHackathon/Home/Api/Service/Event/EventDbSaverService.php @@ -56,4 +56,28 @@ public function getUniqueArticles () } + /** + * Returns article + * @param $hash + * @return mixed + */ + public function getArticleByHash($hash) + { + + return $this->articleRepository->getArticleByHash($hash); + + } + + /** + * Returns article statistics + * @param $hash + * @return mixed + */ + public function getArticleStatistics($hash) + { + + return $this->articleRepository->getArticleStatistics($hash); + + } + } diff --git a/src/SaHackathon/Home/Data/DataControllerProvider.php b/src/SaHackathon/Home/Data/DataControllerProvider.php index 486d587..dc8ca34 100644 --- a/src/SaHackathon/Home/Data/DataControllerProvider.php +++ b/src/SaHackathon/Home/Data/DataControllerProvider.php @@ -2,6 +2,7 @@ namespace SaHackathon\Home\Data; +use SaHackathon\Home\Api\Entity\Article; use Silex\ControllerProviderInterface; use SaHackathon\Home\TwigTrait; use Silex\Application; @@ -42,34 +43,50 @@ protected function initController(Application $app) '/refresh', function (Application $app) use ($that) { - $date = new \DateTime(); + $articleHash = $app['request']->get('hash'); - $event = [ - 'y' => rand(1, 5), - 'x' => strtotime($date->format('Y-m-d H:i:s')) * 1000 - ]; + $service = $app['eventSaver']; + $articleStatistics = $service->getArticleStatistics($articleHash); + + /** @var Article $article */ + $article = $service->getArticleByHash($articleHash); + + $date = new \DateTime(); $seed = rand(1, 20); if ($seed % 3 === 0) { $event['decision'] = 'like'; - $event['color'] = 'green'; - $result['eventLike'][] = $event; + $event['color'] = '#7accc8'; + $event['y'] = ($articleStatistics) ? (int)$articleStatistics->getTimeLikes() : 0; + $event['x'] = strtotime($date->format('Y-m-d H:i:s')) * 1000; } if ($seed % 3 === 1) { $event['decision'] = 'dislike'; - $event['color'] = 'red'; - $result['eventDislike'][] = $event; + $event['color'] = '#f26d7d'; + $event['y'] = ($articleStatistics) ? (int)$articleStatistics->getTimeDislikes() : 0; + $event['x'] = strtotime($date->format('Y-m-d H:i:s')) * 1000; } if ($seed % 3 === 2) { $event['decision'] = 'skip'; - $event['color'] = 'gray'; - $result['eventDislike'][] = $event; + $event['color'] = '#898989'; + $event['y'] = ($articleStatistics) ? (int)$articleStatistics->getTimeSkip() : 0; + $event['x'] = strtotime($date->format('Y-m-d H:i:s')) * 1000; } - return new JsonResponse($event); + $eventsCount = $article->getLikes() + $article->getDislikes() + $article->getSkips(); // TODO: add also skip count + $response = [ + 'event' => $event, + 'article' => [ + 'likesPercent' => (int) ($article->getLikes() / $eventsCount * 100), + 'dislikesPercent' => (int) ($article->getDislikes() / $eventsCount * 100), + 'skipsPercent' => (int) ($article->getSkips() / $eventsCount * 100), + ] + ]; + + return new JsonResponse($response); } ); diff --git a/src/SaHackathon/Home/HomeControllerProvider.php b/src/SaHackathon/Home/HomeControllerProvider.php index dee7bbb..802cd4a 100644 --- a/src/SaHackathon/Home/HomeControllerProvider.php +++ b/src/SaHackathon/Home/HomeControllerProvider.php @@ -51,17 +51,16 @@ function(Application $app) use($that) { ); $controllers->get( - '/article/{slug}', - function($slug) use($that) { + '/article/{hash}', + function($hash) use($app) { + + $service = $app['eventSaver']; + $article = $service->getArticleByHash($hash); + return $this->twig->render( 'article.html.twig', [ - 'article' => [ - 'slug' => $slug, - 'title' => 'Rosenborg-ledelsen visste ikke at Nicki Bille var dømt tidligere', - 'eventsLike' => [], - 'eventsDislike' => [], - ] + 'article' => $article ] ); } diff --git a/src/SaHackathon/Home/views/article.html.twig b/src/SaHackathon/Home/views/article.html.twig index e4d07a5..d690959 100644 --- a/src/SaHackathon/Home/views/article.html.twig +++ b/src/SaHackathon/Home/views/article.html.twig @@ -1,7 +1,7 @@ {% extends 'layout.html.twig' %} {% block body %} -

Article {{ article.title }}

+

Article - {{ article.title }}

@@ -39,50 +39,14 @@ ] %}