This repository was archived by the owner on Dec 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenerator.php
213 lines (179 loc) · 6.02 KB
/
Generator.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?php namespace Impleri\Resource;
use BadFunctionCallException;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\View;
use Impleri\Resource\Contracts\GeneratorInterface;
/**
* Generator
*
* Ancestor class for resource generators with a lot of boilerplate code.
*/
abstract class Generator implements GeneratorInterface
{
/**
* Default namespace.
* @var string
*/
protected $namespace = '';
/**
* Default file path for resources.
* @var string
*/
protected $path = 'resources';
/**
* Default view to use for generating a resource.
* @var string
*/
protected $view = 'resource::view';
/**
* Execute
*
* Generic method to generate resource class files.
* @param array $options Variables to pass to the view
* @return int Number of controllers written
*/
public function execute($options)
{
$count = 0;
$options = $this->fillOptions($options);
foreach ($options['classes'] as $name => $class) {
$data = $this->fillClass($name, $class, $options);
// Override the view if one is passed
$view = (isset($class['view'])) ? $class['view'] : $this->view;
// Generate the contents
$contents = View::make($view, $data)->render();
// Remove the old backup
if ($this->save($data['file'], $contents)) {
$count++;
} else {
// Some kind of warning here
}
}
// Return count to the toolbox
return $count;
}
/**
* Fill Options
*
* Boilerplate method to inflate generator options using defaults.
* @param array $options Variables to pass to the view
* @throws BadFunctionCallException If missing element/collection from $options
*/
protected function fillOptions($options)
{
// Need at least a name to use
if (!isset($options['classes']) || empty($options['classes'])) {
throw new BadFunctionCallException('Classes are required for generation.');
}
// Set the default base path if none is
if (!isset($options['baseNamespace'])) {
$options['baseNamespace'] = $this->namespace;
}
// Set the default base path if none is
if (!isset($options['basePath'])) {
$options['basePath'] = $this->path;
}
// Flesh out the base path
$basePath = $this->trailingSeparator($options['basePath']);
// Add base namespace to base path
$baseNamespace = $options['baseNamespace'];
$basePath .= (empty($baseNamespace)) ? '' : $this->convertNamespace($baseNamespace);
$basePath = $this->trailingSeparator($basePath);
$options['basePath'] = $basePath;
return $options;
}
/**
* Fill Class
*
* Boilerplate method to inflate options for a specific class using defaults.
* @param str|int $name The class name
* @param array $class Class-specific options to pass to the view
* @param array $options Global options to pass to the view
* @throws BadFunctionCallException If missing name from $name and $options
*/
protected function fillClass($name, $class, $options)
{
$namespace = $options['baseNamespace'];
$saveTo = $this->trailingSeparator($options['basePath']);
// Add to the save path and namespace
if (isset($class['subNamespace'])) {
if (!empty($namespace)) {
$namespace = $this->trailingSeparator($namespace, '\\');
}
$namespace .= $class['subNamespace'];
$saveTo .= $this->convertNamespace($class['subNamespace']);
}
$saveTo = $this->trailingSeparator($saveTo);
// Override the class name with the array value
if (isset($class['name'])) {
$name = $class['name'];
}
if (!isset($name) || is_numeric($name) || empty($name)) {
throw new BadFunctionCallException('Every class must have a name.');
}
$saveTo .= $name;
// Set some necessary variables for the view
$data = [
'namespace' => $namespace,
'class' => $name,
'file' => $saveTo
];
// Overload data provided to the view
if (isset($class['data'])) {
$data = array_merge($data, $class['data']);
}
return $data;
}
/**
* Save
*
* Boilerplate method to save file and backup existing one.
* @param string $path File path
* @param string $contents Contents to save to the file
* @return bool True on sucess, false otherwise
*/
protected function save($path, $contents)
{
$success = false;
// Remove the old backup
if (File::exists($path . '.bak.php')) {
File::delete($path . '.bak.php');
}
// Back up the existing file
if (File::exists($path . '.php')) {
File::move($path . '.php', $path . '.bak.php');
}
// Save the new file
if (File::put($path . '.php', $contents)) {
$success = true;
}
return $success;
}
/**
* Trailing Separator
*
* Ensures there is a trailing separator on a string
* @param string $string String to test
* @param string $end Separator to append
* @return string Modified string
*/
protected function trailingSeparator($string, $end = '/')
{
if (substr($string, -strlen($end)) !== $end) {
$string .= $end;
}
return $string;
}
/**
* Convert Namespace
*
* Convert backslash from namespace to forward slash for file path.
* @param string $string Namespace to convert.
* @return string Namespace converted to a path.
*/
protected function convertNamespace($string)
{
return str_replace('\\', '/', $string);
}
}