forked from wowcee/laravel-package-seeds-auto-loader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SeedServiceProvider.php
129 lines (118 loc) · 4 KB
/
SeedServiceProvider.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
namespace Core\Providers;
use Illuminate\Console\Events\CommandFinished;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Symfony\Component\Console\Output\ConsoleOutput;
class SeedServiceProvider extends ServiceProvider
{
protected $seeds_path = '/../database/seeds';
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
if ($this->isConsoleCommandContains([ 'db:seed', '--seed' ], [ '--class', 'help', '-h' ])) {
$this->addSeedsAfterConsoleCommandFinished();
}
}
}
/**
* Get a value that indicates whether the current command in console
* contains a string in the specified $fields.
*
* @param string|array $contain_options
* @param string|array $exclude_options
*
* @return bool
*/
protected function isConsoleCommandContains($contain_options, $exclude_options = null) : bool
{
$args = Request::server('argv', null);
if (is_array($args)) {
$command = implode(' ', $args);
if (
Str::contains($command, $contain_options) &&
($exclude_options == null || !Str::contains($command, $exclude_options))
) {
return true;
}
}
return false;
}
/**
* Add seeds from the $seed_path after the current command in console finished.
*/
protected function addSeedsAfterConsoleCommandFinished()
{
Event::listen(CommandFinished::class, function(CommandFinished $event) {
// Accept command in console only,
// exclude all commands from Artisan::call() method.
if ($event->output instanceof ConsoleOutput) {
$this->addSeedsFrom(__DIR__ . $this->seeds_path);
}
});
}
/**
* Register seeds.
*
* @param string $seeds_path
* @return void
*/
protected function addSeedsFrom($seeds_path)
{
$file_names = glob( $seeds_path . '/*.php');
foreach ($file_names as $filename)
{
$classes = $this->getClassesFromFile($filename);
foreach ($classes as $class) {
echo "\033[1;33mSeeding:\033[0m {$class}\n";
$startTime = microtime(true);
Artisan::call('db:seed', [ '--class' => $class, '--force' => '' ]);
$runTime = round(microtime(true) - $startTime, 2);
echo "\033[0;32mSeeded:\033[0m {$class} ({$runTime} seconds)\n";
}
}
}
/**
* Get full class names declared in the specified file.
*
* @param string $filename
* @return array an array of class names.
*/
private function getClassesFromFile(string $filename) : array
{
// Get namespace of class (if vary)
$namespace = "";
$lines = file($filename);
$namespaceLines = preg_grep('/^namespace /', $lines);
if (is_array($namespaceLines)) {
$namespaceLine = array_shift($namespaceLines);
$match = array();
preg_match('/^namespace (.*);$/', $namespaceLine, $match);
$namespace = array_pop($match);
}
// Get name of all class has in the file.
$classes = array();
$php_code = file_get_contents($filename);
$tokens = token_get_all($php_code);
$count = count($tokens);
for ($i = 2; $i < $count; $i++) {
if ($tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) {
$class_name = $tokens[$i][1];
if ($namespace !== "") {
$classes[] = $namespace . "\\$class_name";
} else {
$classes[] = $class_name;
}
}
}
return $classes;
}
}