I have a form, when clicking on the icon the class should switch to enabled/disabled
我有一个表单,当单击类应该切换到启用/禁用的图标时
$options = [
'enablePushState' => false,
'timeout' => 5000,
'options' => ['tag'=>'span', 'class'=>'access']
];
$id = \Yii::$app->request->get('_pjax');
if($id){$options['id'] = str_replace('#', '', $id);}
?>
<?php Pjax::begin($options); ?>
<?= Html::a('<i class="fa fa-users"></i>', ['/request/'.$id.'/access'], [
'class' => ($access['provider'] ?? null) ? 'enabled' : 'disabled'
]) ?>
<?php Pjax::end(); ?>
public function actionAccess($id){
$requestModel = $this->model->getRequestModel($id);
$this->model->requestToggleAccess($requestModel);
$access = $requestModel->checkAccess();
return $this->renderPartial('access.php', [
'id' => $id,
'access' => $access
]);
}
public function getRequestModel($id)
{
$requestModel = RequestModel::findOne($id);
return $requestModel;
}
public function requestToggleAccess($requestModel)
{
if (Yii::$app->request->isPjax) {
$access = $requestModel->checkAccess();
if( $access['provider'] ){
$request->accessRoleIds = null;
}else{
$request->accessRoleIds = [ROLE_PROVIDER, ROLE_PROVIDER_WORKER];
}
$request->saveAccess();
}
}
public function checkAccess()
{
return self::checkAccessBy($this->access);
}
public static function checkAccessBy($arr)
{
$access = [];
if(empty($arr)){return $access;}
foreach ($arr as $acc){
if(in_array($acc->role_id, [ROLE_PROVIDER, ROLE_PROVIDER_WORKER])){
$access['provider'] = true;
}
}
return $access;
}
The thing is that when initially the class is enabled
and I switch to disabled
, then everything works well, but when I switch in the reverse order from disabled
to enabled
, then I just go to this link '/request /'.$id.'/access'
and returns an empty page, it gives an error 500 without any details.
问题是,当最初启用类并切换到禁用时,一切工作正常,但当我以相反的顺序从禁用切换到启用时,然后我只转到这个链接‘/请求/’.$id.‘/Access’并返回一个空页面,它给出一个错误500,没有任何详细信息。
I'm trying to dump to find the problem
我正在试着转储以找出问题所在
In the actionAccess
function after calling the function checkAccess()
, I added
在调用函数check Access()之后,我在actionAccess函数中添加了
var_dump($access['provider']);
exit();
And got an error
得到了一个错误
Undefined array key "provider"
Although in the neighboring function requestToggleAccess
there is the same checkAccess()
call, after which I added the same dump, and instead of an error I get boolean(true)
, which is what it should be
尽管在邻近的函数questToggleAccess中有相同的check Access()调用,但在此之后我添加了相同的转储,并且我得到的不是错误,而是boolean(True),这是它应该是的
What could be the problem?
这可能是什么问题?
更多回答
Check requestToggleAccess($requestModel)
function
检查questToggleAccess($questModel)函数
@ustmaestro I checked this function and found no errors there
@ustmaestro我检查了这个函数,没有发现任何错误
优秀答案推荐
Look into requestToggleAccess
. The problem is that you assume $access['provider']
to exist. But inside checkAccessBy
(which is called by checkAccess
and whose return value will be assigned to $access
) you will see that $access['provider']
is not necessarily defined. We will return to this problem at the end of this answer, but first, let's make requestToggleAccess
less error-prone:
查看questToggleAccess。问题是您假设$Access[‘Provider’]存在。但在check AccessBy(由check Access调用,其返回值将被赋给$Access)中,您将看到不一定定义$Access[‘Provider’]。我们将在回答结束时返回到这个问题,但首先,让我们使questToggleAccess不太容易出错:
public function requestToggleAccess($requestModel)
{
if (Yii::$app->request->isPjax) {
$access = $requestModel->checkAccess();
if( $access['provider'] ?? false ){
$request->accessRoleIds = null;
}else{
$request->accessRoleIds = [ROLE_PROVIDER, ROLE_PROVIDER_WORKER];
}
$request->saveAccess();
}
}
I have merely added a ?? false
to your if
condition, that is, we know that $access
is defined at this point, but we avoid assuming that it has a value. Instead, we evaluate it and gather its value if it exists, defaulting to false
if it did not exist.
我只是添加了一个??如果条件为假,也就是说,我们知道在这一点上定义了$Access,但我们避免假设它具有值。相反,我们评估它并收集它的值(如果它存在),如果它不存在,则默认为FALSE。
Now, let's see why checkAccessBy
did not specify $access['provider']
. There you receive an array (after self::checkAccessBy($this->access)
is called) and you loop that array. For each item in that array, you check whether in_array($acc->role_id, [ROLE_PROVIDER, ROLE_PROVIDER_WORKER])
and if so, then you set $access['provider']
to true
. But you never ever set it to false
. This is an improved version of the same method:
现在,让我们来看看为什么check AccessBy没有指定$Access[‘Provider’]。在那里,您将收到一个数组(在调用self::check AccessBy($This->Access)之后),然后循环该数组。对于该数组中的每一项,检查in_array($acc->Role_id,[Role_Provider,Role_Provider_Worker]),如果是,则将$Access[‘Provider’]设置为TRUE。但您从未将其设置为False。这是同一方法的改进版本:
public static function checkAccessBy($arr)
{
$access = [
'provider' => false //We initialize provider with false and override it later if needed
];
if(empty($arr)){return $access;}
foreach ($arr as $acc){
if(in_array($acc->role_id, [ROLE_PROVIDER, ROLE_PROVIDER_WORKER])){
$access['provider'] = true;
}
}
return $access;
}
I have changed the initialization of $access
so it will have a provider element, which is initialized with true
and overriden later if needed.
我已经更改了$Access的初始化,因此它将拥有一个提供者元素,该元素被初始化为True,并在以后需要时被覆盖。
Another change you might want to make is to return $access
inside the loop if its provider is to be set to false
, but I did not do that, because you might prefer to return it at the end of the method for styling or other purposes.
您可能希望进行的另一个更改是,如果要将其提供程序设置为False,则在循环内返回$Access,但我没有这样做,因为您可能更喜欢在方法的末尾返回它,以便设置样式或用于其他目的。
更多回答
我是一名优秀的程序员,十分优秀!