Completed
Push — master ( a7b3c5...a3697f )
by Christian
04:52 queued 11s
created

CloudCommandTrait   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 4

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
wmc 7
cbo 4
dl 0
loc 68
ccs 20
cts 22
cp 0.9091
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
doExecuteCommand() 0 1 ?
A configure() 0 10 1
A getCloudManager() 0 8 2
A getCloud() 0 8 2
A execute() 0 12 2
1
<?php
2
3
/*
4
 * This file is part of the XabbuhPandaBundle package.
5
 *
6
 * (c) Christian Flothmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Xabbuh\PandaBundle\Command;
13
14
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Xabbuh\PandaClient\Api\CloudManagerInterface;
21
use Xabbuh\PandaClient\Exception\PandaException;
22
23 1
if (class_exists(ContainerAwareCommand::class)) {
24
    /**
25
     * Base class of all commands which act on panda clouds.
26
     *
27
     * The cloud name can be specified on the command-line. If no cloud is
28
     * given the configured default cloud is used.
29
     *
30
     * @author Christian Flothmann <[email protected]>
31
     *
32
     * @internal since 1.5
33
     */
34
    abstract class CloudCommand extends ContainerAwareCommand
35
    {
36
        use CloudCommandTrait;
37
38
        private $cloudManager;
39
        private $container;
40
41
        public function __construct(CloudManagerInterface $cloudManager = null)
42
        {
43
            if (null === $cloudManager) {
44
                @trigger_error(sprintf('Not injecting a %s instance into the constructor of the %s class is deprecated since PandaBundle 1.5.', CloudManagerInterface::class, static::class), E_USER_DEPRECATED);
45
            }
46
47
            parent::__construct();
48
49
            $this->cloudManager = $cloudManager;
50
        }
51
52
        public function setContainer(ContainerInterface $container = null)
53
        {
54
            @trigger_error(sprintf('The %s() method is deprecated since PandaBundle 1.5.', __METHOD__), E_USER_DEPRECATED);
55
56
            parent::setContainer($container);
57
        }
58
59
        public function getContainer()
60
        {
61
            @trigger_error(sprintf('The %s() method is deprecated since PandaBundle 1.5.', __METHOD__), E_USER_DEPRECATED);
62
63
            return parent::getContainer();
64
        }
65
    }
66
} else {
67
    /**
68
     * Base class of all commands which act on panda clouds.
69
     *
70
     * The cloud name can be specified on the command-line. If no cloud is
71
     * given the configured default cloud is used.
72
     *
73
     * @author Christian Flothmann <[email protected]>
74
     *
75
     * @internal since 1.5
76
     */
77
    abstract class CloudCommand extends Command
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type Xabbuh\PandaBundle\Command\CloudCommand has been defined more than once; this definition is ignored, only the first definition in this file (L34-65) is considered.

This check looks for classes that have been defined more than once in the same file.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
78
    {
79
        use CloudCommandTrait;
80
81
        private $cloudManager;
82
        private $container;
83
84 86
        public function __construct(CloudManagerInterface $cloudManager = null)
85
        {
86 86
            if (null === $cloudManager) {
87
                @trigger_error(sprintf('Not injecting a %s instance into the constructor of the %s class is deprecated since PandaBundle 1.5.', CloudManagerInterface::class, static::class), E_USER_DEPRECATED);
88
            }
89
90 86
            parent::__construct();
91
92 86
            $this->cloudManager = $cloudManager;
93 86
        }
94
95
        public function setContainer(ContainerInterface $container = null)
96
        {
97
            @trigger_error(sprintf('The %s() method is deprecated since PandaBundle 1.5.', __METHOD__), E_USER_DEPRECATED);
98
99
            $this->container = $container;
100
        }
101
102
        public function getContainer()
103
        {
104
            @trigger_error(sprintf('The %s() method is deprecated since PandaBundle 1.5.', __METHOD__), E_USER_DEPRECATED);
105
106
            return $this->container;
107
        }
108
    }
109
}
110
111
/**
112
 * @internal
113
 */
114
trait CloudCommandTrait
115
{
116
    /**
117
     * {@inheritDoc}
118
     */
119 86
    protected function configure()
120
    {
121 86
        $this->setName(static::$defaultName); // BC with Symfony Console 3.3 and older not handling the property automatically
0 ignored issues
show
Bug introduced by
It seems like setName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
122 86
        $this->addOption(
0 ignored issues
show
Bug introduced by
It seems like addOption() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
123 86
            'cloud',
124 86
            '-c',
125 86
            InputOption::VALUE_REQUIRED,
126 86
            'Cloud on which the command is executed.'
127
        );
128 86
    }
129
130
    /**
131
     * @return \Xabbuh\PandaClient\Api\CloudManager
132
     */
133 67
    protected function getCloudManager()
134
    {
135 67
        if (null !== $this->cloudManager) {
136 67
            return $this->cloudManager;
137
        }
138
139
        return $this->getContainer()->get('xabbuh_panda.cloud_manager');
0 ignored issues
show
Bug introduced by
It seems like getContainer() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
140
    }
141
142
    /**
143
     * Get the cloud to work on.
144
     *
145
     * @param \Symfony\Component\Console\Input\InputInterface $input
146
     *
147
     * @return \Xabbuh\PandaClient\Api\CloudInterface
148
     */
149 67
    protected function getCloud(InputInterface $input)
150
    {
151 67
        if (null === $input->getOption('cloud')) {
152 67
            return $this->getCloudManager()->getDefaultCloud();
153
        }
154
155
        return $this->getCloudManager()->getCloud($input->getOption('cloud'));
156
    }
157
158
    /**
159
     * Executes the actual command (to be implemented by subclasses, will be called automatically).
160
     *
161
     * @param InputInterface  $input
162
     * @param OutputInterface $output
163
     */
164
    abstract protected function doExecuteCommand(InputInterface $input, OutputInterface $output);
165
166
    /**
167
     * {@inheritDoc}
168
     */
169 69
    protected function execute(InputInterface $input, OutputInterface $output)
170
    {
171
        try {
172 69
            $this->doExecuteCommand($input, $output);
173
174 40
            return 0;
175 29
        } catch (PandaException $e) {
176 29
            $output->writeln(sprintf('<error>An error occurred: %s</error>', $e->getMessage()));
177
178 29
            return 1;
179
        }
180
    }
181
}
182