Suggestion to improve CDbAuthManager::addItemChild

This isn't really a bug but a suggestion.

The function is:

public function addItemChild($itemName,$childName)


	{


		$sql="SELECT * FROM {$this->itemTable} WHERE name=:name1 OR name=:name2";


		$command=$this->db->createCommand($sql);


		$command->bindValue(':name1',$itemName);


		$command->bindValue(':name2',$childName);


		$rows=$command->queryAll();


		if(count($rows)==2)


		{


			static $types=array('operation','task','role');


			if($rows[0]['name']===$itemName)


			{


				$parentType=$rows[0]['type'];


				$childType=$rows[1]['type'];


			}


			else


			{


				$childType=$rows[0]['type'];


				$parentType=$rows[1]['type'];


			}


			$this->checkItemChildType($parentType,$childType);


			if($this->detectLoop($itemName,$childName))


				throw new CException(Yii::t('yii','Cannot add "{child}" as a child of "{name}". A loop has been detected.',


					array('{child}'=>$childName,'{name}'=>$itemName)));





			$sql="INSERT INTO {$this->itemChildTable} (parent,child) VALUES (:parent,:child)";


			$command=$this->db->createCommand($sql);


			$command->bindValue(':parent',$itemName);


			$command->bindValue(':child',$childName);


			$command->execute();


		}


		else


			throw new CException(Yii::t('yii','Either "{parent}" or "{child}" does not exist.',array('{child}'=>$childName,'{name}'=>$itemName)));


	}

My sugestion it to put a call to detectLoop right in the beggining of the function because if we try to add  'RoleA' to 'RoleA' we get the loop detected message. The way it is now, we get the "Either {parent} or {child} does not exist." message because the query return 1 row.

BTW, @ line 136 of CDbAuthManager.php there is a little bug in the array keys. The phrase uses the tokens {parent} and {child} while in the replacement array the keys are {child} and {name}.

So, the sugested function is:

public function addItemChild($itemName,$childName)


	{


		if($this->detectLoop($itemName,$childName))


				throw new CException(Yii::t('yii','Cannot add "{child}" as a child of "{name}". A loop has been detected.',


					array('{child}'=>$childName,'{name}'=>$itemName)));


				


		$sql="SELECT * FROM {$this->itemTable} WHERE name=:name1 OR name=:name2";


		$command=$this->db->createCommand($sql);


		$command->bindValue(':name1',$itemName);


		$command->bindValue(':name2',$childName);


		$rows=$command->queryAll();


		if(count($rows)==2)


		{


			static $types=array('operation','task','role');


			if($rows[0]['name']===$itemName)


			{


				$parentType=$rows[0]['type'];


				$childType=$rows[1]['type'];


			}


			else


			{


				$childType=$rows[0]['type'];


				$parentType=$rows[1]['type'];


			}


			$this->checkItemChildType($parentType,$childType);


			if($this->detectLoop($itemName,$childName))


				throw new CException(Yii::t('yii','Cannot add "{child}" as a child of "{name}". A loop has been detected.',


					array('{child}'=>$childName,'{name}'=>$itemName)));





			$sql="INSERT INTO {$this->itemChildTable} (parent,child) VALUES (:parent,:child)";


			$command=$this->db->createCommand($sql);


			$command->bindValue(':parent',$itemName);


			$command->bindValue(':child',$childName);


			$command->execute();


		}


		else


			throw new CException(Yii::t('yii','Either "{parent}" or "{child}" does not exist.',array('{child}'=>$childName,'{parent}'=>$itemName)));


	}

Thanks! fixed.