Total Complexity | 48 |
Total Lines | 359 |
Duplicated Lines | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 1 |
Complex classes like ContentController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ContentController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
24 | class ContentController extends Controller |
||
25 | { |
||
26 | protected $formNames = []; |
||
27 | |||
28 | protected $entity = null; |
||
29 | |||
30 | public function __construct() |
||
31 | { |
||
32 | parent::__construct(); |
||
33 | $route = request()->route(); |
||
34 | if (is_null($route)) { |
||
35 | return; |
||
36 | } |
||
37 | $entity = $route->parameter('entity'); |
||
38 | $this->entity = Entity::query()->findOrFail($entity); |
||
39 | ContentRepository::setTable($this->entity->table_name); |
||
40 | $this->breadcrumb[] = ['title' => '内容列表', 'url' => route('admin::content.index', ['entity' => $entity])]; |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * 内容管理-内容列表 |
||
45 | * |
||
46 | */ |
||
47 | public function index($entity) |
||
48 | { |
||
49 | $result = $this->useUserDefinedIndexHandler($entity); |
||
50 | if (!is_null($result)) { |
||
51 | return $result; |
||
52 | } |
||
53 | |||
54 | $this->breadcrumb[] = ['title' => $this->entity->name . '内容列表', 'url' => '']; |
||
55 | Content::$listField = [ |
||
56 | 'title' => '标题' |
||
57 | ]; |
||
58 | return view('admin.content.index', [ |
||
59 | 'breadcrumb' => $this->breadcrumb, |
||
60 | 'entity' => $entity, |
||
61 | 'entityModel' => $this->entity, |
||
62 | 'autoMenu' => EntityRepository::systemMenu() |
||
63 | ]); |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * 内容列表数据接口 |
||
68 | * |
||
69 | * @param Request $request |
||
70 | * @param integer $entity |
||
71 | * @return array |
||
72 | */ |
||
73 | public function list(Request $request, $entity) |
||
74 | { |
||
75 | $result = $this->useUserDefinedListHandler($request, $entity); |
||
76 | if (!is_null($result)) { |
||
77 | return $result; |
||
78 | } |
||
79 | |||
80 | $perPage = (int) $request->get('limit', 50); |
||
81 | $this->formNames = array_merge(['created_at'], EntityFieldRepository::getFields($entity)); |
||
82 | $condition = $request->only($this->formNames); |
||
83 | |||
84 | $data = ContentRepository::list($entity, $perPage, $condition); |
||
85 | |||
86 | return $data; |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * 内容管理-新增内容 |
||
91 | * |
||
92 | */ |
||
93 | public function create($entity) |
||
94 | { |
||
95 | $this->breadcrumb[] = ['title' => "新增{$this->entity->name}内容", 'url' => '']; |
||
96 | $view = $this->getAddOrEditViewPath(); |
||
97 | |||
98 | return view($view, [ |
||
99 | 'breadcrumb' => $this->breadcrumb, |
||
100 | 'entity' => $entity, |
||
101 | 'entityModel' => $this->entity, |
||
102 | 'entityFields' => EntityFieldRepository::getByEntityId($entity), |
||
103 | 'autoMenu' => EntityRepository::systemMenu() |
||
104 | ]); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * 内容管理-保存内容 |
||
109 | * |
||
110 | * @param ContentRequest $request |
||
111 | * @param integer $entity |
||
112 | * @return array |
||
113 | */ |
||
114 | public function save(ContentRequest $request, $entity) |
||
115 | { |
||
116 | $this->validateEntityRequest(); |
||
117 | $result = $this->useUserDefinedSaveHandler($request, $entity); |
||
118 | if (!is_null($result)) { |
||
119 | return $result; |
||
120 | } |
||
121 | |||
122 | try { |
||
123 | DB::beginTransaction(); |
||
124 | |||
125 | $content = ContentRepository::add($request->only( |
||
126 | EntityFieldRepository::getFields($entity) |
||
127 | )); |
||
128 | |||
129 | // 标签类型字段另外处理 多对多关联 |
||
130 | $inputTagsField = EntityFieldRepository::getInputTagsField($entity); |
||
131 | $tags = null; |
||
132 | if ($inputTagsField) { |
||
133 | $tags = $request->post($inputTagsField->name); |
||
134 | } |
||
135 | if (!is_null($tags) && $tags = json_decode($tags, true)) { |
||
136 | foreach ($tags as $v) { |
||
137 | $tag = Tag::firstOrCreate(['name' => $v['value']]); |
||
138 | ContentTag::firstOrCreate(['entity_id' => $entity, 'content_id' => $content->id, 'tag_id' => $tag->id]); |
||
139 | } |
||
140 | } |
||
141 | |||
142 | DB::commit(); |
||
143 | |||
144 | return [ |
||
145 | 'code' => 0, |
||
146 | 'msg' => '新增成功', |
||
147 | 'redirect' => route('admin::content.index', ['entity' => $entity]) |
||
148 | ]; |
||
149 | } catch (QueryException $e) { |
||
150 | DB::rollBack(); |
||
151 | \Log::error($e); |
||
152 | return [ |
||
153 | 'code' => 1, |
||
154 | 'msg' => '新增失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前内容已存在' : '其它错误'), |
||
155 | 'redirect' => false |
||
156 | ]; |
||
157 | } |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * 内容管理-编辑内容 |
||
162 | * |
||
163 | * @param int $id |
||
164 | * @return View |
||
165 | */ |
||
166 | public function edit($entity, $id) |
||
167 | { |
||
168 | $this->breadcrumb[] = ['title' => "编辑{$this->entity->name}内容", 'url' => '']; |
||
169 | $view = $this->getAddOrEditViewPath(); |
||
170 | $model = ContentRepository::find($id); |
||
171 | |||
172 | return view($view, [ |
||
173 | 'id' => $id, |
||
174 | 'model' => $model, |
||
175 | 'breadcrumb' => $this->breadcrumb, |
||
176 | 'entity' => $entity, |
||
177 | 'entityModel' => $this->entity, |
||
178 | 'entityFields' => EntityFieldRepository::getByEntityId($entity), |
||
179 | 'autoMenu' => EntityRepository::systemMenu() |
||
180 | ]); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * 内容管理-更新内容 |
||
185 | * |
||
186 | * @param ContentRequest $request |
||
187 | * @param integer $entity |
||
188 | * @param int $id |
||
189 | * @return array |
||
190 | */ |
||
191 | public function update(ContentRequest $request, $entity, $id) |
||
192 | { |
||
193 | $this->validateEntityRequest(); |
||
194 | $result = $this->useUserDefinedUpdateHandler($request, $entity, $id); |
||
195 | if (!is_null($result)) { |
||
196 | return $result; |
||
197 | } |
||
198 | |||
199 | $fieldInfo = EntityFieldRepository::getByEntityId($entity) |
||
200 | ->where('is_edit', EntityField::EDIT_ENABLE) |
||
201 | ->pluck('form_type', 'name') |
||
202 | ->toArray(); |
||
203 | $data = []; |
||
204 | foreach ($fieldInfo as $k => $v) { |
||
205 | if ($v === 'checkbox') { |
||
206 | $data[$k] = ''; |
||
207 | } |
||
208 | } |
||
209 | $data = array_merge($data, $request->only(array_keys($fieldInfo))); |
||
210 | |||
211 | try { |
||
212 | DB::beginTransaction(); |
||
213 | |||
214 | ContentRepository::update($id, $data); |
||
215 | |||
216 | // 标签类型字段另外处理 多对多关联 |
||
217 | $inputTagsField = EntityFieldRepository::getInputTagsField($entity); |
||
218 | $tags = null; |
||
219 | if ($inputTagsField && $inputTagsField->is_edit === EntityField::EDIT_ENABLE) { |
||
220 | $tags = $request->post($inputTagsField->name); |
||
221 | } |
||
222 | if (!is_null($tags) && $tags = json_decode($tags, true)) { |
||
223 | $tagIds = []; |
||
224 | foreach ($tags as $v) { |
||
225 | $tag = Tag::firstOrCreate(['name' => $v['value']]); |
||
226 | ContentTag::firstOrCreate(['entity_id' => $entity, 'content_id' => $id, 'tag_id' => $tag->id]); |
||
227 | $tagIds[] = $tag->id; |
||
228 | } |
||
229 | if ($tagIds) { |
||
230 | ContentTag::where('entity_id', $entity)->where('content_id', $id)->whereNotIn('tag_id', $tagIds)->delete(); |
||
231 | } |
||
232 | } |
||
233 | |||
234 | DB::commit(); |
||
235 | return [ |
||
236 | 'code' => 0, |
||
237 | 'msg' => '编辑成功', |
||
238 | 'redirect' => route('admin::content.index', ['entity' => $entity]) |
||
239 | ]; |
||
240 | } catch (QueryException $e) { |
||
241 | DB::rollBack(); |
||
242 | \Log::error($e); |
||
243 | return [ |
||
244 | 'code' => 1, |
||
245 | 'msg' => '编辑失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前内容已存在' : '其它错误'), |
||
246 | 'redirect' => false |
||
247 | ]; |
||
248 | } |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * 内容管理-删除内容 |
||
253 | * |
||
254 | * @param int $id |
||
255 | */ |
||
256 | public function delete($entity, $id) |
||
270 | ]; |
||
271 | } |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * 内容管理-内容批量操作 |
||
276 | * |
||
277 | * @param Request $request |
||
278 | * @return array |
||
279 | */ |
||
280 | public function batch(Request $request) |
||
281 | { |
||
282 | $type = $request->input('type', ''); |
||
283 | $ids = $request->input('ids'); |
||
284 | if (!is_array($ids)) { |
||
285 | return [ |
||
286 | 'code' => 1, |
||
287 | 'msg' => '参数错误' |
||
288 | ]; |
||
289 | } |
||
290 | $ids = array_map(function ($item) { |
||
291 | return intval($item); |
||
292 | }, $ids); |
||
293 | |||
294 | $message = ''; |
||
295 | switch ($type) { |
||
296 | case 'delete': |
||
297 | ContentRepository::model()->whereIn('id', $ids)->delete(); |
||
298 | break; |
||
299 | default: |
||
300 | break; |
||
301 | } |
||
302 | |||
303 | return [ |
||
304 | 'code' => 0, |
||
305 | 'msg' => '操作成功' . $message, |
||
306 | 'reload' => true |
||
307 | ]; |
||
308 | } |
||
309 | |||
310 | protected function validateEntityRequest() |
||
311 | { |
||
312 | $entityRequestClass = '\\App\\Http\\Requests\\Admin\\Entity\\' . |
||
313 | Str::ucfirst(Str::singular($this->entity->table_name)) . 'Request'; |
||
314 | if (class_exists($entityRequestClass)) { |
||
315 | $entityRequestClass::capture()->setContainer(app())->setRedirector(app()->make('redirect'))->validate(); |
||
316 | } |
||
317 | } |
||
318 | |||
319 | protected function useUserDefinedSaveHandler($request, $entity) |
||
320 | { |
||
321 | $entityControllerClass = $this->userDefinedHandlerExists('save'); |
||
322 | if ($entityControllerClass === false) { |
||
323 | return null; |
||
324 | } |
||
325 | return call_user_func([new $entityControllerClass, 'save'], $request, $entity); |
||
326 | } |
||
327 | |||
328 | protected function useUserDefinedUpdateHandler($request, $entity, $id) |
||
329 | { |
||
330 | $entityControllerClass = $this->userDefinedHandlerExists('update'); |
||
331 | if ($entityControllerClass === false) { |
||
332 | return null; |
||
333 | } |
||
334 | return call_user_func([new $entityControllerClass, 'update'], $request, $entity, $id); |
||
335 | } |
||
336 | |||
337 | protected function useUserDefinedIndexHandler($entity) |
||
344 | } |
||
345 | |||
346 | protected function useUserDefinedListHandler($request, $entity) |
||
347 | { |
||
348 | $entityControllerClass = $this->userDefinedHandlerExists('list'); |
||
349 | if ($entityControllerClass === false) { |
||
350 | return null; |
||
351 | } |
||
352 | return call_user_func([new $entityControllerClass, 'list'], $request, $entity); |
||
353 | } |
||
354 | |||
355 | /** |
||
356 | * 判断自定义的处理方法是否存在 |
||
357 | * |
||
358 | * @param string $method 方法名 |
||
359 | * @return string|boolean 存在返回控制器类名,不存在返回false |
||
360 | */ |
||
361 | protected function userDefinedHandlerExists($method) |
||
370 | } |
||
371 | |||
372 | protected function getAddOrEditViewPath() |
||
383 | } |
||
384 | } |
||
385 |