We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 5253
    • 17 Posts
    Hi everyone,

    I'm thinking about to extend the regular site_content table, because I need a lot more information for some resources (it will become a gallery).
    First try: I used TVs. Unfortunately a lot of TVs slow down the page speed.
    Now I have two ideas but I don't know which one will be the MODx way wink

    1)
    Using one TV, storing all data as JSON
    => fast but for sorting I need to sort an array. Can't be done by MySQL

    2)
    Extending site_content table with a custom table (as described here mit modUser http://rtfm.modx.com/display/revolution20/Extending+modUser)
    => defining a new class_key for all the gallery resources (single pictures), sorting via tables

    I'm new on this level of developing and I hope someone will give me a hint. Perhaps I didn't realized that there's a third possibility or a improvement for 1 or 2 wink

    thanks a lot!
      *there are no strangers - just friends who never met*
      • 22303 MODX Staff
      • 10,725 Posts
      Optimally, you would combine 1 and 2. Create some new relations to custom tables storing the data as you might need to sort or filter by and then summarize the data into JSON which can be used for quick access when rendering data.

      In MODX 2.2, you can easily achieve this with Custom Resource Classes, and there will also be a namespaced properties field (stored as JSON) available on modResource (site_content table) with full API access in 2.2.1 you can use to store the data on the Resource itself.
        • 5253
        • 17 Posts
        hey,

        thanks for your quick response.
        Let me try to summarize:
        In the backend and with my CMP I'll use the custom table. This is done by creating custom CRC. I can sort, filter, edit, create, whatever using my CMP. In the front end I can access my modMyCRC with ->getObject("modMyCRC")

        But why do I need to summarize data into JSON? I mean, if I got all relevant information in a table and I want to show them up in the front end / CMP: I have to call getObject("modMyCRC"), so all the fields are available?

        Sorry for this - perhaps - silly question. But I'm new on 2.2 and I'll try my very best to make it the MODx & optimal way... I mean: using seperate TVs was quite simple and the script/CMP worked well... but when I tested it with a bit more than 50 docs it became very slow laugh

        cheers from Berlin smiley

          *there are no strangers - just friends who never met*
          • 22303 MODX Staff
          • 10,725 Posts
          Quote from: chrizz at Jan 15, 2012, 03:40 PM
          hey,
          Let me try to summarize:
          In the backend and with my CMP I'll use the custom table. This is done by creating custom CRC. I can sort, filter, edit, create, whatever using my CMP. In the front end I can access my modMyCRC with ->getObject("modMyCRC")

          But why do I need to summarize data into JSON? I mean, if I got all relevant information in a table and I want to show them up in the front end / CMP: I have to call getObject("modMyCRC"), so all the fields are available?

          Sorry for this - perhaps - silly question. But I'm new on 2.2 and I'll try my very best to make it the MODx & optimal way... I mean: using seperate TVs was quite simple and the script/CMP worked well... but when I tested it with a bit more than 50 docs it became very slow laugh
          It's not a silly question at all — we are still in the process of developing best practices for working with Custom Resource Classes.

          What we are trying to avoid is the need to add custom fields to the Resource table and instead encourage the use of custom related tables that can be joined on demand for back-end management and advanced front-end summarization requirements (searching/sorting). The only reason to summarize or duplicate the data in the new properties field is to make it easier to access and use that data without having to always join the additional tables, for performance reasons (i.e. avoiding additional joins/queries when working with collections of these custom Resources).
            • 5253
            • 17 Posts
            thanks for this explanation. This is what I like about MODx. It's getting more flexible with every new release smiley

            Unfortunatley this is the problem right now... I followed the steps in these tutorials:
            http://rtfm.modx.com/display/revolution20/Extending+modUser
            http://rtfm.modx.com/display/revolution20/Creating+a+Resource+Class

            I created a schema file, generated a model from this and added classes as described. The difference between the provided schema file of copyrightresources (custom CRC tutorial) is the second object (see below) which describes my custom table and the composite information.

            The CRC works out fine and it add's the copyright notice on every "ugalleryMeta" (name of my resource type) resource.
            I got no errors/warnings at all, but my custom table seems to be not accessible. For testing I used the getContent method and try to add a value from my custom field.
            $content .= $this->get("price");
            


            I also tried to set a custom table field @beforeSave. No effect.

            Here's a part of my schema file
            <?xml version="1.0" encoding="UTF-8"?>
            <model package="ugallerymeta" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM"> 
                <object class="ugalleryMeta" table="site_content" extends="modResource">
                    <composite alias="ugalleryMeta" local="id" foreign="ugallery" cardinality="one" owner="local" />
                </object>
             	
            	<object class="ugallery_metadata" table="ugallery_metadata" extends="xPDOSimpleObject">
                    <field key="ugallery" dbtype="int" phptype="integer" null="false" default="0" index="index" />
            		<field key="price" dbtype="int" precision="11" phptype="integer" null="false" />
            		<field key="status" dbtype="tinytext" phptype="string" null="false" />
            		<field key="technic" dbtype="varchar" precision="255" phptype="string" null="false" />
            		<field key="meta_data" dbtype="text" phptype="string" null="false" />
                            ... a lot more fields here ...
            		<aggregate alias="ugalleryMetadata" local="ugallery" foreign="id" cardinality="one" owner="foreign" />
            	</object>
            	
            </model>
            


            Does someone have a hint, where I could search for a coding error?

            thanks a lot!
              *there are no strangers - just friends who never met*
              • 3749
              • 24,544 Posts
              It's hard to tell without seeing more code, but it's possible that you want the variable returned from the get*() method rather than "this" and you might not want to use $content as a variable name since it is a field name:

              <?php
              $obj = $modx->getObject('MyObject', $c);
              $price = $obj->get('price');



              ---------------------------------------------------------------------------------------------------------------
              PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
              MODx info for everyone: http://bobsguides.com/MODx.html
                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
                • 5253
                • 17 Posts
                Hi Bob,

                I tried to use the custom CRC tutorial.
                In a snippet I tried to access a field in my custom table with these lines:
                $oUG = $modx->getObject("ugallery_metadata", array());
                var_dump($oUG->get("price"));
                

                This works fine. But when I try to get the pagetitle the same way it returns null. I think the missing link between modResource (site_content) and my ugallery package is the reason.

                If I update or create a new resource using my custom CRC there is no possibility to access my custom table. If used mostly the code of the custom CRC tutorial.

                // filename: ugallerymeta.class.php
                
                require_once MODX_CORE_PATH.'model/modx/modprocessor.class.php';
                require_once MODX_CORE_PATH.'model/modx/processors/resource/create.class.php';
                require_once MODX_CORE_PATH.'model/modx/processors/resource/update.class.php';
                
                class ugalleryMeta extends modResource {
                    
                	public $showInContextMenu = true;
                    
                    function __construct(xPDO & $xpdo) {
                        parent :: __construct($xpdo);
                        $this->set('class_key','ugallerymeta');
                		#echo "<pre>".print_r($this,true)."</pre>";
                		#die();
                    }
                
                    public static function getControllerPath(xPDO &$modx) {
                        return $modx->getOption('ugallerymeta.core_path',null,$modx->getOption('core_path').'components/ugallerymeta/').'controllers/';
                    }
                
                    public function getContextMenuText() {
                        $this->xpdo->lexicon->load('ugallerymeta:default');
                        return array(
                            'text_create' => $this->xpdo->lexicon('ugallerymeta'),
                            'text_create_here' => $this->xpdo->lexicon('ugallerymeta_create_here'),
                        );
                    }
                
                    public function getResourceTypeName() {
                        $this->xpdo->lexicon->load('ugallerymeta:default');
                        return $this->xpdo->lexicon('ugallerymeta');
                    }
                
                    public function getContent(array $options = array()) {
                		$content = parent::getContent($options);
                        $year = date('Y');
                        $content .= '<div class="copyright">© '.$year.'. All Rights Reserved. - KEKS</div>';
                		$content .= $this->get("price");
                        return $content;
                    }
                }
                
                
                class ugalleryMetaCreateProcessor extends modResourceCreateProcessor {
                }
                
                class ugalleryMetaUpdateProcessor extends modResourceUpdateProcessor {
                    /**
                     * Do any processing before the fields are set
                     * @return boolean
                     */
                    public function beforeSet() {
                        $beforeSet = parent::beforeSet();
                        /**
                        if ($this->getProperty('shouldBeTrue') == false) {
                          $this->addFieldError('fieldname','The error message');
                        }
                        */
                        return $beforeSet;
                    }
                
                    /**
                     * Do any processing before the save of the Resource but after fields are set.
                     * @return boolean
                     */
                    public function beforeSave() {
                        $beforeSave = parent::beforeSave();
                        if ($this->object->get('longtitle') == 'Send an Error') {
                            $this->addFieldError('longtitle','Specify a different longtitle!');
                        }
                		$this->object->set('content', "Replaced Content"); // works fine
                		$this->object->set('price', "123"); // no effect
                        return $beforeSave;
                    }
                
                    /**
                     * Do any custom after save processing
                     * @return boolean
                     */
                    public function afterSave() {
                        $afterSave = parent::afterSave();
                        $this->modx->log(modX::LOG_LEVEL_DEBUG,'Saving a Copyrighted Page!');
                        return $afterSave;
                    }	
                }
                


                I think the mistake is between the php class, the xml schema and me...
                hopefully you have the time and you're in the mood to take a look at the code... smiley

                thanks a lot!
                  *there are no strangers - just friends who never met*
                  • 3749
                  • 24,544 Posts
                  I think getObject() expects some criteria that specify a specific object in the array (not an empty array). It may not return a proper object without one.

                  You can leave out the second argument with getCollection() and get all the objects, but you have to treat the return value as an array.



                  ---------------------------------------------------------------------------------------------------------------
                  PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
                  MODx info for everyone: http://bobsguides.com/MODx.html
                    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
                    • 5253
                    • 17 Posts
                    I think it's a little missunderstanding.
                    Actually my problem is to link the table site_content with my custom table. Perhaps it's my mistake, but I thought, that I can insert a placeholder in my custom resources like [[*price]].
                    But even if I try to create or update a ugallerymeta resource my custom table keeps empty (even if I try to set the price field in the beforeSave method of the ugalleryMetaUpdateProcessor class which extends the modResourceUpdateProcessor)...

                      *there are no strangers - just friends who never met*
                      • 3749
                      • 24,544 Posts
                      This may not be related, but I've had trouble lately when I update or create DB records in code and then try to retrieve data immediately after that. I'm still trying to figure out why.


                      ---------------------------------------------------------------------------------------------------------------
                      PLEASE, PLEASE specify the version of MODX you are using . . . PLEASE!
                      MODx info for everyone: http://bobsguides.com/MODx.html
                        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