3

ユーザーが追加したコメントのみを編集/削除できるように制限したい。私は、intergral30 という名前の人物による YouTube の例を見つけ、彼の指示に従いました。そして今、私の管理者アカウントはすべてを編集/削除する可能性がありますが、私のユーザーは自分のコメントにアクセスできません.

コードは次のとおりです: リソース

class Application_Model_CommentResource implements Zend_Acl_Resource_Interface{
public $ownerId = null;
public $resourceId = 'comment';

public function getResourceId() {
    return $this->resourceId;
}
}

役割

class Application_Model_UserRole implements Zend_Acl_Role_Interface{
public $role = 'guest';
public $id = null;

public function __construct(){
    $auth = Zend_Auth::getInstance();
    $identity = $auth->getStorage()->read();

    $this->id = $identity->id;
    $this->role = $identity->role;
}

public function getRoleId(){
    return $this->role;
}
}

アサーション

class Application_Model_CommentAssertion implements Zend_Acl_Assert_Interface
{
public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $user=null,
            Zend_Acl_Resource_Interface $comment=null, $privilege=null){
    // if role is admin, he can always edit a comment
    if ($user->getRoleId() == 'admin') {
        return true;
    }

    if ($user->id != null && $comment->ownerId == $user->id){
        return true;
    } else {
        return false;
    }
}

}

私の ACL には、アクセス チェック プラグインの preDispatch メソッドで呼び出される setDynemicPermissions という名前の関数があります。

public function setDynamicPermissions() {
    $this->addResource('comment');
    $this->addResource('post');

    $this->allow('user', 'comment', 'modify', new Application_Model_CommentAssertion());

    $this->allow('admin', 'post', 'modify', new Application_Model_PostAssertion());
}

public function preDispatch(Zend_Controller_Request_Abstract $request) 
{
    $this->_acl->setDynamicPermissions();
}

そして、コメント オブジェクトのリストを返すコメント モデルから ACL の isAllowed メソッドを呼び出しています。

public function getComments($id){
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();
    $commentResource = new Application_Model_CommentResource();

    $comments = array();
    foreach ($res as $comment) {
        $commentResource->ownerId = $comment[userId];

        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        if (Zend_Registry::get('acl')->isAllowed($userRole->getRoleId(), $commentResource->getResourceId(), 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}

誰が私が間違ったことを教えてもらえますか? または、管理者に投稿を開始する権利を与え、他のユーザーにコメントする権利を与えたい場合は、何を使用すればよいでしょうか。各ユーザーには自分のコメントを編集または削除する機会が必要であり、管理者にはすべての権限が必要です。

4

1 に答える 1

5

roleIdまだにを渡しているため、動的アサーションを間違った方法で使用しているようですisAllowed()

これらの動的アサーションが実際に行うことは、完全なオブジェクトを取得して操作することです。getResourceId()Zend は、オブジェクトを呼び出して、どのルールを使用する必要があるかを判断getRoleId()します。

したがって、文字列の代わりにオブジェクトisAllowed()を に渡すだけです。

public function getComments($id){
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();
    $commentResource = new Application_Model_CommentResource();

    $comments = array();
    foreach ($res as $comment) {
        $commentResource->ownerId = $comment[userId];

        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        // This line includes the changes
        if (Zend_Registry::get('acl')->isAllowed($userRole, $commentResource, 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}

しかし、もっとうまくやることができます

total new を実装する必要はありませんが、代わりに次のようApplication_Model_CommentResourceに actual を使用できます。Application_Model_Comment

// we are using your normal Comment class here
class Application_Model_Comment implements Zend_Acl_Resource_Interface {
    public $resourceId = 'comment';

    public function getResourceId() {
        return $this->resourceId;
    }

    // all other methods you have implemented
    // I think there is something like this among them
    public function getOwnerId() {
        return $this->ownerId;
    }
}

次に、アサーションはこのオブジェクトを使用して所有者を取得し、実際にログインしている人物と比較します。

class Application_Model_CommentAssertion implements Zend_Acl_Assert_Interface {
    public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $user=null,
        Zend_Acl_Resource_Interface $comment=null, $privilege=null){
    // if role is admin, he can always edit a comment
    if ($user->getRoleId() == 'admin') {
        return true;
    }

    // using the method now instead of ->ownerId, but this totally depends
    // on how one can get the owner in Application_Model_Comment
    if ($user->id != null && $comment->getOwnerId() == $user->id){
        return true;
    } else {
        return false;
    }
}

そして使い方はこんな感じです。

public function getComments($id) {
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();

    $comments = array();
    foreach ($res as $comment) {
        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        // no $commentResource anymore, just pure $comment
        if (Zend_Registry::get('acl')->isAllowed($userRole, $comment, 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}
于 2012-07-29T13:08:04.677 に答える