Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 62ff810

Browse files
authored
Merge pull request #23 from modulusphp/feature/new-commands
Feature/new commands
2 parents cafc3f5 + 7b429aa commit 62ff810

File tree

9 files changed

+601
-8
lines changed

9 files changed

+601
-8
lines changed

Commands/CraftJob.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
namespace Modulus\Console\Commands;
4+
5+
use Modulus\Console\ModulusCLI;
6+
use AtlantisPHP\Console\Command;
7+
use Modulus\Scaffolding\Template;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
11+
class CraftJob extends Command
12+
{
13+
/**
14+
* The name and signature of the console command.
15+
*
16+
* @var string
17+
*/
18+
protected $signature = 'craft:job {name}';
19+
20+
/**
21+
* The full command description.
22+
*
23+
* @var string
24+
*/
25+
protected $help = 'This command allows you to create a Job';
26+
27+
/**
28+
* The descriptions of the console commands.
29+
*
30+
* @var array
31+
*/
32+
protected $descriptions = [
33+
'craft:job' => 'Create a new Job',
34+
'name' => 'The name of the job'
35+
];
36+
37+
/**
38+
* @param InputInterface $input
39+
* @param OutputInterface $output
40+
*
41+
* @return void
42+
*/
43+
protected function execute(InputInterface $input, OutputInterface $output)
44+
{
45+
$name = $input->getArgument('name');
46+
47+
if ($this->add($name)) {
48+
return $output->writeln('<info>Job "' . $name . '" has been successfully created.</info>');
49+
}
50+
51+
return $output->writeln('Job "' . $name . '" already exists.');
52+
}
53+
54+
/**
55+
* Add asset
56+
*
57+
* @param string $name
58+
* @return boolean
59+
*/
60+
private function add(string $name) : bool
61+
{
62+
$jobs = ModulusCLI::$appdir . 'app' . DIRECTORY_SEPARATOR . 'Jobs';
63+
$job = $jobs . DIRECTORY_SEPARATOR . $name . '.php';
64+
$namespace = '';
65+
66+
if (substr_count($name, '/') > 0) {
67+
ModulusCLI::_dir(substr($job, 0, strrpos($job, DIRECTORY_SEPARATOR)));
68+
$namespace = substr($name, 0, strrpos($name, DIRECTORY_SEPARATOR));
69+
$name = str_replace($namespace . DIRECTORY_SEPARATOR, '', $name);
70+
71+
$namespace = '\\' . str_replace('/', '\\', $namespace);
72+
}
73+
74+
ModulusCLI::_dir($jobs);
75+
76+
$content = Template::asset('job_template');
77+
$content = str_replace('{job_name}', $name, $content);
78+
$content = str_replace('{namespace}', $namespace, $content);
79+
80+
if (file_exists($job)) {
81+
return false;
82+
}
83+
84+
file_put_contents($job, $content);
85+
return true;
86+
}
87+
}

Commands/Migrate.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
5050

5151
$migrationFile = ModulusCLI::$appdir . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . '0000_00_00_00_00_00_migrations.php';
5252

