1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace yiicod\listener\commands; |
4
|
|
|
|
5
|
|
|
use ReflectionClass; |
6
|
|
|
use ReflectionException; |
7
|
|
|
use Yii; |
8
|
|
|
use yii\base\UnknownClassException; |
9
|
|
|
use yii\console\Controller; |
10
|
|
|
use yii\helpers\Console; |
11
|
|
|
|
12
|
|
|
class Listener extends Controller |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* Default action |
16
|
|
|
* |
17
|
|
|
* @var string |
18
|
|
|
*/ |
19
|
|
|
public $defaultAction = 'parse'; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Mapping folder alias to listener |
23
|
|
|
*vi Pa |
24
|
|
|
* |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
public $inAliases = [ |
28
|
|
|
'@frontend' => '@frontend/config/listeners.php', |
29
|
|
|
'@backend' => '@backend/config/listeners.php', |
30
|
|
|
'@console' => '@console/config/listeners.php', |
31
|
|
|
'@common' => '@common/config/listeners.php', |
32
|
|
|
]; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Excluded folders |
36
|
|
|
* |
37
|
|
|
* @var array |
38
|
|
|
*/ |
39
|
|
|
public $excluded = [ |
40
|
|
|
'tests', |
41
|
|
|
]; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Parse application |
45
|
|
|
*/ |
46
|
|
|
public function actionParse() |
47
|
|
|
{ |
48
|
|
|
foreach ($this->inAliases as $alias => $listener) { |
49
|
|
|
$finder = new \Symfony\Component\Finder\Finder(); |
50
|
|
|
$finder->files()->name('*.php') |
51
|
|
|
->files() |
52
|
|
|
->exclude($this->excluded) |
53
|
|
|
->in(Yii::getAlias($alias)); |
|
|
|
|
54
|
|
|
$data = []; |
55
|
|
|
|
56
|
|
|
$step = 100 / $finder->count(); |
57
|
|
|
$percent = 0; |
58
|
|
|
foreach ($finder as $file) { |
59
|
|
|
$percent += $step; |
60
|
|
|
$this->progress($percent); |
61
|
|
|
|
62
|
|
|
if (false === strpos(file_get_contents($file->getPathname()), sprintf('class %s', $file->getBasename('.php')))) { |
63
|
|
|
continue; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
$className = str_replace('@', '\\', $alias) . str_replace([Yii::getAlias($alias), '/', '.php'], ['', '\\', ''], $file->getPathname()); |
67
|
|
|
|
68
|
|
|
try { |
69
|
|
|
if (false === @class_exists($className)) { |
70
|
|
|
continue; |
71
|
|
|
} |
72
|
|
|
} catch (UnknownClassException $e) { |
73
|
|
|
$this->stdout($e->getMessage() . "\n", Console::FG_RED); |
74
|
|
|
continue; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
try { |
78
|
|
|
$r = new ReflectionClass($className); |
79
|
|
|
} catch (ReflectionException $e) { |
80
|
|
|
$this->stdout($e->getMessage() . "\n", Console::FG_RED); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
if (in_array('yiicod\listener\components\listeners\ListenerInterface', $r->getInterfaceNames()) && false === $r->isAbstract() && false === empty($className::event())) { |
84
|
|
|
$data[$className::priority()][$className::event()][] = [$className, 'on']; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
if (in_array('yiicod\listener\components\subscribers\SubscriberInterface', $r->getInterfaceNames()) && false === $r->isAbstract()) { |
88
|
|
|
$events = $className::subscribe(); |
89
|
|
|
foreach ($events as $event => $method) { |
90
|
|
|
if (false === empty($event)) { |
91
|
|
|
$data[$className::priority()][$event][] = [$className, $method]; |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
$this->exportListener($data, Yii::getAlias($listener)); |
98
|
|
|
|
99
|
|
|
$this->stdout(sprintf("Exported to %s \n", $listener), Console::FG_GREEN); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Render progress message |
105
|
|
|
*/ |
106
|
|
|
private function progress($percent) |
107
|
|
|
{ |
108
|
|
|
Console::stdout(sprintf("\rProgress: %s ", round($percent))); |
109
|
|
|
Console::clearLineAfterCursor(); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Export listener |
114
|
|
|
* |
115
|
|
|
* @param $data |
116
|
|
|
* @param $listenerFile |
117
|
|
|
*/ |
118
|
|
|
public function exportListener($data, $listenerFile) |
119
|
|
|
{ |
120
|
|
|
$array = str_replace("\r", '', var_export($data, true)); |
121
|
|
|
$content = <<<EOD |
122
|
|
|
<?php |
123
|
|
|
/** |
124
|
|
|
* Events list. |
125
|
|
|
* |
126
|
|
|
* This file is automatically generated by 'yii listenersParse\index' command. |
127
|
|
|
* |
128
|
|
|
* NOTE, this file must be saved in UTF-8 encoding. |
129
|
|
|
*/ |
130
|
|
|
return $array; |
131
|
|
|
|
132
|
|
|
EOD; |
133
|
|
|
file_put_contents($listenerFile, $content); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.