Completed
Push — master ( aa9657...bb9832 )
by Sebastian
05:21
created

PHP::createAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * This file is part of CaptainHook.
4
 *
5
 * (c) Sebastian Feldmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace SebastianFeldmann\CaptainHook\Runner\Action;
11
12
use SebastianFeldmann\CaptainHook\Config;
13
use SebastianFeldmann\CaptainHook\Console\IO;
14
use SebastianFeldmann\CaptainHook\Exception\ActionFailed;
15
use SebastianFeldmann\CaptainHook\Hook\Action;
16
use SebastianFeldmann\Git\Repository;
17
18
/**
19
 * Class PHP
20
 *
21
 * @package CaptainHook
22
 * @author  Sebastian Feldmann <[email protected]>
23
 * @link    https://github.com/sebastianfeldmann/captainhook
24
 * @since   Class available since Release 0.9.0
25
 */
26
class PHP implements Action
27
{
28
    /**
29
     * Execute the configured action.
30
     *
31
     * @param  \SebastianFeldmann\CaptainHook\Config         $config
32
     * @param  \SebastianFeldmann\CaptainHook\Console\IO     $io
33
     * @param  \SebastianFeldmann\Git\Repository             $repository
34
     * @param  \SebastianFeldmann\CaptainHook\Config\Action  $action
35
     * @throws \SebastianFeldmann\CaptainHook\Exception\ActionFailed
36
     */
37 7
    public function execute(Config $config, IO $io, Repository $repository, Config\Action $action)
38
    {
39 7
        $class = $action->getAction();
40
41
        try {
42 7
            if ($this->isStaticMethodCall($class)) {
43 3
                $io->write($this->executeStatic($class));
44
            } else {
45 4
                $exe = $this->createAction($class);
46 4
                $exe->execute($config, $io, $repository, $action);
47
            }
48 5
        } catch (\Exception $e) {
49 4
            throw ActionFailed::withMessage('Execution failed: ' . $e->getMessage());
50 1
        } catch (\Error $e) {
51 1
            throw ActionFailed::withMessage('PHP Error: ' . $e->getMessage());
52
        }
53 2
    }
54
55
    /**
56
     * Execute static method call and return its output.
57
     *
58
     * @param  string $class
59
     * @return string
60
     */
61 3
    protected function executeStatic(string $class) : string
62
    {
63 3
        list($class, $method) = explode('::', $class);
64 3
        if (!class_exists($class)) {
65 1
            throw new \RuntimeException('could not find class: ' . $class);
66
        }
67 2
        if (!method_exists($class, $method)) {
68 1
            throw new \RuntimeException('could not find method in class: ' . $method);
69
        }
70 1
        ob_start();
71 1
        $class::$method();
72 1
        return ob_get_clean();
73
    }
74
75
    /**
76
     * Create an action instance.
77
     *
78
     * @param  string $class
79
     * @return \SebastianFeldmann\CaptainHook\Hook\Action
80
     * @throws \SebastianFeldmann\CaptainHook\Exception\ActionFailed
81
     */
82 4
    protected function createAction(string $class) : Action
83
    {
84 4
        $action = new $class();
85 4
        if (!$action instanceof Action) {
86 1
            throw ActionFailed::withMessage(
87 1
                'PHP class ' . $class . ' has to implement the \'Action\' interface'
88
            );
89
        }
90 3
        return $action;
91
    }
92
93
    /**
94
     * Is this a static method call.
95
     *
96
     * @param  string $class
97
     * @return bool
98
     */
99 7
    protected function isStaticMethodCall(string $class) : bool
100
    {
101 7
        return (bool)preg_match('#^\\\\.+::.+$#i', $class);
102
    }
103
}
104