2

I'm writing a customer portal plugin that will have 3 types of users.

  • Organizations
  • Organization members
  • Private

I would like to use Craft's built in UserRecord for front end login, backend management, ..?, and extend it to handle these three user types.

The way I have it set up so far, is that I have a proxy user record, which handles the relations to the organization profile and user profile records. Below I have listed the relevant attributes/keys and relations for each of the records:


MyPortal_ProxyUserRecord:
Acts as a middle man between the Craft UserRecord and the two records further below.

id
craft_user_id
organization_id  (# | null if private user)
user_id  (# | null if organization)

'craft_user' => array(static::BELONGS_TO, 'UserRecord', 'craft_user_id'),
'organization_profile' => array(static::HAS_ONE, 'MyPortal_OrganizationProfileRecord', 'proxy_user_id'),
'user_profile' => array(static::HAS_ONE, 'MyPortal_UserProfileRecord', 'proxy_user_id'),


MyPortal_OrganizationProfileRecord:

id
proxy_user_id
contact_user_id

'proxy_user' => array(static::BELONGS_TO, 'MyPortal_ProxyUserRecord', 'proxy_user_id'),
// Organization members:
'user_profiles' => array(static::HAS_MANY, 'MyPortal_UserProfileRecord', 'organization_id'),
// Contact user:
'contact_user' => array(static::HAS_ONE, 'MyPortal_UserProfileRecord', 'organization_id'),


MyPortal_UserProfileRecord:
Handles both private users and organization members.

id
proxy_user_id
organization_id  (# | null if private user)

'proxy_user' => array(static::BELONGS_TO, 'MyPortal_ProxyUserRecord', 'proxy_user_id'),
'organization' => array(static::BELONGS_TO, 'MyPortal_OrganizationProfileRecord', 'organization_id'),


Questions:

  1. Is it possible to extend the Craft UserRecord itself with the necessary attributes and relations to handle the OrganizationProfileRecord and the UserProfileRecord, and ditch the proxy user record? If so, how do I do that?
  2. If not possible, should I structure my records and relations differently than I have done so far?
  3. Are there any pitfalls I should be vary of?


Please let me know if I should provide any further information! :)

Many thanks in advance for any help you can provide! bowing

/Monkey

1

When extending Craft's active record classes (like UserRecord), you'll only be able to setup the AR relationships one way (from your class to Craft's i.e. MyPortal_ProxyUserRecord => UserRecord) as you've done. Setting up the relationship in the other direction (UserRecord => MyPortal_ProxyUserRecord) would require hacking core Craft files (not recommended).

For queries going in that direction, you'd need to go outside the scope of AR and use QueryBuilder to manually build the SQL query you need.

As for your current structure, I'm not sure what the purpose of MyPortal_ProxyUserRecord is. Why not just have MyPortal_UserProfileRecord and MyPortal_OrganizationProfileRecord link to UserRecord directly? Maybe you just want a single place for that interaction instead of two, I suppose.

  • I see. Coming from Laravel, where you can easily add relations to a model (record), without altering it's code, by defining these in the "boot" function of your plugin class, I figured it would be possible to do the same in Yii. Perhaps this is not possible? Ok. I'll make some helper functions in my account service class, to handle organization vs member vs private user. Ex: function isOrganization($craft_user_id) { ... } function getOrganizationMembers($craft_user_id) { ... } Yes, I wanted a unified place, but I'll ditch the proxy user record in favor of the service helper functions. Thanks – CodeMonkey Feb 25 '16 at 10:23
  • FWIW what you're trying to do will be a lot easier in the upcoming Craft 3 (which uses Yii 2) – Brad Bell Feb 25 '16 at 17:52
  • Yeah, I did some quick reading about that, and it does seem quite nice. =) Any ETA on Craft 3? – CodeMonkey Mar 2 '16 at 7:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.