Skip to content

Commit 2752c9e

Browse files
committed
lets add some meat to make:schedule
1 parent b12240d commit 2752c9e

File tree

9 files changed

+327
-48
lines changed

9 files changed

+327
-48
lines changed

src/Maker/MakeSchedule.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Maker;
13+
14+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
15+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
16+
use Symfony\Bundle\MakerBundle\FileManager;
17+
use Symfony\Bundle\MakerBundle\Generator;
18+
use Symfony\Bundle\MakerBundle\InputConfiguration;
19+
use Symfony\Bundle\MakerBundle\Str;
20+
use Symfony\Bundle\MakerBundle\Util\UseStatementGenerator;
21+
use Symfony\Component\Console\Command\Command;
22+
use Symfony\Component\Console\Input\InputInterface;
23+
use Symfony\Component\Finder\Finder;
24+
use Symfony\Component\Process\Process;
25+
use Symfony\Component\Scheduler\Attribute\AsSchedule;
26+
use Symfony\Component\Scheduler\RecurringMessage;
27+
use Symfony\Component\Scheduler\Schedule;
28+
use Symfony\Component\Scheduler\ScheduleProviderInterface;
29+
30+
/**
31+
* @author Jesse Rushlow <[email protected]>
32+
*
33+
* @internal
34+
*/
35+
final class MakeSchedule extends AbstractMaker
36+
{
37+
private string $scheduleName;
38+
private ?string $message = null;
39+
40+
public function __construct(
41+
private FileManager $fileManager,
42+
private Finder $finder = new Finder(),
43+
) {
44+
}
45+
46+
public static function getCommandName(): string
47+
{
48+
return 'make:schedule';
49+
}
50+
51+
public static function getCommandDescription(): string
52+
{
53+
return 'Create a scheduler component';
54+
}
55+
56+
public function configureCommand(Command $command, InputConfiguration $inputConfig): void
57+
{
58+
$command
59+
->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeScheduler.txt'))
60+
;
61+
}
62+
63+
public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void
64+
{
65+
if (!class_exists(AsSchedule::class)) {
66+
// throw new \RuntimeException('You must install symfony/scheduler to create a schedule (composer require symfony/scheduler)');
67+
$io->writeln('Running composer require symfony/scheduler');
68+
$process = Process::fromShellCommandline('composer require symfony/scheduler');
69+
$process->run();
70+
$io->writeln('Scheduler successfully installed!');
71+
}
72+
73+
// Loop over existing src/Message/* and ask which message the user would like to schedule
74+
$availableMessages = ['Empty Schedule'];
75+
$messageDir = $this->fileManager->getRootDirectory().'/src/Message';
76+
77+
if ($this->fileManager->fileExists($messageDir)) {
78+
$finder = $this->finder->in($this->fileManager->getRootDirectory().'/src/Message');
79+
80+
foreach ($finder->files() as $file) {
81+
$availableMessages[] = $file->getFilenameWithoutExtension();
82+
}
83+
}
84+
85+
$scheduleNameHint = 'MainSchedule';
86+
87+
// If the count is 1, no other messages were found - don't ask to create a message
88+
if (1 !== \count($availableMessages)) {
89+
$selectedMessage = $io->choice('Select which message', $availableMessages);
90+
91+
if ('Empty Schedule' !== $selectedMessage) {
92+
$this->message = $selectedMessage;
93+
94+
// We don't want SomeMessageSchedule, so remove the "Message" suffix to give us SomeSchedule
95+
$scheduleNameHint = sprintf('%sSchedule', Str::removeSuffix($selectedMessage, 'Message'));
96+
}
97+
}
98+
99+
// Otherwise call `make:message` to create a new message
100+
101+
// Ask the name of the new schedule
102+
$this->scheduleName = $io->ask(question: 'What should we call the new schedule?', default: $scheduleNameHint);
103+
}
104+
105+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
106+
{
107+
$scheduleClassDetails = $generator->createClassNameDetails(
108+
$this->scheduleName,
109+
'Scheduler\\',
110+
);
111+
112+
$useStatements = new UseStatementGenerator([
113+
AsSchedule::class,
114+
RecurringMessage::class,
115+
Schedule::class,
116+
ScheduleProviderInterface::class,
117+
]);
118+
119+
if (null !== $this->message) {
120+
$useStatements->addUseStatement('App\\Message\\'.$this->message);
121+
}
122+
123+
$generator->generateClass(
124+
$scheduleClassDetails->getFullName(),
125+
'scheduler/Schedule.tpl.php',
126+
[
127+
'use_statements' => $useStatements,
128+
'has_custom_message' => null !== $this->message,
129+
'message_class_name' => $this->message,
130+
],
131+
);
132+
133+
$generator->writeChanges();
134+
135+
$this->writeSuccessMessage($io);
136+
}
137+
138+
public function configureDependencies(DependencyBuilder $dependencies): void
139+
{
140+
// TODO: Implement configureDependencies() method.
141+
}
142+
}

src/Maker/MakeScheduler.php

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/Resources/config/makers.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@
9292
<tag name="maker.command" />
9393
</service>
9494

