/**
  * Return true if this user may change the state of this attachment
  *
  * (Note that all of the arguments are assumed to be valid; no sanity checking is done.
  *	It is up to the caller to validate the arguments before calling this function.)
  *
  * @param	int		$parent_id				the ID for the parent object
  * @param	string	$parent_entity			the type of entity for this parent type
  * @param	int		$attachment_creator_id	the ID of the creator of the attachment
  * @param	object	$user_id				the user_id to check (optional, primarily for testing)
  *
  * @return true if this user may change the state of this attachment
  */
 public function userMayChangeAttachmentState($parent_id, $parent_entity, $attachment_creator_id, $user_id = null)
 {
     // If the user generally has permissions to edit all content, they
     // may change this attachment state (editor, publisher, admin, etc)
     $user = JFactory::getUser($user_id);
     if ($user->authorise('com_content', 'edit', 'content', 'all')) {
         return true;
     }
     require_once JPATH_ADMINISTRATOR . '/components/com_attachments/permissions.php';
     // Handle each entity type
     switch ($parent_entity) {
         case 'category':
             // ?? Deal with parents being created (parent_id == 0)
             // First, determine if the user can edit this category
             if (!AttachmentsPermissions::userMayEditCategory($parent_id)) {
                 return false;
             }
             // See if the user can change the state of any attachment
             if ($user->authorise('core.edit.state', 'com_attachments')) {
                 return true;
             }
             // See if the user has permissions to change the state of their own attachments
             if ($user->authorise('attachments.edit.state.own', 'com_attachments') && (int) $user->id == (int) $attachment_creator_id) {
                 return true;
             }
             // See if the user has permission to change the state of any attachments for categories they created
             if ($user->authorise('attachments.edit.state.ownparent', 'com_attachments')) {
                 $category_creator_id = $this->getParentCreatorId($parent_id, 'category');
                 return (int) $user->id == (int) $category_creator_id;
             }
             break;
         default:
             // Articles
             // ?? Deal with parents being created (parent_id == 0)
             // First, determine if the user can edit this article
             if (!AttachmentsPermissions::userMayEditArticle($parent_id)) {
                 return false;
             }
             // See if the user can change the state of any attachment
             if ($user->authorise('core.edit.state', 'com_attachments')) {
                 return true;
             }
             // See if the user has permissions to change the state of their own attachments
             if ($user->authorise('attachments.edit.state.own', 'com_attachments') && (int) $user->id == (int) $attachment_creator_id) {
                 return true;
             }
             // See if the user has permission to edit the state of any attachments for articles they created
             if ($user->authorise('attachments.edit.state.ownparent', 'com_attachments')) {
                 $article_creator_id = $this->getParentCreatorId($parent_id, 'article');
                 return (int) $user->id == (int) $article_creator_id;
             }
     }
     return false;
 }
 /**
  * Test to see whether a user may edit a specified article
  * 
  * @dataProvider provider
  *
  * @param int $user_id the id of the user to test
  * @param string $username the username (for error printouts)
  * @param int $art_id the id of the article to test
  * @param int $may_edit the expected result of the test
  */
 public function testArticleEdit($user_id, $username, $art_id, $may_edit)
 {
     $result = AttachmentsPermissions::userMayEditArticle((int) $art_id, (int) $user_id);
     $errmsg = "----> Failed test for {$username} edit article {$art_id}, expected {$may_edit}, got {$result}";
     $this->assertEquals($result, (bool) $may_edit, $errmsg);
 }