CommandListener::onCommand()   C
last analyzed

Complexity

Conditions 8
Paths 7

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 34
ccs 0
cts 27
cp 0
rs 5.3846
cc 8
eloc 23
nc 7
nop 1
crap 72
1
<?php
2
3
namespace Jns\Bundle\XhprofBundle\EventListener;
4
5
use Symfony\Component\Console\Event\ConsoleCommandEvent;
6
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
7
use Symfony\Component\Console\Input\InputOption;
8
use Symfony\Component\DependencyInjection\ContainerInterface;
9
use Jns\Bundle\XhprofBundle\DataCollector\XhprofCollector;
10
11
/**
12
 * A command listener to profile command runs.
13
 *
14
 * The methods must be connected to the console.command and console.terminate
15
 * events.
16
 *
17
 * @author David Buchmann <[email protected]>
18
 */
19
class CommandListener
20
{
21
    private $collector;
22
    private $container;
23
    private $optionName;
24
    private $mode;
25
    private $filters = array();
26
    private $webLocation;
27
28
    public function __construct(XhprofCollector $collector, ContainerInterface $container)
29
    {
30
        $this->collector = $collector;
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * @param string $mode on|off|option
36
     */
37
    public function setEnabled($mode)
38
    {
39
        $this->mode = $mode;
40
    }
41
42
    /**
43
     * @param string $option name of the cli option for enabled mode "option"
44
     */
45
    public function setOptionName($option)
46
    {
47
        $this->optionName = $option;
48
    }
49
50
    /**
51
     * @param array $excludes List of regular expressions for command names to exclude
52
     */
53
    public function setFilters(array $excludes)
54
    {
55
        $this->filters = $excludes;
56
    }
57
58
    /**
59
     * Configure the base url to the xhprof web gui.
60
     *
61
     * @param string $webLocation
62
     */
63
    public function setWebLocation($webLocation)
64
    {
65
        $this->webLocation = $webLocation;
66
    }
67
68
    /**
69
     * We need to add the profile enable option to all commands if we are in
70
     * the parameter mode.
71
     *
72
     * Inspired by
73
     * http://php-and-symfony.matthiasnoback.nl/2013/11/symfony2-add-a-global-option-to-console-commands-and-generate-pid-file/
74
     *
75
     * @param ConsoleCommandEvent $event
76
     * @return mixed
77
     */
78
    private function isProfileOption(ConsoleCommandEvent $event)
79
    {
80
        $definition = $event->getCommand()->getDefinition();
81
82
        $definition->addOption(
83
            new InputOption($this->optionName, null, InputOption::VALUE_NONE, '<info>JnsXhprofBundle</info>: Whether to profile this command with xhprof', null)
84
        );
85
86
        $input = $event->getInput();
87
        $input->bind($definition);
88
89
        return $input->getOption($this->optionName);
90
    }
91
92
    /**
93
     * Start the profiler if
94
     * - we are not running the list or help command
95
     * - the command mode is on
96
     * - or the command mode if option and the option is specified
97
     *
98
     * @param ConsoleCommandEvent $event
99
     */
100
    public function onCommand(ConsoleCommandEvent $event)
101
    {
102
        $command = $event->getCommand()->getName();
103
        $system = array(
104
            'list',
105
            'help',
106
            'assetic:dump',
107
            'assets:install',
108
            'config:dump-reference',
109
            'container:debug',
110
            'router:debug',
111
            'cache:clear',
112
            'cache:warmup',
113
            'cache:create-cache-class',
114
        );
115
        if (in_array($command, $system)) {
116
            return;
117
        }
118
        if ('off' == $this->mode ||
119
            'option' == $this->mode && !$this->isProfileOption($event)) {
120
            return;
121
        }
122
123
        foreach ($this->filters as $exclude) {
124
            if (preg_match('@' . $exclude . '@', $command)) {
125
                return;
126
            }
127
        }
128
129
130
        if ($this->collector->startProfiling()) {
131
            $event->getOutput()->writeln("XHProf starting run\n---");
132
        }
133
    }
134
135
    /**
136
     * Trigger the collector to end the request and output the xhprof link if
137
     * we where collecting.
138
     *
139
     * @param ConsoleTerminateEvent $event
140
     */
141
    public function onTerminate(ConsoleTerminateEvent $event)
142
    {
143
        $command = $event->getCommand();
144
        $link = $this->collector->stopProfiling('cli', $command->getName());
145
        if (false === $link) {
146
            return;
147
        }
148
149
150
        $event->getOutput()->writeln(sprintf(
151
            "\n---\nXHProf run link <info>%s</info>",
152
            $this->collector->getXhprofUrl()
153
        ));
154
    }
155
}
156