Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions SOLUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ SOLUTION

Estimation
----------
Estimated: n hours
Estimated: 4 hours

Spent: x hours
Spent: 4.5 hours


Solution
--------
Comments on your solution
Najbrž bi bilo smiselno predelati leto v wildcard, ki bi dopuščal izpis vseh profilov po letih. - 2 uri
Možnost opcijskega filtra(sortiranje po določenem polju(leto, največ ogledov) asc/dec) - 4 ure


22 changes: 18 additions & 4 deletions src/Command/ReportYearlyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use BOF\Profile\Report;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;

class ReportYearlyCommand extends ContainerAwareCommand
{
Expand All @@ -14,6 +17,11 @@ protected function configure()
$this
->setName('report:profiles:yearly')
->setDescription('Page views report')
->setDefinition(
new InputDefinition([
new InputOption('year', 'y', InputOption::VALUE_OPTIONAL),
])
);
;
}

Expand All @@ -23,10 +31,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
$io = new SymfonyStyle($input,$output);
$db = $this->getContainer()->get('database_connection');

$profiles = $db->query('SELECT profile_name FROM profiles')->fetchAll();

// Show data in a table - headers, data
$io->table(['Profile'], $profiles);
$report = new Report($db);

if (!$report->setYear($input->getOption("year"))) {
$io->writeln("Year must be a valid integer.");
return false;
}

if (!$report->setProfileViews())
$io->table("Profile", []);

$io->table($report->getHeaders(), $report->getProfiles());
}
}
54 changes: 54 additions & 0 deletions src/Profile/Profile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace BOF\Profile;

class Profile
{
private $id;
private $name;
private $months;

public function __construct($id)
{
$this->id = $id;
}

public function getId()
{
return $this->id;
}

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}

public function addViewsToMonth($month, $views)
{
if (isset($this->months[$month])) {
$this->months[$month] += $views;
} else {
$this->months[$month] = $views;
}
}

public function sortMonths()
{
for ($i = 1; $i <= 12; $i++) {
if (!isset($this->months[$i]))
$this->months[$i] = "N/A";
}

ksort($this->months);
}

public function getMonths()
{
return $this->months;
}
}
88 changes: 88 additions & 0 deletions src/Profile/Report.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

namespace BOF\Profile;

use BOF\Profile\Profile;
use Doctrine\DBAL\Connection;

class Report
{
private $db;
private $profiles = [];
private $year;

public function __construct(Connection $db)
{
$this->db = $db;
}

public function setProfileViews()
{
if (!isset($this->year))
$this->setYear(date('Y'));

return $this->getProfileViewsByYear();
}

public function getProfileViewsByYear()
{
$profiles = $this->db->query("SELECT p.profile_name, p.profile_id, date_format(v.date, '%m') dateMonth, v.views from profiles p left join views v on p.profile_id = v.profile_id AND YEAR(v.date) = $this->year")->fetchAll();

if (!$profiles)
return false;

$this->sortProfileViews($profiles);

return true;
}

public function getProfiles()
{
$return = [];

foreach ($this->profiles as $profile) {
$profile->sortMonths();
$values = array_values($profile->getMonths());
array_unshift($values, $profile->getName());
$return[$profile->getName()] = $values;
}

ksort($return);
return array_values($return);
}

public function getHeaders()
{
return ['Profile ' . $this->year, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
}

private function sortProfileViews($profiles)
{
$sortedProfiles = [];

foreach ($profiles as $view) {
if (isset($sortedProfiles[$view["profile_id"]])) {
$user = $sortedProfiles[$view["profile_id"]];
} else {
$user = new Profile($view["profile_id"]);
$user->setName($view["profile_name"]);
$sortedProfiles[$user->getId()] = $user;
}

if (isset($view["dateMonth"]))
$user->addViewsToMonth((int) $view["dateMonth"], (int) $view["views"]);
}

$this->profiles = $sortedProfiles;
}

public function setYear($year)
{
if ((int) $year == 0)
return false;

$this->year = (int) $year;

return true;
}
}
14 changes: 14 additions & 0 deletions src/Tests/YearlyReport.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GIVEN that there is 0 profile data available
WHEN I execute the Yearly Views report
THEN I expect to see a blank table with Profile header

GIVEN that there isn't input option "year" set
WHEN I execute the Yearly Views report
THEN I expect to see a monthly breakdown of the total views per profiles for active year

GIVEN that there is option "year" set
AND year is invalid integer
WHEN I execute the Yearly Views report
THEN I expect to see error text: "Year must be a valid integer"