53-
require $migrationFile;
54-
5553
if (Capsule::schema()->hasTable('migrations') == false) {
5654
if (file_exists($migrationFile)) {
57-
call_user_func(['Migrations', 'up']);
58-
}
59-
else {
55+
require $migrationFile;
56+
57+
(new \Migrations)->run(true);
58+
} else {
6059
return $output->writeln('<error>The migrations file is missing</error>');
6160
}
6261
}
@@ -130,7 +129,7 @@ private function migrateAll(string $migrationFile, string $name, string $action)
130129
if (strtolower($action == 'drop' ? 'down' : $action) == 'down') {
131130
if ($migration != null) {
132131
try {
133-
call_user_func([$name, 'down']);
132+
(new $name)->run(false);
134133
}
135134
catch (Exception $e) {
136135
Log::error($e);
@@ -147,7 +146,7 @@ private function migrateAll(string $migrationFile, string $name, string $action)
147146
else if (strtolower($action) == 'up'){
148147
if ($migration == null) {
149148
try {
150-
call_user_func([$name, 'up']);
149+
(new $name)->run(true);
151150
}
152151
catch (Exception $e) {
153152
Log::error($e);

Commands/PluginInstall.php

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<?php
2+
3+
namespace Modulus\Console\Commands;
4+
5+
use ReflectionClass;
6+
use Modulus\Utility\Plugin;
7+
use Modulus\Console\ModulusCLI;
8+
use Modulus\Support\Filesystem;
9+
use AtlantisPHP\Console\Command;
10+
use Modulus\Framework\Plugin\Validate;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
14+
class PluginInstall extends Command
15+
{
16+
/**
17+
* The name and signature of the console command.
18+
*
19+
* @var string
20+
*/
21+
protected $signature = 'plugin:install {--class=}';
22+
23+
/**
24+
* The full command description.
25+
*
26+
* @var string
27+
*/
28+
protected $help = 'Verify and install a new plugin';
29+
30+
/**
31+
* The descriptions of the console commands.
32+
*
33+
* @var array
34+
*/
35+
protected $descriptions = [
36+
'plugin:install' => 'Verify and install a new plugin'
37+
];
38+
39+
/**
40+
* @param InputInterface $input
41+
* @param OutputInterface $output
42+
*
43+
* @return void
44+
*/
45+
protected function execute(InputInterface $input, OutputInterface $output)
46+
{
47+
return $this->install($input, $output);
48+
}
49+
50+
/**
51+
* Install plugin
52+
*
53+
* @param InputInterface $input
54+
* @param OutputInterface $output
55+
* @return void
56+
*/
57+
private function install(InputInterface $input, OutputInterface $output)
58+
{
59+
$plugin = $this->getPlugin($input);
60+
61+
$pluginInfo = $this->getInfo($plugin);
62+
63+
if (Validate::check($plugin, $pluginInfo)) {
64+
65+
$package = $plugin::PACKAGE;
66+
$version = $plugin::VERSION;
67+
68+
if (config('app.plugins') && in_array($pluginInfo->name, config('app.plugins'))) {
69+
return $output->writeln("<error>{$package} is a registered plugin. Aborting...</error>");
70+
}
71+
72+
$output->writeln("<info>Installing: {$package} {$version}</info>");
73+
74+
if (!$this->addConfig($plugin, $pluginInfo)) {
75+
throw new \Exception('Could not add config file');
76+
}
77+
78+
if (!$this->addMigration($plugin, $pluginInfo)) {
79+
throw new \Exception('Could not add migration file');
80+
}
81+
82+
return $output->writeln("<info>Installed: {$package} {$version}. Append \"{$pluginInfo->name}::class\" in your plugins</info>");
83+
84+
}
85+
86+
$output->writeln("<error>Failed: {$package} {$version}</error>");
87+
}
88+
89+
/**
90+
* Get plugin instance
91+
*
92+
* @param InputInterface $input
93+
* @return string
94+
*/
95+
private function getPlugin(InputInterface $input) : Plugin
96+
{
97+
$class = $input->getOption('class');
98+
99+
if (!class_exists($class)) {
100+
throw new \Exception("Plugin {$class} does not exist");
101+
}
102+
103+
$plugin = new $class;
104+
105+
if (!$plugin instanceof Plugin) {
106+
throw new \Exception("{$class} is not a Modulus Plugin");
107+
}
108+
109+
return $plugin;
110+
}
111+
112+
/**
113+
* Get plugin information
114+
*
115+
* @param Plugin $plugin
116+
* @return ReflectionClass
117+
*/
118+
private function getInfo(Plugin $plugin) : ReflectionClass
119+
{
120+
return new ReflectionClass($plugin);
121+
}
122+
123+
/**
124+
* Add plugin config
125+
*
126+
* @param Plugin $plugin
127+
* @param ReflectionClass $pluginInfo
128+
* @return bool
129+
*/
130+
private function addConfig(Plugin $plugin, ReflectionClass $pluginInfo) : bool
131+
{
132+
$pluginConfig = dirname($pluginInfo->getFileName()) . DS . '..' . DS . 'install' . DS . 'config.php';
133+
134+
if (
135+
array_key_exists('CONFIG', $pluginInfo->getConstants()) &&
136+
file_exists($pluginConfig)
137+
) {
138+
$appConfig = config('app.dir') . 'config' . DS . $plugin::CONFIG . '.php';
139+
140+
if (file_exists($appConfig)) return false;
141+
142+
$pluginConfig = Filesystem::get($pluginConfig);
143+
144+
return Filesystem::put($appConfig, $pluginConfig);
145+
}
146+
147+
return true;
148+
}
149+
150+
/**
151+
* Add plugin migration
152+
*
153+
* @param Plugin $plugin
154+
* @param ReflectionClass $pluginInfo
155+
* @return bool
156+
*/
157+
private function addMigration(Plugin $plugin, ReflectionClass $pluginInfo) : bool
158+
{
159+
$pluginMigration = dirname($pluginInfo->getFileName()) . DS . '..' . DS . 'install' . DS . 'migration.php';
160+
161+
if (
162+
array_key_exists('MIGRATION', $pluginInfo->getConstants()) &&
163+
file_exists($pluginMigration)
164+
) {
165+
$name = $plugin::MIGRATION;
166+
167+
$class = implode('', array_map('ucfirst', explode('_', $name)));
168+
169+
return $this->add($name, $class, Filesystem::get($pluginMigration));
170+
}
171+
172+
return true;
173+
}
174+
175+
/**
176+
* Add asset
177+
*
178+
* @param string $name
179+
* @param string $class
180+
* @param string $content
181+
* @return bool
182+
*/
183+
private function add(string $name, string $class, string $content) : bool
184+
{
185+
$migrations = ModulusCLI::$appdir . 'database' . DIRECTORY_SEPARATOR . 'migrations';
186+
$date = date('Y_m_d_H_i_s');
187+
$migration = $migrations . DIRECTORY_SEPARATOR . $date . '_' . $name . '.php';
188+
189+
ModulusCLI::_dir($migrations);
190+
191+
if (file_exists($migration)) {
192+
return false;
193+
}
194+
195+
return file_put_contents($migration, $content);
196+
}
197+
}

Commands/QueueDispatcher.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Modulus\Console\Commands;
4+
5+
use AtlantisPHP\Console\Command;
6+
use Modulus\Hibernate\Queue\Commands\Dispatcher;
7+
use Symfony\Component\Console\Input\InputInterface;
8+
use Symfony\Component\Console\Output\OutputInterface;
9+
10+
class QueueDispatcher extends Command
11+
{
12+
use Dispatcher;
13+
14+
/**
15+
* The name and signature of the console command.
16+
*
17+
* @var string
18+
*/
19+
protected $signature = 'queue:dispatch {id=}';
20+
21+
/**
22+
* The full command description.
23+
*
24+
* @var string
25+
*/
26+
protected $help = 'Process a single job';
27+
28+
/**
29+
* The descriptions of the console commands.
30+
*
31+
* @var array
32+
*/
33+
protected $descriptions = [
34+
'queue:dispatch' => 'Process a single job',
35+
'id' => 'Queue id'
36+
];
37+
38+
/**
39+
* @param InputInterface $input
40+
* @param OutputInterface $output
41+
*
42+
* @return void
43+
*/
44+
protected function execute(InputInterface $input, OutputInterface $output)
45+
{
46+
$this->start($input);
47+
}
48+
49+
}

0 commit comments

Comments
 (0)