简体   繁体   中英

Symfony2 users with doctrine

I'm looking for best practices to fetch users created content. I have $user object form 'security.context' and I need to get single record created by this user by some $record_id,

so what I should do?

$this->getDoctrine()->getRepository('AcmeRecordBundle:Record')
->findOneBy(array( 'id' => $record_id, 'user' => $user->getId() ));

This doesn't look good to me, because I have lot's of information that needs to be fetch looking for user too(to don't let other users try get it by some id). And for any content( personal photo, some other private content) I have to pass 'user' => $user->getId() ?

Or it's better to create UserRepository with all these functions? getRecordById($id), getPhotoById($id), getPrivateInformationById($id), etc.

I was working with Rails a little, and there I was able to define current_user method

def current_user
  return @current_user if defined?(@current_user)
  # ....
end

and then just use it as

current_account.records.find(params[:id])

is there any possibility to make it work like this with Doctrine2 and Symfony2? Like

$user->getRecords()->find($recordId)

在任何情况下,你必须指定user ,你传递给你的函数,如指定其处理的定制仓库里取逻辑官方文档的学说。

Of course you have to pass the user's id for the "WHERE" sql clause, just because ROR did it magically behind the scenes (which is a very bad practice imo), doesn't mean it didn't do it at all.

As for the other matter, both solutions are ok:

  1. Fetch data from the particular repository, and pass the object id + the user's id, or:
  2. Create methods which internally get user's id and put them in queries

And remember that user's id is fetched only once during the request, so don't worry about getting it from the security context too much.

You need to implement Symfony 2 ACL features. This allows you to specify ownership for "domain objects" (individual instances of DB classes) and what kind of access users have on a domain object. Then you can use for example the JMSSecurityExtraBundle and implement access controls based on object ownership. Once implemented your users won't be able to modify each other's objects (by parameter manipulation) and you won't need the additional parameter in your queries.

Here are a few relevant links:

  1. Access Control Lists (ACLs)
  2. JMSSecurityExtraBundle

Personally I found the repository classes to bloat things a bit in a small to mid-size application. Not sure what your approach is, but most everything I've read (and what I went w/ in a recent Doctrine 2 app) was to have a 'service' layer which manipulated the entities. This is b/c in D2, implementing save / delete etc in the entities undermines the purpose of the system which is to alleviate knowledge of persistence from the entities and treat them as Plain Old Php Objects (TM) ;)

The thing that looks odd to me about your query is passing an primary key id and a User id to fetch a User. Seems to me like the pk of the User table would be the user id, or at the very least if the user id isn't the pk (not sure why that would be) you should be able to get the records w/ just the pk. Here's the method to fetch a User object in my system

/**
 * @param int $iId user id
 *
 * @return object
 */
public function fetch($iId)
{
    return $this->_oEm->find('AwesomeApp\Entity\User', $iId);
}

The current user sort of function you're looking for should be related to the session in your application. In zf I've created a session handler that persists the doctrine User object to session storage, then when the session is read I re-attach the User object to the Entity Manager. You probly want to do something similar in sf, then a 'getCurrentUser' call would return the same User object as pulling it from the database. Storing a User object in the session prevents the need to go back to the database for it on every page load, for example if you just stored the User id in the session.

At the end of the day you're 'supposed' to put complex select queries into repositories, but this is obviously left to User discretion when it comes to best practices. In this case, when you have just a pk, I'd say there's no point to writing a repository class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM