Skip to content

Commit c4d578d

Browse files
hjuarez20enzolutions
authored andcommitted
[console] Implement statistics feature (#342)
* [console] Implement statistics feature * [statistics] Change statistics config location * [statistics] Remove getStatisticsDirectory * [statistics] Use fgetcsv function * [statistics] Remove statistics after success response * [statistics] Add validation to custom commands. * [statistics] Remove var_dump from saveStatistics class * [statistics] Add validation is finder count is 0 * [config] Add statistics to console config * [configManager] Change getConfigGlobalAsArray function * [settings:set] Add missing message to success execution * [statistics] Add more condition to send info * [statistics] Change count-attempted to times-attempted * [statistics] Delete the error message for failed attempted * [statistics] Add validation if there is not config file * Add url to config.yml to send data
1 parent 4914556 commit c4d578d

File tree

12 files changed

+559
-35
lines changed

12 files changed

+559
-35
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
"symfony/yaml": "~2.8|~3.0",
5353
"twig/twig": "^1.23.1",
5454
"webflo/drupal-finder": "^1.0",
55-
"webmozart/path-util": "^2.3"
55+
"webmozart/path-util": "^2.3",
56+
"guzzlehttp/guzzle": "~6.1"
5657
},
5758
"minimum-stability": "dev",
5859
"prefer-stable": true,

config/config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
application:
2+
statistics:
3+
enabled: false
4+
last-attempted: ~
5+
times-attempted: 0
26
language: 'en'
37
autowire:
48
commands:

services.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ services:
105105
# DrupalConsoleCore Generators
106106
console.init_generator:
107107
class: Drupal\Console\Core\Generator\InitGenerator
108+
arguments: ['@console.configuration_manager']
108109
tags:
109110
- { name: drupal.generator }
110111
console.site_alias_generator:

src/Application.php

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Drupal\Console\Core;
44

5+
use Drupal\Console\Core\EventSubscriber\SendStatisticsListener;
56
use Drupal\Console\Core\EventSubscriber\RemoveMessagesListener;
7+
use Drupal\Console\Core\EventSubscriber\SaveStatisticsListener;
68
use Drupal\Console\Core\EventSubscriber\ShowGenerateCountCodeLinesListener;
79
use Drupal\Console\Core\Utils\TranslatorManagerInterface;
810
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -305,6 +307,21 @@ private function registerEvents()
305307
)
306308
);
307309

