Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e30dd2f
init
ziberiDev Nov 11, 2021
41e202c
Created main coman controller StoreManager
ziberiDev Nov 12, 2021
49c6996
implemented listing for fasts
ziberiDev Nov 12, 2021
42735d1
Inputvalidation and CreateFast command
ziberiDev Nov 16, 2021
ead243d
update
ziberiDev Nov 16, 2021
fc41b8a
CommandController update updateCanCreate if store is empty add true
ziberiDev Nov 17, 2021
12bece5
updated Create command
ziberiDev Nov 17, 2021
4481a40
listFasts changed Fast print function added
ziberiDev Nov 17, 2021
4fb396c
FileManagerInterface write method accepts array
ziberiDev Nov 17, 2021
2c62839
Collection class added a toArray method
ziberiDev Nov 17, 2021
6609a2c
Fast model added jsonSerialize method and print method
ziberiDev Nov 17, 2021
32cbb08
getAll method updated if store is empty return empty collection write…
ziberiDev Nov 17, 2021
eacd34d
updated files
ziberiDev Nov 17, 2021
24db1a3
small functionality changes on printing menu
ziberiDev Nov 17, 2021
0056a76
too much to commit
ziberiDev Nov 18, 2021
d28b70c
final commit before merge to master
ziberiDev Nov 19, 2021
6a8f9eb
sad
ziberiDev Nov 19, 2021
53e8b48
Merge branch 'develop' into main
ziberiDev Nov 19, 2021
88a327b
edited redme file with app instructions
ziberiDev Nov 19, 2021
ac385a5
edit redme
ziberiDev Nov 19, 2021
4b8a69d
Delete vendor directory
ziberiDev Nov 19, 2021
9a3c83c
modified gitignore
ziberiDev Nov 19, 2021
412f0db
resolved comments from pull request
ziberiDev Nov 23, 2021
6659062
fixed issues
ziberiDev Sep 23, 2022
3a4101a
update file manager
ziberiDev Sep 23, 2022
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
APP_STORAGE=./store.json
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
composer.lock
/vendor/
.idea
store.json
145 changes: 145 additions & 0 deletions App/Commands/BaseCommandController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

namespace App\Commands;

use App\Console\InputConsole;
use App\Console\InputValidator;
use App\Console\OutputConsole;
use App\Enums\FastType;
use App\Model\Fast;
use App\Store\StoreManager;
use Exception;

class BaseCommandController
{

protected array $fastTypes;
protected array $confirmationOptions = [
"Y" => true,
"N" => false
];

public function __construct(
protected InputConsole $input,
protected OutputConsole $output,
protected StoreManager $store,
protected InputValidator $validator,
protected Fast $newFast
){
$this->setFastTypes();
}

/**
* Sets fast starting date from user input.
* @throws Exception
*/
protected function getStartDate()
{
$this->output->write('Enter Start Date of Fast format:(Y-m-d H:i:s) => (2020-10-10 20:00:00)', 'yellow');
$userInput = $this->input->getInput();

while ($message = $this->validator->validateStartDate($userInput)) {
$this->output->write($message, 'red');
$userInput = $this->input->getInput();
}
$this->newFast->set([
'start' => $userInput
]);
}

/**
* Prints fast types in console and sets fast type from user input.
* @throws Exception
*/
protected function getFastType()
{
$this->output->write('Select a fast type', 'yellow');
$this->printFastTypes();
$userInput = $this->input->getInput();

while (!isset($this->fastTypes[$userInput])) {
$this->output->write('Please choose from existing types.', 'red');
$userInput = $this->input->getInput();
}
$this->newFast->set([
'type' => $this->fastTypes[$userInput]['value']
]);
}

/**
* Sets $fastTypes property as array from FastType enum class
*/
protected function setFastTypes()
{
foreach (FastType::getAll() as $const => $value) {
$this->fastTypes[] = [
'const' => $const,
'value' => $value
];
}
}

/**
* Prints Fast types from fastTypes property.
*/
protected function printFastTypes()
{
foreach ($this->fastTypes as $key => $value) {
$this->output->write("[$key] " . $value['const'] . " ({$value['value']}" . 'h)', 'yellow');
}
}

/**
* Sets the newly created fast end Date
*/
protected function setFastEndDate()
{
$hours = 'PT' . $this->newFast->type . 'H';
$fastEndDate = $this->newFast
->start
->add(new \DateInterval("$hours"))
->format('Y-m-d H:i:s');

$this->newFast->set([
'end' => $fastEndDate
]);
}

/**
* Saves the newly created fast into the store file.
*/
protected function saveFast()
{
$storeFasts = $this->store->getAll()->toArray();

$storeFasts[] = $this->newFast;

$this->store->write($storeFasts);
}

/**
* Saves a single Fast object passed as a parameter in the store file.
* @param Fast $fast
* @throws Exception
*/
protected function save(Fast $fast)
{
$storeFasts = $this->store->getAll()->toArray();
$storeFasts[] = $fast;
$this->store->write($storeFasts);
}

protected function askForConfirmation(string $question): string
{
$this->output->write($question, 'yellow');
$this->printConfirmationMenu();
return strtoupper($this->input->getInput());
}

private function printConfirmationMenu()
{
foreach ($this->confirmationOptions as $key => $value) {
$this->output->write("[$key]", 'yellow');
}
}
}
17 changes: 17 additions & 0 deletions App/Commands/CheckCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Commands;

