Completed
Push — master ( 68e801...0d4db1 )
by Jianhua
04:39
created

ContentController::save()   B

Complexity

Conditions 8
Paths 51

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
eloc 28
c 2
b 0
f 0
nc 51
nop 2
dl 0
loc 42
rs 8.4444
1
<?php
2
/**
3
 * @author  Eddy <[email protected]>
4
 */
5
6
namespace App\Http\Controllers\Admin;
7
8
use App\Http\Controllers\Controller;
9
use App\Http\Requests\Admin\ContentRequest;
10
use App\Model\Admin\Content;
11
use App\Model\Admin\Entity;
12
use App\Model\Admin\EntityField;
13
use App\Repository\Admin\ContentRepository;
14
use App\Repository\Admin\EntityFieldRepository;
15
use App\Repository\Admin\EntityRepository;
16
use Illuminate\Database\QueryException;
17
use Illuminate\Http\Request;
18
use Illuminate\Support\Str;
19
use Illuminate\View\View;
20
use App\Model\Admin\Tag;
21
use App\Model\Admin\ContentTag;
22
use Illuminate\Support\Facades\DB;
23
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)
257
    {
258
        try {
259
            ContentRepository::delete($id);
260
            return [
261
                'code' => 0,
262
                'msg' => '删除成功',
263
                'redirect' => route('admin::content.index')
264
            ];
265
        } catch (\RuntimeException $e) {
266
            return [
267
                'code' => 1,
268
                'msg' => '删除失败:' . $e->getMessage(),
269
                'redirect' => route('admin::content.index')
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)
338
    {
339
        $entityControllerClass = $this->userDefinedHandlerExists('index');
340
        if ($entityControllerClass === false) {
341
            return null;
342
        }
343
        return call_user_func([new $entityControllerClass, 'index'], $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)
362
    {
363
        $entityControllerClass = '\\App\\Http\\Controllers\\Admin\\Entity\\' .
364
            Str::ucfirst(Str::singular($this->entity->table_name)) . 'Controller';
365
        if (class_exists($entityControllerClass) && method_exists($entityControllerClass, $method)) {
366
            return $entityControllerClass;
367
        }
368
369
        return false;
370
    }
371
372
    protected function getAddOrEditViewPath()
373
    {
374
        $view = 'admin.content.add';
375
        // 自定义模板
376
        $modelName = Str::singular($this->entity->table_name);
377
        $path = resource_path('views/admin/content/' . $modelName . '_add.blade.php');
378
        if (file_exists($path)) {
379
            $view = 'admin.content.' . $modelName . '_add';
380
        }
381
382
        return $view;
383
    }
384
}
385