310+
$dispatcher->addSubscriber(
311+
new SaveStatisticsListener(
312+
$this->container->get('console.count_code_lines'),
313+
$this->container->get('console.configuration_manager'),
314+
$this->container->get('console.translator_manager')
315+
)
316+
);
317+
318+
$dispatcher->addSubscriber(
319+
new SendStatisticsListener(
320+
$this->container->get('console.configuration_manager'),
321+
$this->container->get('console.translator_manager')
322+
)
323+
);
324+
308325
$dispatcher->addSubscriber(
309326
new RemoveMessagesListener(
310327
$this->container->get('console.message_manager')
@@ -714,7 +731,9 @@ public function getData($filterNamespaces = null, $excludeNamespaces = [], $excl
714731
$namespaces = array_diff($namespaces, $excludeNamespaces);
715732

716733
// filter namespaces if available
717-
if($filterNamespaces) $namespaces = array_intersect($namespaces, $filterNamespaces);
734+
if ($filterNamespaces) {
735+
$namespaces = array_intersect($namespaces, $filterNamespaces);
736+
}
718737

719738
foreach ($namespaces as $namespace) {
720739
$commands = $this->all($namespace);
@@ -726,8 +745,8 @@ public function getData($filterNamespaces = null, $excludeNamespaces = [], $excl
726745

727746
foreach ($commands as $command) {
728747
// Exclude command if is a chain command and was requested to exclude chain commands
729-
if($excludeChainCommands && $command instanceof ChainCustomCommand) {
730-
continue;
748+
if ($excludeChainCommands && $command instanceof ChainCustomCommand) {
749+
continue;
731750
}
732751

733752
if (method_exists($command, 'getModule')) {
@@ -745,9 +764,11 @@ public function getData($filterNamespaces = null, $excludeNamespaces = [], $excl
745764
}
746765

747766
// Remove namepsaces without commands
748-
$namespaces = array_filter($namespaces, function($namespace) use( $data) {
749-
return count($data['commands'][$namespace]) > 0;
750-
});
767+
$namespaces = array_filter(
768+
$namespaces, function ($namespace) use ($data) {
769+
return count($data['commands'][$namespace]) > 0;
770+
}
771+
);
751772

752773
$input = $this->getDefinition();
753774
$options = [];
@@ -894,7 +915,8 @@ public function getContainer()
894915
/**
895916
* Add Drupal system messages.
896917
*/
897-
protected function addDrupalMessages($messageManager) {
918+
protected function addDrupalMessages($messageManager)
919+
{
898920
if (function_exists('drupal_get_messages')) {
899921
$drupalMessages = drupal_get_messages();
900922
foreach ($drupalMessages as $type => $messages) {
@@ -915,13 +937,14 @@ protected function addDrupalMessages($messageManager) {
915937
* @return string
916938
* Name of the method
917939
*/
918-
protected function getMessageMethod($type) {
940+
protected function getMessageMethod($type)
941+
{
919942
$methodName = 'info';
920943
switch ($type) {
921-
case 'error':
922-
case 'warning':
923-
$methodName = $type;
924-
break;
944+
case 'error':
945+
case 'warning':
946+
$methodName = $type;
947+
break;
925948
}
926949

927950
return $methodName;

src/Command/InitCommand.php

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ class InitCommand extends Command
5656
'sites' => false,
5757
'learning' => false,
5858
'generate_inline' => false,
59-
'generate_chain' => false
59+
'generate_chain' => false,
60+
'statistics' => true
6061
];
6162

6263
private $directories = [
@@ -192,6 +193,27 @@ protected function interact(InputInterface $input, OutputInterface $output)
192193
);
193194
$input->setOption('autocomplete', $autocomplete);
194195
}
196+
197+
$this->getIo()->commentBlock(
198+
sprintf(
199+
$this->trans('commands.init.messages.statistics'),
200+
sprintf(
201+
'%sconfig.yml',
202+
$this->configurationManager->getConsoleDirectory()
203+
)
204+
)
205+
);
206+
207+
$this->configParameters['statistics'] = $this->getIo()->confirm(
208+
$this->trans('commands.init.questions.statistics'),
209+
true
210+
);
211+
212+
if ($this->configParameters['statistics']) {
213+
$this->getIo()->commentBlock(
214+
$this->trans('commands.init.messages.statistics-disable')
215+
);
216+
}
195217
}
196218

197219
/**
@@ -269,13 +291,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
269291
$process->stop();
270292
}
271293

272-
$this->generator->generate([
273-
'user_home' => $this->configurationManager->getConsoleDirectory(),
274-
'executable_name' => $executableName,
275-
'override' => $override,
276-
'destination' => $destination,
277-
'config_parameters' => $this->configParameters,
278-
]);
294+
$this->generator->generate(
295+
[
296+
'user_home' => $this->configurationManager->getConsoleDirectory(),
297+
'executable_name' => $executableName,
298+
'override' => $override,
299+
'destination' => $destination,
300+
'config_parameters' => $this->configParameters,
301+
]
302+
);
279303

280304
$this->getIo()->writeln($this->trans('application.messages.autocomplete'));
281305

src/Command/Settings/SetCommand.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ protected function execute(InputInterface $input, OutputInterface $output)
8282
$settingName = $input->getArgument('name');
8383
$settingValue = $input->getArgument('value');
8484

85+
// Reset the default values ​​of the statistics.
86+
if ($settingName == 'statistics.enabled') {
87+
$this->configurationManager->updateConfigGlobalParameter(
88+
'statistics.last-attempted',
89+
null
90+
);
91+
$this->configurationManager->updateConfigGlobalParameter(
92+
'statistics.times-attempted',
93+
0
94+
);
95+
}
96+
8597
$userConfigFile = sprintf(
8698
'%s/.console/config.yml',
8799
$this->configurationManager->getHomeDirectory()
@@ -111,6 +123,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
111123
}
112124

113125
$parents = array_merge(['application'], explode(".", $settingName));
126+
// Change the value type if it is boolean.
127+
$settingValue = json_decode($settingValue) === null ? $settingValue : json_decode($settingValue);
114128

115129
$this->nestedArray->setValue(
116130
$userConfigFileParsed,
@@ -163,6 +177,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
163177
return 1;
164178
}
165179

180+
$settingValue = is_bool($settingValue) ? $settingValue ? 'true' : 'false' : $settingValue;
166181
$this->getIo()->success(
167182
sprintf(
168183
$this->trans('commands.settings.set.messages.success'),
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Contains \Drupal\Console\Core\EventSubscriber\SaveStatisticsListener.
6+
*/
7+
8+
namespace Drupal\Console\Core\EventSubscriber;
9+
10+
use Drupal\Console\Core\Command\Chain\ChainCustomCommand;
11+
use Drupal\Console\Core\Utils\ConfigurationManager;
12+
use Drupal\Console\Core\Utils\CountCodeLines;
13+
use Drupal\Console\Core\Utils\TranslatorManagerInterface;
14+
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
15+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16+
use Symfony\Component\Console\ConsoleEvents;
17+
use Symfony\Component\Filesystem\Filesystem;
18+
19+
/**
20+
* Class SaveStatisticsListener
21+
*
22+
* @package Drupal\Console\Core\EventSubscriber
23+
*/
24+
class SaveStatisticsListener implements EventSubscriberInterface
25+
{
26+
27+
/**
28+
* @var ShowGenerateChainListener
29+
*/
30+
protected $countCodeLines;
31+
32+
/**
33+
* @var ConfigurationManager
34+
*/
35+
protected $configurationManager;
36+
37+
/**
38+
* @var TranslatorManagerInterface
39+
*/
40+
protected $translator;
41+
42+
/**
43+
* FileSystem $fs
44+
*/
45+
protected $fs;
46+
47+
/**
48+
* SaveStatisticsListener constructor.
49+
*
50+
* @param CountCodeLines $countCodeLines
51+
* @param ConfigurationManager $configurationManager
52+
* @param TranslatorManagerInterface $translator
53+
*/
54+
public function __construct(
55+
CountCodeLines $countCodeLines,
56+
ConfigurationManager $configurationManager,
57+
TranslatorManagerInterface $translator
58+
) {
59+
$this->countCodeLines = $countCodeLines;
60+
$this->configurationManager = $configurationManager;
61+
$this->translator = $translator;
62+
63+
$this->fs = new Filesystem();
64+
}
65+
66+
/**
67+
* @param ConsoleTerminateEvent $event
68+
*/
69+
public function saveStatistics(ConsoleTerminateEvent $event)
70+
{
71+
if ($event->getExitCode() != 0) {
72+
return;
73+
}
74+
75+
$configGlobalAsArray = $this->configurationManager->getConfigGlobalAsArray();
76+
77+
//Validate if the config is enable.
78+
if (is_null($configGlobalAsArray) || !$configGlobalAsArray['application']['statistics']['enabled']) {
79+
return;
80+
}
81+
82+
//Check that the namespace starts with 'Drupal\Console'.
83+
$class = new \ReflectionClass($event->getCommand());
84+
if (strpos($class->getNamespaceName(), "Drupal\Console") !== 0) {
85+
return;
86+
}
87+
88+
//Validate if the command is not a custom chain command.
89+
if ($event->getCommand() instanceof ChainCustomCommand) {
90+
return;
91+
}
92+
93+
$path = $path = sprintf(
94+
'%s/.console/stats/',
95+
$this->configurationManager->getHomeDirectory()
96+
);
97+
98+
$information = $event->getCommand()->getName() . ',' . $this->translator->getLanguage();
99+
100+
$countCodeLines = $this->countCodeLines->getCountCodeLines();
101+
if ($countCodeLines > 0) {
102+
$information = $information . ',' . $countCodeLines;
103+
}
104+
105+
106+
$this->fs->appendToFile(
107+
$path . date('Y-m-d') . '.csv',
108+
$information . PHP_EOL
109+
);
110+
}
111+
112+
/**
113+
* @{@inheritdoc}
114+
*/
115+
public static function getSubscribedEvents()
116+
{
117+
return [ConsoleEvents::TERMINATE => 'saveStatistics'];
118+
}
119+
}

0 commit comments

Comments
 (0)