use App\Interface\BaseCommandInterface;

class CheckCommand extends BaseCommandController implements BaseCommandInterface
{
public function run()
{
if (!$activeFast = $this->store->getActiveFast()) {
$this->output->write('You have no active fast please create one.', 'red');
return;
}
$this->output->write($activeFast->print(), 'green');
}
}
129 changes: 129 additions & 0 deletions App/Commands/CommandController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace App\Commands;

use App\Console\{InputConsole, InputValidator, OutputConsole};
use App\Interface\{BaseCommandInterface, FileManagerInterface};
use App\Model\Fast;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need of that much empty lines :)

class CommandController implements BaseCommandInterface
{

public bool $appRunning = true;

protected bool $activeFasts = false;

protected bool $canCreate = false;

protected bool $noCondition = true;

protected array $availableCommands = [];

private array $menu = [
[
'option' => 'Check the fast status',
'command' => CheckCommand::class,
'condition' => 'noCondition'
],
[
'option' => 'Create Fast',
'command' => CreateCommand::class,
'condition' => 'canCreate'
],
[
'option' => 'Update an active fast',
'command' => UpdateCommand::class,
'condition' => 'activeFasts',

],
[
'option' => 'End an active fast',
'command' => EndCommand::class,
'condition' => 'activeFasts',

],
[
'option' => 'List all fasts',
'command' => ListCommand::class,
'condition' => 'noCondition'
],
[
'option' => 'Exit',
'command' => ExitCommand::class,
'condition' => 'noCondition'
],

];

public function __construct(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need a constructor with empty body ?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The body of the constructor is empty because the properties of the class are defined in the entry parameters. According to PHP 8.0 documentation you can declare class properties in the constructor with no need of assigning them in the body PHP does it for you. Am i wrong ? Here is where i read that https://stitcher.io/blog/constructor-promotion-in-php-8

protected InputConsole $input,
protected OutputConsole $output,
protected FileManagerInterface $store,
protected InputValidator $validator,
protected Fast $newFast,
){}

public function run()
{
while ($this->appRunning) {
$this->updateActiveFastParameter();
$this->updateCanCreateParameter();
$this->adjustMenuAndPrint();
$input = $this->input->getInput();
if (key_exists($input, $this->menu)) {
/**
* @var $command BaseCommandInterface
*/
$command = new $this->availableCommands[$input](
$this->input,
$this->output,
$this->store,
$this->validator,
$this->newFast,
);
$command->run();
} else {
$this->output->write('Please select a specific command.', 'yellow');
}
}
}

public function adjustMenuAndPrint()
{
$counter = 0;
foreach ($this->menu as $key => $bundle) {
++$counter;
$condition = $bundle['condition'];
if ($this->{$condition}) {
$this->output->write("[" . $counter . "] " . $bundle['option']);
$this->availableCommands[$counter] = $bundle['command'];
} else {
$counter--;
}
}
}

/**
* @throws \Exception
*/
private function updateActiveFastParameter()
{
if ($this->store->hasActiveFasts()) {
$this->activeFasts = true;
return;
}
$this->activeFasts = false;
}

/**
* @throws \Exception
*/
private function updateCanCreateParameter()
{
if (!$this->store->hasActiveFasts()) {
$this->canCreate = true;
return;
}
$this->canCreate = false;
}
}
17 changes: 17 additions & 0 deletions App/Commands/CreateCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Commands;

use App\Interface\BaseCommandInterface;


class CreateCommand extends BaseCommandController implements BaseCommandInterface
{
public function run()
{
$this->getStartDate();
$this->getFastType();
$this->setFastEndDate();
$this->saveFast();
}
}
35 changes: 35 additions & 0 deletions App/Commands/EndCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Commands;

use App\Enums\Status;
use App\Interface\BaseCommandInterface;
use DateTime;

class EndCommand extends BaseCommandController implements BaseCommandInterface
{
public function run()
{
$today = new DateTime('NOW');
if ($activeFast = $this->store->getActiveFast()) {
$userInput = $this->askForConfirmation("Are you sure you want to end current active fast?");
while (!key_exists($userInput, $this->confirmationOptions)) {
$userInput = $this->input->getInput();
}
if (!$this->confirmationOptions[$userInput]) return;
// Once we have confirmation delete the current active fast from file.
$this->store->deleteActiveFast();
$activeFast->set([
'status' => Status::INACTIVE,
]);
if ($activeFast->start < $today) {
$activeFast->set([
'elapsedTime' => $today->diff($activeFast->start)
->format('%Y years %m months %d days %H h %i min %s sec')
]);
}
//Save the updated fast into file.
$this->save($activeFast);
}
}
}
29 changes: 29 additions & 0 deletions App/Commands/ExitCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace App\Commands;

use App\{Console\InputConsole,
Console\InputValidator,
Console\OutputConsole,
Interface\BaseCommandInterface,
Store\StoreManager,
Model\Fast};

class ExitCommand extends BaseCommandController implements BaseCommandInterface
{
public function __construct(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here no need of empty body constructors

protected InputConsole $input,
protected OutputConsole $output,
protected StoreManager $store,
protected InputValidator $validator,
protected Fast $newFast
){}

public function run()
{
$userInput = $this->askForConfirmation("Are you sure you want to exit the app?");
if (!$this->confirmationOptions[$userInput]) return;
$this->output->write('See you soon.. Goodbye....', 'green');
exit;
}
}
Loading