Maintenance::maintenanceOff()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php namespace Tequilarapido\Cli\Commands;
2
3
use Datum\Datum;
4
use Symfony\Component\Console\Input\InputArgument;
5
use Symfony\Component\Console\Input\InputInterface;
6
use Symfony\Component\Console\Input\InputOption;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Filesystem\Filesystem;
9
use Tequilarapido\Cli\Commands\Base\AbstractCommand;
10
11
class Maintenance extends AbstractCommand
12
{
13
    const ARGUMENT_MODE = 'mode';
14
    const OPTION_DONT_CHECK_DIRECTORY = 'dont-check-directory';
15
    const MODE_OFF = 'off';
16
    const MODE_ON = 'on';
17
    const MODE_STATUS = 'status';
18
    const MAINTENANCE_FILE = '.maintenance';
19
20
    protected $mode = '';
21
22
    protected function configure()
23
    {
24
        parent::configure();
25
26
        $description = '';
27
        $description .= 'Can be used to take put the application in maintenance mode and bring it live again. ' . PHP_EOL;
28
        $description .= 'It add a maintenance file on the application root. It is up to the application to use it. ' . PHP_EOL;
29
30
        $this
31
            ->setName('maintenance')
32
            ->setDescription($description)
33
            ->addArgument(
34
                self::ARGUMENT_MODE,
35
                InputArgument::OPTIONAL,
36
                'mode=off : remove maintenance mode or mode=off : put the application uin maintenance mode ',
37
                null
38
            )->addOption(
39
                static::OPTION_DONT_CHECK_DIRECTORY,
40
                null,
41
                InputOption::VALUE_NONE,
42
                'Will not check if we are on wordpress directory. Useful for running tests.'
43
            );
44
45
46
    }
47
48
    protected function execute(InputInterface $input, OutputInterface $output)
49
    {
50
        parent::execute($input, $output);
51
52
        // Don't check directory if requested
53
        if (!$this->input->getOption(static::OPTION_DONT_CHECK_DIRECTORY)) {
54
            $this->checkExecutionDirectory();
55
        }
56
57
        // Parse mode and execute related command
58
        $this->parseMode($input->getArgument(self::ARGUMENT_MODE));
59
        if (static::MODE_ON === $this->mode) {
60
            $this->maintenanceOn();
61
        } elseif (static::MODE_OFF === $this->mode) {
62
            $this->maintenanceOff();
63
        } else {
64
            $this->maintenanceStatus();
65
        }
66
    }
67
68
    protected function maintenanceOn()
69
    {
70
        $fs = new Filesystem();
71
        $this->output->info('Maintenance mode is now on');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Output\OutputInterface as the method info() does only exist in the following implementations of said interface: Tequilarapido\Cli\EnhancedOutput.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
72
        $fs->touch($this->getMaintenanceFile());
73
    }
74
75
    protected function maintenanceOff()
76
    {
77
        $fs = new Filesystem();
78
        $fs->remove($this->getMaintenanceFile());
79
        $this->output->info('Maintenance mode is now off');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Output\OutputInterface as the method info() does only exist in the following implementations of said interface: Tequilarapido\Cli\EnhancedOutput.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
80
    }
81
82
    protected function maintenanceStatus()
83
    {
84
        $fs = new Filesystem();
85
        $currentMode = $fs->exists($this->getMaintenanceFile()) ? static::MODE_ON : static::MODE_OFF;
86
87
        // Since ?
88
        $since = '';
89
        if ($currentMode == static::MODE_ON) {
90
            $since = Datum::createFromTimestamp(filemtime($this->getMaintenanceFile()))->diffForHumans();
91
            $since = " (activated $since)";
92
        }
93
94
        $this->output->info("Current Maintenance mode : $currentMode $since");
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Output\OutputInterface as the method info() does only exist in the following implementations of said interface: Tequilarapido\Cli\EnhancedOutput.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
95
    }
96
97
    protected function checkExecutionDirectory()
98
    {
99
        $fs = new Filesystem();
100
        $cwd = $this->getProjectDirectory();
101
102
        // Is it wordpress dir ?
103
        $wordpressDir = $fs->exists(array($cwd . 'wp-admin', $cwd . 'wp-includes'));
104
105
        // Is it appcli project dir (pass for test and dev) ?
106
        $wpcliprojectDir = $fs->exists(array($cwd . 'bin', $cwd . 'src/Teq/Tasks/Command/Maintenance.php', $cwd . 'box.json.dist'));
107
108
109
        if (!$wordpressDir && !$wpcliprojectDir) {
110
            $this->output->error("You must be on the Doc root (wordpress directory : we cannot find wp-admin or wp-includes directory for instance.)");
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Output\OutputInterface as the method error() does only exist in the following implementations of said interface: Tequilarapido\Cli\EnhancedOutput.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
111
        }
112
113
    }
114
115
    protected function parseMode($mode)
116
    {
117
        if (is_null($mode)) {
118
            $mode = static::MODE_STATUS;
119
        }
120
121
        if (in_array(strtolower($mode), array(static::MODE_ON, static::MODE_OFF, static::MODE_STATUS))) {
122
            $this->mode = $mode;
123
        } else {
124
            $this->output->error('Unknown mode.');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Output\OutputInterface as the method error() does only exist in the following implementations of said interface: Tequilarapido\Cli\EnhancedOutput.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
125
        }
126
    }
127
128
    protected function getProjectDirectory()
129
    {
130
        return getcwd() . '/';
131
    }
132
133
    protected function getMaintenanceFile()
134
    {
135
        return $this->getProjectDirectory() . static::MAINTENANCE_FILE;
136
    }
137
138
}