95+
<service id="maker.maker.make_schedule" class="Symfony\Bundle\MakerBundle\Maker\MakeSchedule">
96+
<argument type="service" id="maker.file_manager" />
97+
<tag name="maker.command" />
98+
</service>
99+
95100
<service id="maker.maker.make_serializer_encoder" class="Symfony\Bundle\MakerBundle\Maker\MakeSerializerEncoder">
96101
<tag name="maker.command" />
97102
</service>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?= "<?php\n" ?>
2+
3+
namespace <?= $namespace; ?>;
4+
5+
<?= $use_statements; ?>
6+
7+
#[AsSchedule]
8+
final class <?= $class_name; ?> implements ScheduleProviderInterface
9+
{
10+
public function getSchedule(): Schedule
11+
{
12+
return (new Schedule())->add(
13+
<?php if ($has_custom_message): ?>
14+
// @TODO - Modify the frequency to suite your needs
15+
RecurringMessage::every('1 hour', new <?= $message_class_name; ?>()),
16+
<?php else: ?>
17+
// @TODO - Create a Message to schedule
18+
// RecurringMessage::every('1 hour', new App\Message\Message()),
19+
<?php endif ?>
20+
);
21+
}
22+
}

tests/Maker/MakeScheduleTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Tests\Maker;
13+
14+
use Symfony\Bundle\MakerBundle\Maker\MakeSchedule;
15+
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
16+
use Symfony\Bundle\MakerBundle\Test\MakerTestRunner;
17+
18+
class MakeScheduleTest extends MakerTestCase
19+
{
20+
protected function getMakerClass(): string
21+
{
22+
return MakeSchedule::class;
23+
}
24+
25+
public function getTestDetails(): \Generator
26+
{
27+
yield 'it_generates_a_schedule' => [$this->createMakerTest()
28+
->run(function (MakerTestRunner $runner) {
29+
$output = $runner->runMaker([
30+
'', // use default schedule name "MainSchedule"
31+
]);
32+
33+
$this->assertStringContainsString('Success', $output);
34+
35+
self::assertFileEquals(
36+
\dirname(__DIR__).'/fixtures/make-schedule/expected/DefaultScheduleEmpty.php',
37+
$runner->getPath('src/Scheduler/MainSchedule.php')
38+
);
39+
}),
40+
];
41+
42+
yield 'it_generates_a_schedule_select_empty' => [$this->createMakerTest()
43+
->preRun(function (MakerTestRunner $runner) {
44+
$runner->copy(
45+
'make-schedule/standard_setup',
46+
''
47+
);
48+
})
49+
->run(function (MakerTestRunner $runner) {
50+
$output = $runner->runMaker([
51+
0, // Select "Empty Schedule"
52+
'MySchedule', // Go with the default name "MainSchedule"
53+
]);
54+
55+
$this->assertStringContainsString('Success', $output);
56+
57+
self::assertFileEquals(
58+
\dirname(__DIR__).'/fixtures/make-schedule/expected/MyScheduleEmpty.php',
59+
$runner->getPath('src/Scheduler/MySchedule.php')
60+
);
61+
}),
62+
];
63+
64+
yield 'it_generates_a_schedule_select_existing_message' => [$this->createMakerTest()
65+
->preRun(function (MakerTestRunner $runner) {
66+
$runner->copy(
67+
'make-schedule/standard_setup',
68+
''
69+
);
70+
})
71+
->run(function (MakerTestRunner $runner) {
72+
$output = $runner->runMaker([
73+
1, // Select "MyMessage" from choice
74+
'', // Go with the default name "MessageFixtureSchedule"
75+
]);
76+
77+
$this->assertStringContainsString('Success', $output);
78+
79+
self::assertFileEquals(
80+
\dirname(__DIR__).'/fixtures/make-schedule/expected/MyScheduleWithMessage.php',
81+
$runner->getPath('src/Scheduler/MessageFixtureSchedule.php')
82+
);
83+
}),
84+
];
85+
}
86+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Scheduler;
4+
5+
use Symfony\Component\Scheduler\Attribute\AsSchedule;
6+
use Symfony\Component\Scheduler\RecurringMessage;
7+
use Symfony\Component\Scheduler\Schedule;
8+
use Symfony\Component\Scheduler\ScheduleProviderInterface;
9+
10+
#[AsSchedule]
11+
final class MainSchedule implements ScheduleProviderInterface
12+
{
13+
public function getSchedule(): Schedule
14+
{
15+
return (new Schedule())->add(
16+
// @TODO - Create a Message to schedule
17+
// RecurringMessage::every('1 hour', new App\Message\Message()),
18+
);
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Scheduler;
4+
5+
use Symfony\Component\Scheduler\Attribute\AsSchedule;
6+
use Symfony\Component\Scheduler\RecurringMessage;
7+
use Symfony\Component\Scheduler\Schedule;
8+
use Symfony\Component\Scheduler\ScheduleProviderInterface;
9+
10+
#[AsSchedule]
11+
final class MySchedule implements ScheduleProviderInterface
12+
{
13+
public function getSchedule(): Schedule
14+
{
15+
return (new Schedule())->add(
16+
// @TODO - Create a Message to schedule
17+
// RecurringMessage::every('1 hour', new App\Message\Message()),
18+
);
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace App\Scheduler;
4+
5+
use App\Message\MessageFixture;
6+
use Symfony\Component\Scheduler\Attribute\AsSchedule;
7+
use Symfony\Component\Scheduler\RecurringMessage;
8+
use Symfony\Component\Scheduler\Schedule;
9+
use Symfony\Component\Scheduler\ScheduleProviderInterface;
10+
11+
#[AsSchedule]
12+
final class MessageFixtureSchedule implements ScheduleProviderInterface
13+
{
14+
public function getSchedule(): Schedule
15+
{
16+
return (new Schedule())->add(
17+
// @TODO - Modify the frequency to suite your needs
18+
RecurringMessage::every('1 hour', new MessageFixture()),
19+
);
20+
}
21+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Message;
4+
5+
final class MessageFixture
6+
{
7+
public function __construct(
8+
public string $message = 'Howdy!',
9+
) {
10+
}
11+
}

0 commit comments

Comments
 (0)