We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 49407
    • 159 Posts
    I have a table/class `UserAttributesSoc` in a Package called Social. This package also has many other tables/classes. I have setup a foreign key in the database for the `user_id` row in social_user_attributes_soc table that is pointing to modx_users table, it's a unique field because it must be. (social_ is a prefix)

    When I run the steps in the docs that tell you to use writeSchema(), that method writes the schema erroneously, completely ignores the foreign key assignment already in the database, and tries to force `user_id` to be a PK. Now, from what I have been told over Slack you cannot have a PK for an extended user table. So what the heck is going on?

    The only difference from previously functioning package to currently unable to access extended user methods and data is that I upgraded from MODx 2.5.7 to 2.6.5 and renamed the table from generic extendeduser's user_data to user_attributes_soc. I went through the same steps Bob told me to, that I'd written down, last time I got this working, but it just won't work now.

    I already added a system setting for this...
    key: extension_packages
    value: [{"UserAttributesSoc":{"path":"[[++core_path]]components/UserAttributesSoc/model/"}}]

    My Package Requirements:

    • Ability to access methods I've written with $extUser->method()
    • Ability to getOne() instance of the extended user's data that is in a table called user_attributes_soc
    • Keep my class name & methods inside userattributessoc.class.php in the Social package, not create a new generic class called extendeduser
    • Maintain sanity

    Here is the way I think the schema should be after writeSchema()...
    	<object class="ExtUser" extends="modUser">
            	<composite alias="ExtUser" local="id" class="UserAttributes" foreign="user_id" cardinality="one" owner="local" />
    	</object>
    	<object class="UserAttributesSoc" table="user_attributes_soc" extends="xPDOObject">
    		<field key="user_id" dbtype="int" precision="11" phptype="integer" null="false" index="index" />
    		<field key="ig_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="tw_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="yt_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="fb_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="ig_at" dbtype="varchar" precision="255" phptype="string" null="true" />
    		<field key="tw_at" dbtype="varchar" precision="255" phptype="string" null="true" />
    		<field key="yt_at" dbtype="varchar" precision="255" phptype="string" null="true" />
    		<field key="fb_at" dbtype="varchar" precision="255" phptype="string" null="true" />
    		<field key="dnd" dbtype="int" precision="1" phptype="integer" null="false" default="0" />
    		<field key="api_key" dbtype="varchar" precision="64" phptype="string" null="false" />
    		<field key="alias" dbtype="varchar" precision="64" phptype="string" null="false" />
    		<field key="bio" dbtype="text" phptype="string" null="true" />
    		<field key="followers" dbtype="longtext" phptype="string" null="true" />
    		<field key="following" dbtype="longtext" phptype="string" null="true" />
    
    		<index alias="id" name="id" primary="false" unique="true" type="BTREE">
                <column key="id" length="" collation="A" null="false" />
            </index>
            <aggregate alias="ExtUser" class="modUser" local="user_id" foreign="id" cardinality="one" owner="foreign"/>
    	</object>


    Here's what writeSchema() produces...
    	<object class="UserAttributesSoc" table="user_attributes_soc" extends="xPDOObject">
    		<field key="user_id" dbtype="int" precision="11" attributes="unsigned" phptype="integer" null="false" index="pk" />
    		<field key="ig_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="tw_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="yt_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="fb_id" dbtype="bigint" precision="17" phptype="integer" null="true" />
    		<field key="ig_pw" dbtype="varchar" precision="32" phptype="string" null="true" />
    		<field key="tw_pw" dbtype="varchar" precision="32" phptype="string" null="true" />
    		<field key="yt_pw" dbtype="varchar" precision="32" phptype="string" null="true" />
    		<field key="fb_pw" dbtype="varchar" precision="32" phptype="string" null="true" />
    		<field key="dnd" dbtype="int" precision="1" phptype="integer" null="false" default="0" />
    		<field key="api_key" dbtype="varchar" precision="64" phptype="string" null="true" />
    		<field key="alias" dbtype="varchar" precision="32" phptype="string" null="false" />
    		<field key="bio" dbtype="text" phptype="string" null="true" />
    		<field key="followers" dbtype="int" precision="11" phptype="integer" null="false" default="0" />
    		<field key="following" dbtype="int" precision="11" phptype="integer" null="false" default="0" />
    
    		<index alias="user_id" name="user_id" primary="false" unique="true" type="BTREE" >
    			<column key="user_id" length="" collation="A" null="false" />
    		</index>
    	</object>


    May I please get step by step instructions on how to implament my package in 2.6.5? I just want to release this huge social network platform package that is basically a facebook clone using modx as the engine. Everyone I've talked to is dying to see it running in 2.5.6 and I'm just about to say forget it, won't work in 2.5.6, too bad...but there has got to be a better resolution than giving up.

    I spent almost 4 years developing this extra for people to enjoy using and It's got to be usable in 2.5.6, I just can't figure what the huge problem is with loading the new class over the old generic one. Maybe I need to seek a partner who can focus on core compatability...Seems like I just don't get how or why MODx does things the way it does, like not adding existing DB foreign keys to the schema when it writes the schema.
      • 3749
      • 24,544 Posts
      If I'm understanding you, MODX (xPDO, actually) has no way of knowing about the related objects by looking at the DB in writeSchema(). For any complex related-object use case, you need to create your own schema, or modify the one it creates.

      FWIW, I usually extend xPDOSimpleObject instead of xPDOObject. The former automatically give you 'id' as the PK, then you can have your own indexed key to store the user ID. I'm not sure if that will help with your problem, but it might.

      Something that helped me a lot was to look at the modUserProfile section of the MODX schema. It's basically what you want -- a table that contains extra user data. You can use $profile->getOne('User'), and going the other way, $user->getOne('Profile');

      Something else you might try is to use the wizard in the ClassExtender extra to create your table and the class and map files for you. It will set up the relationships between its table and the modx_users table. Once that's working, you can create other tables if necessary. It will also put your extra fields a the bottom of the Manager's Create/Edit User panel, which might be handy.

      ClassExtender takes a slightly different approach than you have in that it does not extend modUser (to avoid conflicts with other extras like Articles which extend modUser), but does put the user's ID in the 'internalKey' field of the custom table (just like the User Profile does). It extends xPDOSimpleObject rather than modUser, but that still gives you all the related object methods like getOne(), getMany(), getCollection(), etc. It comes with a snippet that works like getResources, but for users, that you could modify to meet your needs.

      I wish I had time to help you more directly (it sounds like a great project), but I'm completely swamped.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting