commands/Listener.php
<?php
namespace yiicod\listener\commands;
use ReflectionClass;
use ReflectionException;
use Yii;
use yii\base\UnknownClassException;
use yii\console\Controller;
use yii\helpers\Console;
class Listener extends Controller
{
/**
* Default action
*
* @var string
*/
public $defaultAction = 'parse';
/**
* Mapping folder alias to listener
*vi Pa
*
* @var array
*/
public $inAliases = [
'@frontend' => '@frontend/config/listeners.php',
'@backend' => '@backend/config/listeners.php',
'@console' => '@console/config/listeners.php',
'@common' => '@common/config/listeners.php',
];
/**
* Excluded folders
*
* @var array
*/
public $excluded = [
'tests',
];
/**
* Parse application
*/
public function actionParse()
{
foreach ($this->inAliases as $alias => $listener) {
$finder = new \Symfony\Component\Finder\Finder();
$finder->files()->name('*.php')
->files()
->exclude($this->excluded)
->in(Yii::getAlias($alias));
$data = [];
$step = 100 / $finder->count();
$percent = 0;
foreach ($finder as $file) {
$percent += $step;
$this->progress($percent);
if (false === strpos(file_get_contents($file->getPathname()), sprintf('class %s', $file->getBasename('.php')))) {
continue;
}
$className = str_replace('@', '\\', $alias) . str_replace([Yii::getAlias($alias), '/', '.php'], ['', '\\', ''], $file->getPathname());
try {
if (false === @class_exists($className)) {
continue;
}
} catch (UnknownClassException $e) {
$this->stdout($e->getMessage() . "\n", Console::FG_RED);
continue;
}
try {
$r = new ReflectionClass($className);
} catch (ReflectionException $e) {
$this->stdout($e->getMessage() . "\n", Console::FG_RED);
}
if (in_array('yiicod\listener\components\listeners\ListenerInterface', $r->getInterfaceNames()) && false === $r->isAbstract() && false === empty($className::event())) {
$data[$className::priority()][$className::event()][] = [$className, 'on'];
}
if (in_array('yiicod\listener\components\subscribers\SubscriberInterface', $r->getInterfaceNames()) && false === $r->isAbstract()) {
$events = $className::subscribe();
foreach ($events as $event => $method) {
if (false === empty($event)) {
$data[$className::priority()][$event][] = [$className, $method];
}
}
}
}
$this->exportListener($data, Yii::getAlias($listener));
$this->stdout(sprintf("Exported to %s \n", $listener), Console::FG_GREEN);
}
}
/**
* Render progress message
*/
private function progress($percent)
{
Console::stdout(sprintf("\rProgress: %s ", round($percent)));
Console::clearLineAfterCursor();
}
/**
* Export listener
*
* @param $data
* @param $listenerFile
*/
public function exportListener($data, $listenerFile)
{
$array = str_replace("\r", '', var_export($data, true));
$content = <<<EOD
<?php
/**
* Events list.
*
* This file is automatically generated by 'yii listenersParse\index' command.
*
* NOTE, this file must be saved in UTF-8 encoding.
*/
return $array;
EOD;
file_put_contents($listenerFile, $content);
}
}