ContentController::batch()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 29
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 3
eloc 22
c 2
b 0
f 1
nc 3
nop 1
dl 0
loc 29
rs 9.568
1
<?php
2
/**
3
 * @author  Eddy <[email protected]>
4
 */
5
6
namespace App\Http\Controllers\Admin;
7
8
use App\Events\ContentCreated;
9
use App\Events\ContentCreating;
10
use App\Events\ContentDeleted;
11
use App\Events\ContentUpdated;
12
use App\Events\ContentUpdating;
13
use App\Http\Controllers\Controller;
14
use App\Http\Requests\Admin\ContentRequest;
15
use App\Model\Admin\Content;
16
use App\Model\Admin\Entity;
17
use App\Model\Admin\EntityField;
18
use App\Repository\Admin\ContentRepository;
19
use App\Repository\Admin\EntityFieldRepository;
20
use App\Repository\Admin\EntityRepository;
21
use Illuminate\Database\QueryException;
22
use Illuminate\Http\Request;
23
use Illuminate\Support\Str;
24
use Illuminate\View\View;
25
use App\Model\Admin\Tag;
26
use App\Model\Admin\ContentTag;
27
use Illuminate\Support\Facades\DB;
28
use Illuminate\Support\Facades\Log;
29
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)
0 ignored issues
show
Unused Code introduced by
The parameter $entity is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

257
    public function delete(/** @scrutinizer ignore-unused */ $entity, $id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
258
    {
259
        try {
260
            $content = ContentRepository::findOrFail($id);
261
            ContentRepository::delete($id);
262
            event(new ContentDeleted(collect([$content]), $this->entity));
263
264
            return [
265
                'code' => 0,
266
                'msg' => '删除成功',
267
                'reload' => true
268
            ];
269
        } catch (\RuntimeException $e) {
270
            return [
271
                'code' => 1,
272
                'msg' => '删除失败:' . $e->getMessage(),
273
                'redirect' => false
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)
344
    {
345
        $entityControllerClass = $this->userDefinedHandlerExists('index');
346
        if ($entityControllerClass === false) {
347
            return null;
348
        }
349
        return call_user_func([new $entityControllerClass, 'index'], $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)
368
    {
369
        $entityControllerClass = '\\App\\Http\\Controllers\\Admin\\Entity\\' .
370
            Str::ucfirst(Str::camel(Str::singular($this->entity->table_name))) . 'Controller';
371
        if (class_exists($entityControllerClass) && method_exists($entityControllerClass, $method)) {
372
            return $entityControllerClass;
373
        }
374
375
        return false;
376
    }
377
378
    protected function getAddOrEditViewPath()
379
    {
380
        $view = 'admin.content.add';
381
        // 自定义模板
382
        $modelName = Str::singular($this->entity->table_name);
383
        $path = resource_path('views/admin/content/' . $modelName . '_add.blade.php');
384
        if (file_exists($path)) {
385
            $view = 'admin.content.' . $modelName . '_add';
386
        }
387
388
        return $view;
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
            }
399
        }
400
        return array_merge($data, $request->only(array_keys($fieldInfo)));
401
    }
402
}
403