在我的Laravel应用程序中,我有几个策略正在运行,但其中一个不起作用。
控制器
//
// YMPianoRollLayout.swift
//
import UIKit
class YMPianoRollLayout: UICollectionViewLayout {
let notes : Array<CGPoint> = []
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!;
}
override var collectionViewContentSize : CGSize {
let cv = self.collectionView as! YMPianoRollCollectionView
let screenInfo = cv.pianoRollViewController.screenInfo
let totalSize = screenInfo.collectionViewContentsSize();
print("contentSize = \(totalSize)")
return totalSize;
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
// "screenInfo" keeps the user specified view parameters including the scale ratio by the pinch gesture
let cv = self.collectionView as! YMPianoRollCollectionView;
let pianoRoll = cv.pianoRollViewController;
// Check which musical note can be included in the view rect
let indexArray: Array<Int> = pianoRoll!.getNoteIndexes(inRect:rect, useOnlyStartTime: false);
var retArray : [UICollectionViewLayoutAttributes] = []
for i in indexArray {
if let _ = pianoRoll?.pattern.eventSequence[i] as? YMPatternEventNoteOn {
retArray.append( self.layoutAttributesForPatternEventInfo(i) )
}
}
// This always reports non-zero count. Also checked the positions of each array members
// by breaking here and they all had proper size and positions
print("retArray count = \(retArray.count)");
return retArray
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let i = Int((indexPath as NSIndexPath).row)
return self.layoutAttributesForPatternEventInfo(i)
}
//
// This is my specific func to convert the musical time-pitch into the view geometory
//
func layoutAttributesForPatternEventInfo(_ index: Int) -> UICollectionViewLayoutAttributes!{
let cv = self.collectionView as! YMPianoRollCollectionView
// "screenInfo" keeps the user specified view parameters including the scale ratio by the pinch gesture
let screenInfo = cv.pianoRollViewController.screenInfo
// Retrieve musical event
let event = cv.pianoRollViewController.pattern.eventSequence[index]
let index = IndexPath(row:index, section: 0)
let newAttr = UICollectionViewLayoutAttributes(forCellWith:index)
var frame : CGRect!
if let e = event as? YMPatternEventNoteOn {
let noteNo = e.noteNo;
let origin = YMMusicalValuePoint(time:event.time, noteNumber:noteNo);
let size = YMMusicalValueSize(timeLength:e.duration, numberOfNotes: 1);
// Actual size calculation is done in my "screenInfo" class.
frame = screenInfo.getPhysicalRange(YMMusicalValueRange(origin:origin, size:size));
} else {
frame = CGRect(x: 0, y: 0, width: 0, height: 0);
}
newAttr.frame = frame;
newAttr.zIndex = 1;
return newAttr
}
//
// For checking the bounds
//
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
print("BBB newBounds = \(newBounds)")
return true
}
}
政策
public function store(Project $project, CreateActionRequest $request)
{
$this->authorize('store', $project);
Action::create([
'name' => $request->name,
]);
return redirect()->route('projects.show', $project->id)->withSuccess('Massnahme erfolgreich gespeichert');
}
AuthServiceProvider
namespace App\Policies\Project;
use App\Models\Project\Project;
use App\Models\User;
use App\Models\Project\Action;
use Illuminate\Auth\Access\HandlesAuthorization;
class ActionPolicy
{
use HandlesAuthorization;
public function store(User $user, Project $project)
{
return $user->company_id === $project->company_id;
}
}
CreateActionRequest
protected $policies = [
'App\Models\User' => 'App\Policies\CompanyAdmin\UserPolicy',
'App\Models\Company' => 'App\Policies\CompanyAdmin\CompanyPolicy',
'App\Models\Team' => 'App\Policies\CompanyAdmin\TeamPolicy',
'App\Models\Department' => 'App\Policies\CompanyAdmin\DepartmentPolicy',
'App\Models\Location' => 'App\Policies\CompanyAdmin\LocationPolicy',
'App\Models\Division' => 'App\Policies\CompanyAdmin\DivisionPolicy',
'App\Models\Costcenter' => 'App\Policies\CompanyAdmin\CostcenterPolicy',
'App\Models\Workplace' => 'App\Policies\CompanyAdmin\WorkplacePolicy',
'App\Models\Product' => 'App\Policies\CompanyAdmin\ProductPolicy',
'App\Models\Project\Action' => 'App\Policies\Project\ActionPolicy',
'App\Models\Project\Project' => 'App\Policies\Project\ProjectPolicy',
];
除ActionPolicy和ProjectPolicy外,所有政策均有效。 我在策略中添加了一个__construct()方法来检查策略是否被调用。但ActionPolicy和ProjectPolicy无效。 我该如何搜索错误?我试过用dd()但我总是得到消息:这个动作是未经授权的
答案 0 :(得分:0)
由于您正在注入CreateActionRequest
而不是Request
,这意味着您要定义自己的一套规则来授权方法中的FormRequest
。此外,这意味着您必须定义一些规则,其中包括&#34; FormRequest
&#34;必须通过才能到达你的控制器,这是一个很好的概念,我喜欢Laravel,因为代码不是集中的,而是传播,每一层都有它自己的责任。现在,您不必从CreateActionRequest
调用任何方法,也不必在控制器中编写有关该类的任何代码,因为Laravel在authorize
之前运行default
方法允许Request
到达您的控制器,然后在authorize
中运行CreateActionRequest
方法运行rules
方法,该方法验证所有给定字段都通过您指定的表达式,执行是这样的CreateActionRequest => rules => authorize => IF(authorized) Controller ELSE Not authorized
,希望这是有道理的。为了修复你的代码:
1。)删除$this->authorize('store', $project);
如果您的not authorized
通过name
方法内rules
方法内的真值测试,则可以传递CreateActionRequest
错误。如果您希望使用Action Policy
,则需要使用它来连接自定义Request
(CreateActionRequest),具体方法如下:
public function authorize()
{
$store = $this->route('project');
//The above line will return Project object if your mapping is correct
//If it's not it will return the value you passed to your route for {project}
return $this->user() && $this->user()->can('store', $store);
}
修改强>
Here is the link您可以在其中查看如何使用CreateActionRequest
正确授权和关联政策
答案 1 :(得分:0)
您是否最后使用Request
对象定义了所有控制器方法?
public function store(Project $project, CreateActionRequest $request)
Request
对象应该是方法签名中的第一个参数:
public function store(CreateActionRequest $request, Project $project)
依赖注入&amp;路线参数
如果您的控制器方法也期望来自路由参数的输入,则应在其他依赖项之后列出路由参数。
大多数Laravel授权机制都有相同的方法签名,允许它们在不同的类中工作。