Completed
Pull Request — master (#1)
by Jim
08:57
created

TaskCommand::execute()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
c 0
b 0
f 0
rs 8.5806
cc 4
eloc 15
nc 6
nop 2
1
<?php
2
3
namespace Jarobe\TaskRunner\Command;
4
5
use Jarobe\TaskRunner\Entity\TaskEvent;
6
use Jarobe\TaskRunner\Manager\TaskEventManager;
7
use Jarobe\TaskRunner\Manager\TaskManager;
8
use Jarobe\TaskRunner\Model\TaskBuilder;
9
use Jarobe\TaskRunner\TaskType\TaskTypeInterface;
10
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Validator\ConstraintViolationInterface;
14
use Symfony\Component\Validator\Validator\ValidatorInterface;
15
16
abstract class TaskCommand extends ContainerAwareCommand
17
{
18
    /** @var TaskEventManager */
19
    private $taskEventManager;
20
21
    /** @var TaskManager */
22
    private $taskManager;
23
24
    /** @var ValidatorInterface */
25
    private $validator;
26
27
    public function initialize(InputInterface $input, OutputInterface $output)
28
    {
29
        parent::initialize($input, $output);
30
        $container = $this->getContainer();
31
        $this->taskEventManager = $container->get('jarobe.task_runner.task_event_manager');
32
        $this->taskManager = $container->get('jarobe.task_runner.task_manager');
33
        $this->validator = $container->get('validator');
34
    }
35
36
    /**
37
     * @param InputInterface $input
38
     * @param OutputInterface $output
39
     * @return TaskEvent
40
     */
41
    public function execute(InputInterface $input, OutputInterface $output)
42
    {
43
        $taskBuilder = new TaskBuilder();
44
45
        $taskBuilder = $this->buildTaskBuilder($taskBuilder, $input);
46
47
        $validationErrors = $this->validateTask($taskBuilder->getTask());
48
        foreach ($validationErrors as $validationError) {
49
            $taskBuilder->addError($validationError);
50
        }
51
52
        if ($taskBuilder->hasErrors()) {
53
            foreach ($taskBuilder->getErrors() as $error) {
54
                $output->writeln("<error>".$error."</error>");
55
            }
56
            return null;
57
        }
58
59
        //Create the TaskEvent
60
        $taskEvent = $this->taskEventManager->createTaskEvent($taskBuilder->getTask());
61
62
        $this->preProcess($taskEvent, $input, $output);
63
64
        $taskEvent = $this->taskManager->process($taskEvent);
65
66
        $this->postProcess($taskEvent, $input, $output);
67
68
        return $taskEvent;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $taskEvent; (Jarobe\TaskRunner\Entity\TaskEvent) is incompatible with the return type of the parent method Symfony\Component\Console\Command\Command::execute of type null|integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

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

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
69
    }
70
71
    /**
72
     * @param TaskBuilder $taskBuilder
73
     * @param InputInterface $input
74
     * @return TaskBuilder
75
     */
76
    abstract protected function buildTaskBuilder(TaskBuilder $taskBuilder, InputInterface $input);
77
78
    /**
79
     * Overwrite this function if you want to do something before we process the TaskEvent
80
     * @param TaskEvent $taskEvent
81
     * @param InputInterface $input
82
     * @param OutputInterface $output
83
     */
84
    protected function prepareTaskEvent(TaskEvent $taskEvent, InputInterface $input, OutputInterface $output)
3 ignored issues
show
Unused Code introduced by
The parameter $taskEvent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $output is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
85
    {
86
    }
87
88
    /**
89
     * Overwrite this function if you want to do something before we process the TaskEvent
90
     * @param TaskEvent $taskEvent
91
     * @param InputInterface $input
92
     * @param OutputInterface $output
93
     */
94
    protected function preProcess(TaskEvent $taskEvent, InputInterface $input, OutputInterface $output)
3 ignored issues
show
Unused Code introduced by
The parameter $taskEvent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $output is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
95
    {
96
    }
97
98
    /**
99
     * Overwrite this function if you want to do something before we process the TaskEvent
100
     * @param TaskEvent $taskEvent
101
     * @param InputInterface $input
102
     * @param OutputInterface $output
103
     */
104
    protected function postProcess(TaskEvent $taskEvent, InputInterface $input, OutputInterface $output)
3 ignored issues
show
Unused Code introduced by
The parameter $taskEvent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $output is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
    {
106
    }
107
108
    /**
109
     * @param TaskTypeInterface $task
110
     * @return array
111
     */
112
    protected function validateTask(TaskTypeInterface $task)
113
    {
114
        $validationErrors = [];
115
        $validationErrorList = $this->validator->validate($task);
116
        /** @var ConstraintViolationInterface $error */
117
        foreach($validationErrorList as $error){
118
            $validationErrors[] = sprintf("%s: %s", $error->getPropertyPath(), $error->getMessage());
119
        }
120
        return $validationErrors;
121
    }
122
}
123