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
21 changes: 18 additions & 3 deletions SOLUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@ SOLUTION

Estimation
----------
Estimated: n hours
Estimated: 3 hours

Spent: x hours
Spent: 3,5 hours
- 2 hours (thinking and redesigned the code)
- 45 min setup the environment
- 45 min coding


Solution
--------
Comments on your solution
This task can be done with multiples options. One of these options I just wrote it with code. I use Laravel collection package, which helped me to easily
get array data from DB to multidimensional array (collection).

Other options:
- The other option how can be this task done is to write raw SQL sentence and get all data with mysql.
- If I will know a little bit more Symfony ORM package, this can be also done with ORM command and you can get data out from ORM and then display in console:

Other good solution is to display more tables if user doesn't type in year data. Tables can be separate with new line and if have in DB 10 years it will display 10 tables.
But with this solution you need to be careful, because if you get a lot of years and data in you databases it can too much loaded a server.

This example can be upgraded in the future with nice console message if user doesn't type a year of a report and suggested a option to type a year without to return error exceptions.

Code can be also separated into function if you need it to reuse it somewhere else.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"symfony/dependency-injection": "^3.2",
"symfony/config": "^3.2",
"symfony/yaml": "^3.2",
"doctrine/dbal": "^2.5"
"doctrine/dbal": "^2.5",
"tightenco/collect": "v5.6.27"
},
"license": "proprietary",
"authors": [
Expand Down
121 changes: 85 additions & 36 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 55 additions & 3 deletions src/Command/ReportYearlyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Tightenco\Collect\Support\Collection;
use Symfony\Component\Console\Input\InputArgument;

class ReportYearlyCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('report:profiles:yearly')
->addArgument('year', InputArgument::REQUIRED, 'For which year do you need a report?')
->setDescription('Page views report')
;
}
Expand All @@ -23,10 +26,59 @@ 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();
if($input->getArgument('year')){
$yearOfDisplay = $input->getArgument('year');
}

// Show data in a table - headers, data
$io->table(['Profile'], $profiles);
$profiles = collect($db->query('SELECT profile_name, date, views FROM profiles as p LEFT JOIN views as v ON p.profile_id=v.profile_id WHERE date LIKE "'.$yearOfDisplay.'-%" ORDER BY p.profile_name, v.date')->fetchAll());

// Group by profiles and order by alphabetic order
$export = $profiles->groupBy('profile_name')->sortBy('profile_name');

// SUM for each user theirs data
$export = $export->transform(function($personData){

return $personData->groupBy(function($month){

return date('M', strtotime($month['date']));

})->transform(function($monthValue){

return number_format($monthValue->sum('views'));
});
});

// Display no data found.
if(sizeof($export->toArray()) == 0){
return $io->table(
['Profiles - '.$yearOfDisplay],
[
['n/a']
]
);
}

// Design array for Symfony console display
// Header with name of profiles and months
$header = $profiles->sortBy('date')->groupBy(function($val) {

return date('M', strtotime($val['date']));

})->keys()->toArray();
array_unshift($header, 'Profiles - '.$yearOfDisplay);


// Add profile name in the same row as totals
$data = [];
foreach($export->toArray() as $name => $monthData){
$data[$name] = $monthData;
array_unshift($data[$name], $name);
}

return $io->table(
$header,
$data
);

}
}
4 changes: 4 additions & 0 deletions src/Tests/YearlyReport.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
My weakness are tests, because I haven't need to use it on small project, but on big project where I have been worked on we didn't use test. So on this project I will need to improve myself.

First you need set year for which you would like to get data. Then you need to check if you get any data. When console display the table you need to check id if return success message or exceptions.
Sometimes you can also checked type of given data.