防止更改属于错误项目的子项

时间:2016-07-26 09:57:29

标签: php laravel laravel-5.2

我有一个包含事件的Laravel应用程序。每个事件都包含项目。事件表如下:

+----+-------------+------------+-------------------+---------------------+---------------------------+---------------------+---------------------+
| id | category_id | event_name | event_description | event_startdate     | event_closedate           | created_at          | updated_at          |
+----+-------------+------------+-------------------+---------------------+---------------------------+---------------------+---------------------+
|  1 |           1 | Event 1    | Event 1           | 2016-05-02 00:00:00 | 2016-06-30 00:00:00       | 2016-07-07 15:59:03 | 2016-07-08 12:26:07 |
|  2 |           1 | Event 2    | Event 2           | 2016-06-02 00:00:00 | 2016-07-30 00:00:00       | 2016-07-07 15:59:03 | 2016-07-08 12:26:22 |
|  3 |           2 | Event 3    | Event 3           | 2016-07-02 00:00:00 | 2016-08-19 00:00:00       | 2016-07-07 15:59:03 | 2016-07-08 12:27:04 |
|  4 |           2 | Event 4    | Event 4           | 2016-09-01 00:00:00 | 2016-10-30 00:00:00       | 2016-07-07 15:59:03 | 2016-07-07 15:59:03 |
+----+-------------+------------+-------------------+---------------------+---------------------------+---------------------+---------------------+

并且每个事件包含许多项目,表格如下:

+----+------------+-----------+-----------------------+
| id | event_id   | item_name | item_description      |
+----+------------+-----------+-----------------------+
|  1 |          1 | Item 1    | Item 1 - description  |
|  2 |          1 | Item 2    | Item 2 - description  |
|  3 |          2 | Item 3    | Item 3 - description  |
|  4 |          2 | Item 4    | Item 4 - description  |
|  5 |          3 | Item 5    | Item 5 - description  |

我正在主页上显示当前事件。我想确保这些项目属于该事件。所以以下内容应该有效:

http://localhost:5000/event/2/item/3
http://localhost:5000/event/3/item/5 

以下不应该起作用

http://localhost:5000/event/2/item/1
http://localhost:5000/event/3/item/4

我正在通过在我的控制器中添加一些逻辑来解决这个问题(对于route / event / {event} / item / {item}。我正在使用的代码如下:

$now = Carbon::now();

$event = Event::where('event_startdate', '<=', $now)
            ->where('event_closedate', '>=', $now)
            ->findOrFail($event->id);

$item = Item::where('event_id', '=', $event->id)
        ->findOrFail($item->id);


return view('guest/items/detail', ['item' => $item]);

如果事件ID属于过去或将来的事件,则会显示“未找到”视图。类似地,如果该项目不属于某个事件,则会显示“未找到”视图。

虽然这项工作,我觉得这不是最佳做法,必须有更优化的方法来实现这一目标?

相关路线如下:

Route::get('event/{event}/item/{item}', ['as' => 'item_details', 'uses' => 'Guest\ItemsController@showItemDetail' ]);

2 个答案:

答案 0 :(得分:0)

根据收到的反馈,我想出了以下内容:

public function showItemDetail(Event $event, Item $item)
    {
        $event = Event::findOrFail($event->id);

        if ($event->id != $item->event_id) {
            abort(403);
        }

        return view('guest/item/detail',  ['item' => $item]);

    }

相信这比我原来的方法更好。

答案 1 :(得分:0)

我对->where()条款的评论有点不对劲;如果在特定日期范围内,他们会努力过滤Event只返回。这是我的方法:

如果您正在使用Laravel的关系,则可以轻松找到附加到此Event的{​​{1}}并验证它是否正确。在同一项检查中,您可以检查Item$item是否存在,$item->event网址参数的完整性以及$eventId是否在特定时间段内:< / p>

$event

以上只是逻辑的一个示例,创建public function showItemDetail($eventId, $itemId){ $now = Carbon::now(); $item = Item::with(["event" => function($query) use($now){ $query->where('event_startdate', '<=', $now)->where('event_closedate', '>=', $now); }])->where("id", "=", $itemId)->first(); // Check that the Event's ID matches that in the URL if(!$item){ abort(403); // No Item found. } else if(!$item->event){ abort(403); // No Event found. } else if($item->event->id != $eventId) { abort(403); // Mismatched EventID } } 标志可能更简单,如果满足任何条件,则将其设置为$valid = true;,并且仅返回{{ 1}}如果false等同于abort(403)。另外if($valid == false)是一种可接受的方法,我只使用true进行额外控制。