Total Complexity | 49 |
Total Lines | 371 |
Duplicated Lines | 0 % |
Changes | 8 | ||
Bugs | 0 | Features | 4 |
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 |
||
30 | class ContentController extends Controller |
||
31 | { |
||
32 | protected $formNames = []; |
||
33 | |||
34 | protected $entity = null; |
||
35 | |||
36 | public function __construct() |
||
37 | { |
||
38 | parent::__construct(); |
||
39 | $route = request()->route(); |
||
40 | if (is_null($route)) { |
||
41 | return; |
||
42 | } |
||
43 | $entity = $route->parameter('entity'); |
||
44 | $this->entity = Entity::query()->findOrFail($entity); |
||
45 | ContentRepository::setTable($this->entity->table_name); |
||
46 | $this->breadcrumb[] = ['title' => '内容列表', 'url' => route('admin::content.index', ['entity' => $entity])]; |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * 内容管理-内容列表 |
||
51 | * |
||
52 | */ |
||
53 | public function index($entity) |
||
54 | { |
||
55 | $result = $this->useUserDefinedIndexHandler($entity); |
||
56 | if (!is_null($result)) { |
||
57 | return $result; |
||
58 | } |
||
59 | |||
60 | $this->breadcrumb[] = ['title' => $this->entity->name . '内容列表', 'url' => '']; |
||
61 | Content::$listField = [ |
||
62 | 'title' => '标题' |
||
63 | ]; |
||
64 | return view('admin.content.index', [ |
||
65 | 'breadcrumb' => $this->breadcrumb, |
||
66 | 'entity' => $entity, |
||
67 | 'entityModel' => $this->entity, |
||
68 | 'autoMenu' => EntityRepository::systemMenu() |
||
69 | ]); |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * 内容管理-内容列表数据接口 |
||
74 | * |
||
75 | * @param Request $request |
||
76 | * @param integer $entity |
||
77 | * @return array |
||
78 | */ |
||
79 | public function list(Request $request, $entity) |
||
80 | { |
||
81 | $result = $this->useUserDefinedListHandler($request, $entity); |
||
82 | if (!is_null($result)) { |
||
83 | return $result; |
||
84 | } |
||
85 | |||
86 | $perPage = (int) $request->get('limit', 50); |
||
87 | $this->formNames = array_merge(['created_at', 'light_sort_fields'], EntityFieldRepository::getFields($entity)); |
||
88 | $condition = $request->only($this->formNames); |
||
89 | |||
90 | $data = ContentRepository::list($entity, $perPage, $condition); |
||
91 | |||
92 | return $data; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * 内容管理-新增内容 |
||
97 | * |
||
98 | */ |
||
99 | public function create($entity) |
||
100 | { |
||
101 | $this->breadcrumb[] = ['title' => "新增{$this->entity->name}内容", 'url' => '']; |
||
102 | $view = $this->getAddOrEditViewPath(); |
||
103 | |||
104 | return view($view, [ |
||
105 | 'breadcrumb' => $this->breadcrumb, |
||
106 | 'entity' => $entity, |
||
107 | 'entityModel' => $this->entity, |
||
108 | 'entityFields' => EntityFieldRepository::getByEntityId($entity), |
||
109 | 'autoMenu' => EntityRepository::systemMenu() |
||
110 | ]); |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * 内容管理-保存内容 |
||
115 | * |
||
116 | * @param ContentRequest $request |
||
117 | * @param integer $entity |
||
118 | * @return array |
||
119 | */ |
||
120 | public function save(ContentRequest $request, $entity) |
||
121 | { |
||
122 | $this->validateEntityRequest(); |
||
123 | event(new ContentCreating($request, $this->entity)); |
||
124 | $result = $this->useUserDefinedSaveHandler($request, $entity); |
||
125 | if (!is_null($result)) { |
||
126 | return $result; |
||
127 | } |
||
128 | |||
129 | try { |
||
130 | DB::beginTransaction(); |
||
131 | |||
132 | $content = ContentRepository::add($request->only( |
||
133 | EntityFieldRepository::getSaveFields($entity) |
||
134 | ), $this->entity); |
||
135 | |||
136 | // 标签类型字段另外处理 多对多关联 |
||
137 | $inputTagsField = EntityFieldRepository::getInputTagsField($entity); |
||
138 | $tags = null; |
||
139 | if ($inputTagsField) { |
||
140 | $tags = $request->post($inputTagsField->name); |
||
141 | } |
||
142 | if (is_string($tags) && $tags = json_decode($tags, true)) { |
||
143 | foreach ($tags as $v) { |
||
144 | $tag = Tag::firstOrCreate(['name' => $v['value']]); |
||
145 | ContentTag::firstOrCreate( |
||
146 | ['entity_id' => $entity, 'content_id' => $content->id, 'tag_id' => $tag->id] |
||
147 | ); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | DB::commit(); |
||
152 | event(new ContentCreated($content, $this->entity)); |
||
153 | |||
154 | return [ |
||
155 | 'code' => 0, |
||
156 | 'msg' => '新增成功', |
||
157 | 'redirect' => route('admin::content.index', ['entity' => $entity]) |
||
158 | ]; |
||
159 | } catch (QueryException $e) { |
||
160 | DB::rollBack(); |
||
161 | Log::error($e); |
||
162 | return [ |
||
163 | 'code' => 1, |
||
164 | 'msg' => '新增失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前内容已存在' : '其它错误'), |
||
165 | 'redirect' => false |
||
166 | ]; |
||
167 | } |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * 内容管理-编辑内容 |
||
172 | * |
||
173 | * @param int $id |
||
174 | * @return View |
||
175 | */ |
||
176 | public function edit($entity, $id) |
||
177 | { |
||
178 | $this->breadcrumb[] = ['title' => "编辑{$this->entity->name}内容", 'url' => '']; |
||
179 | $view = $this->getAddOrEditViewPath(); |
||
180 | $model = ContentRepository::find($id); |
||
181 | |||
182 | return view($view, [ |
||
183 | 'id' => $id, |
||
184 | 'model' => $model, |
||
185 | 'breadcrumb' => $this->breadcrumb, |
||
186 | 'entity' => $entity, |
||
187 | 'entityModel' => $this->entity, |
||
188 | 'entityFields' => EntityFieldRepository::getByEntityId($entity), |
||
189 | 'autoMenu' => EntityRepository::systemMenu() |
||
190 | ]); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * 内容管理-更新内容 |
||
195 | * |
||
196 | * @param ContentRequest $request |
||
197 | * @param integer $entity |
||
198 | * @param int $id |
||
199 | * @return array |
||
200 | */ |
||
201 | public function update(ContentRequest $request, $entity, $id) |
||
202 | { |
||
203 | $this->validateEntityRequest(); |
||
204 | event(new ContentUpdating($request, $this->entity)); |
||
205 | $result = $this->useUserDefinedUpdateHandler($request, $entity, $id); |
||
206 | if (!is_null($result)) { |
||
207 | return $result; |
||
208 | } |
||
209 | |||
210 | $data = $this->getUpdateData($request, $entity); |
||
211 | try { |
||
212 | DB::beginTransaction(); |
||
213 | |||
214 | ContentRepository::update($id, $data, $this->entity); |
||
215 | // 标签类型字段另外处理 多对多关联 |
||
216 | $inputTagsField = EntityFieldRepository::getInputTagsField($entity); |
||
217 | $tags = null; |
||
218 | if ($inputTagsField && intval($inputTagsField->is_edit) === EntityField::EDIT_ENABLE) { |
||
219 | $tags = $request->post($inputTagsField->name); |
||
220 | } |
||
221 | if (is_string($tags) && $tags = json_decode($tags, true)) { |
||
222 | $tagIds = []; |
||
223 | foreach ($tags as $v) { |
||
224 | $tag = Tag::firstOrCreate(['name' => $v['value']]); |
||
225 | ContentTag::firstOrCreate(['entity_id' => $entity, 'content_id' => $id, 'tag_id' => $tag->id]); |
||
226 | $tagIds[] = $tag->id; |
||
227 | } |
||
228 | if ($tagIds) { |
||
229 | ContentTag::where('entity_id', $entity)->where('content_id', $id)->whereNotIn('tag_id', $tagIds)->delete(); |
||
230 | } |
||
231 | } |
||
232 | |||
233 | DB::commit(); |
||
234 | event(new ContentUpdated([$id], $this->entity)); |
||
235 | |||
236 | return [ |
||
237 | 'code' => 0, |
||
238 | 'msg' => '编辑成功', |
||
239 | 'redirect' => route('admin::content.index', ['entity' => $entity]) |
||
240 | ]; |
||
241 | } catch (QueryException $e) { |
||
242 | DB::rollBack(); |
||
243 | Log::error($e); |
||
244 | return [ |
||
245 | 'code' => 1, |
||
246 | 'msg' => '编辑失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前内容已存在' : '其它错误'), |
||
247 | 'redirect' => false |
||
248 | ]; |
||
249 | } |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * 内容管理-删除内容 |
||
254 | * |
||
255 | * @param int $id |
||
256 | */ |
||
257 | public function delete($entity, $id) |
||
274 | ]; |
||
275 | } |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * 内容管理-内容批量操作 |
||
280 | * |
||
281 | * @param Request $request |
||
282 | * @return array |
||
283 | */ |
||
284 | public function batch(Request $request) |
||
285 | { |
||
286 | $type = $request->input('type', ''); |
||
287 | $ids = $request->input('ids'); |
||
288 | if (!is_array($ids)) { |
||
289 | return [ |
||
290 | 'code' => 1, |
||
291 | 'msg' => '参数错误' |
||
292 | ]; |
||
293 | } |
||
294 | $ids = array_map(function ($item) { |
||
295 | return intval($item); |
||
296 | }, $ids); |
||
297 | |||
298 | $message = ''; |
||
299 | switch ($type) { |
||
300 | case 'delete': |
||
301 | $contents = ContentRepository::model()->whereIn('id', $ids)->get(); |
||
302 | ContentRepository::model()->whereIn('id', $ids)->delete(); |
||
303 | event(new ContentDeleted($contents, $this->entity)); |
||
304 | break; |
||
305 | default: |
||
306 | break; |
||
307 | } |
||
308 | |||
309 | return [ |
||
310 | 'code' => 0, |
||
311 | 'msg' => '操作成功' . $message, |
||
312 | 'reload' => true |
||
313 | ]; |
||
314 | } |
||
315 | |||
316 | protected function validateEntityRequest() |
||
317 | { |
||
318 | $entityRequestClass = '\\App\\Http\\Requests\\Admin\\Entity\\' . |
||
319 | Str::ucfirst(Str::singular($this->entity->table_name)) . 'Request'; |
||
320 | if (class_exists($entityRequestClass)) { |
||
321 | $entityRequestClass::capture()->setContainer(app())->setRedirector(app()->make('redirect'))->validateResolved(); |
||
322 | } |
||
323 | } |
||
324 | |||
325 | protected function useUserDefinedSaveHandler($request, $entity) |
||
326 | { |
||
327 | $entityControllerClass = $this->userDefinedHandlerExists('save'); |
||
328 | if ($entityControllerClass === false) { |
||
329 | return null; |
||
330 | } |
||
331 | return call_user_func([new $entityControllerClass, 'save'], $request, $entity); |
||
332 | } |
||
333 | |||
334 | protected function useUserDefinedUpdateHandler($request, $entity, $id) |
||
335 | { |
||
336 | $entityControllerClass = $this->userDefinedHandlerExists('update'); |
||
337 | if ($entityControllerClass === false) { |
||
338 | return null; |
||
339 | } |
||
340 | return call_user_func([new $entityControllerClass, 'update'], $request, $entity, $id); |
||
341 | } |
||
342 | |||
343 | protected function useUserDefinedIndexHandler($entity) |
||
350 | } |
||
351 | |||
352 | protected function useUserDefinedListHandler($request, $entity) |
||
353 | { |
||
354 | $entityControllerClass = $this->userDefinedHandlerExists('list'); |
||
355 | if ($entityControllerClass === false) { |
||
356 | return null; |
||
357 | } |
||
358 | return call_user_func([new $entityControllerClass, 'list'], $request, $entity); |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * 判断自定义的处理方法是否存在 |
||
363 | * |
||
364 | * @param string $method 方法名 |
||
365 | * @return string|boolean 存在返回控制器类名,不存在返回false |
||
366 | */ |
||
367 | protected function userDefinedHandlerExists($method) |
||
376 | } |
||
377 | |||
378 | protected function getAddOrEditViewPath() |
||
389 | } |
||
390 | |||
391 | protected function getUpdateData($request, $entity) |
||
392 | { |
||
393 | $fieldInfo = EntityFieldRepository::getUpdateFields($entity); |
||
394 | $data = []; |
||
395 | foreach ($fieldInfo as $k => $v) { |
||
396 | if ($v === 'checkbox') { |
||
397 | $data[$k] = ''; |
||
398 | } |
||
403 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.