We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 44195
    • 293 Posts
    Hi, I'm currently trying to wrap my head around migx.

    I've followed through the tutorials and know I can basically display a table in a CMP and perform CRUD actions on it.. but say a CMP had a list of images and I wanted a particular user to vote on their favourite by clicking an accompanying button. Once they had voted, the list would reload but the voting button wouldn't be accessible anymore.
    Is this kind of thing possible using migx?
    e.g. can events be triggered somehow?

    If so, any hints at resources to look at would be greatly appreciated! smiley

    Thanks,
    Muzz

    This question has been answered by Bruno17. See the first response.

      I'm lead developer at Digital Penguin Creative Studio in Hong Kong. https://www.digitalpenguin.hk
      Check out the MODX tutorial series on my blog at https://www.hkwebdeveloper.com
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      This voting button would be on the front-end, correct? Then it would be in the tpl used by the getImageList snippet. The button would use AJAX to insert the count and the user's IP address into your database table - well, the IP address would need a different table, and the AJAX request handler (a snippet in a resource with no template is the easiest way to deal with that) would set a cookie as well as returning the incremented count, which would replace the active button.

      A plugin would determine whether the cookie was set, or the IP address already logged, in which case the vote button would not be inserted at all. Or just go by cookie if you don't want to be logging IP addresses.

      Another way of checking for previous votes could be by using the new HTML 5 storage and Javascript to load the vote button or not. No plugin necessary, it would all be handled in the browser on page load.
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 44195
        • 293 Posts
        Thanks very much for your help. I had wanted to implement something along these lines from the CMP in the backend if it was at all possible.
        Although it's not the end of the world if I did it on the front end as long as an admin had a way of approving photo submissions from the backend. Possibly with checkboxes and a submit button.

        Would this kind of thing be possible with migx from the backend? smiley
          I'm lead developer at Digital Penguin Creative Studio in Hong Kong. https://www.digitalpenguin.hk
          Check out the MODX tutorial series on my blog at https://www.hkwebdeveloper.com
          • 28042 ☆ A M B ☆
          • 24,524 Posts
          I'm sure it is, anything is possible with MIGx. It's just a matter of the configuration to load the javascript, but that's way over my head!

          I was thinking of something like the Easy2Gallery snippet for Evo. It has a really nice AJAX-based "comments" utility built into it, and once upon a time I converted that to a "voting" utility. [ed. note: sottwell last edited this post 12 years, 9 months ago.]
            Studying MODX in the desert - http://sottwell.com
            Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
            Join the Slack Community - http://modx.org
            • 4172
            • 5,888 Posts
            OK, as I understand so far,
            you have a custom-table with images
            you have different users, which can login to the manager
            you want to have a CMP, where you have a grid with all this images in your table
            and a vote-button for the user at each item for the logged-in user.
            As soon as he had clicked this button, a new record is created at another table, lets say its name is 'image_votings'
            This button only is hidden, as soon, as the users has voted for an image.

            Is this correct?

            If not, can you explain a bit more of it?

            This is possible with a CMP created with MIGXdb.
            Will explain it later, how, if the above is correct.

              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 44195
              • 293 Posts
              Exactly right Bruno! smiley
                I'm lead developer at Digital Penguin Creative Studio in Hong Kong. https://www.digitalpenguin.hk
                Check out the MODX tutorial series on my blog at https://www.hkwebdeveloper.com
                • 4172
                • 5,888 Posts
                do have allready a xpdo-schema for your custom-tables created?
                If so, can you show it here, please?
                  -------------------------------

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!
                  • 44195
                  • 293 Posts
                  Hi Bruno,
                  Here's a quick example I've thrown together. It's probably full of errors and far from optimal but hopefully will suit for this purpose!

                  <?xml version="1.0" encoding="UTF-8"?>
                  <model package="artvoting" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM">
                  
                  
                      <object class="artItem" table="artvoting_items" extends="xPDOSimpleObject">
                          <field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
                          <field key="artist" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
                          <field key="filename" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
                          <field key="description" dbtype="text" phptype="string" />
                          <field key="url" dbtype="text" phptype="string" />
                          <field key="createdon" dbtype="datetime" phptype="datetime" null="true" />
                          <field key="createdby" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="false" default="0" index="index" />
                          <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign" />
                      </object>
                     
                     
                      <object class="artAlbum" table="artvoting_albums" extends="xPDOSimpleObject">
                          <field key="name" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
                          <field key="year" dbtype="varchar" precision="255" phptype="string" />
                          <field key="description" dbtype="text" phptype="string" />
                          <field key="createdon" dbtype="datetime" phptype="datetime" null="true" />
                          <field key="createdby" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="false" default="0" index="index" />
                          <field key="active" dbtype="tinyint" precision="1" phptype="integer" attributes="unsigned" null="false" default="0" />
                          <field key="cover_filename" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
                          <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign" />
                      </object>
                  
                  
                      <object class="artVotes" table="artvoting_votes" extends="xPDOSimpleObject">
                          <field key="item" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                          <field key="userid" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                          <field key="value" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                          <field key="ip" dbtype="varchar" precision="40" phptype="string" null="false" default="" index="index" />
                          <field key="date" dbtype="int" precision="11" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                                 
                          <composite alias="Item" class="artItem" local="item" foreign="id" cardinality="one" owner="foreign" />
                      </object>
                      
                      
                  </model>
                  
                    I'm lead developer at Digital Penguin Creative Studio in Hong Kong. https://www.digitalpenguin.hk
                    Check out the MODX tutorial series on my blog at https://www.hkwebdeveloper.com
                  • discuss.answer
                    • 4172
                    • 5,888 Posts
                    your updated schema:

                    <?xml version="1.0" encoding="UTF-8"?>
                    <model package="artvoting" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM">
                     
                     
                        <object class="artItem" table="artvoting_items" extends="xPDOSimpleObject">
                            <field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
                            <field key="artist" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
                            <field key="filename" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
                            <field key="description" dbtype="text" phptype="string" />
                            <field key="url" dbtype="text" phptype="string" />
                            <field key="createdon" dbtype="datetime" phptype="datetime" null="true" />
                            <field key="createdby" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="false" default="0" index="index" />
                            <field key="votes" dbtype="int" precision="10" phptype="integer" null="false" default="0" index="index" /> 
                            
                            <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign" />
                            <composite alias="Votes" class="artVotes" local="id" foreign="item_id" cardinality="many" owner="local" />
                        </object>
                        
                        
                        <object class="artAlbum" table="artvoting_albums" extends="xPDOSimpleObject">
                            <field key="name" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
                            <field key="year" dbtype="varchar" precision="255" phptype="string" />
                            <field key="description" dbtype="text" phptype="string" />
                            <field key="createdon" dbtype="datetime" phptype="datetime" null="true" />
                            <field key="createdby" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="false" default="0" index="index" />
                            <field key="active" dbtype="tinyint" precision="1" phptype="integer" attributes="unsigned" null="false" default="0" />
                            <field key="cover_filename" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
                            <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign" />
                        </object>
                     
                     
                        <object class="artVotes" table="artvoting_votes" extends="xPDOSimpleObject">
                            <field key="item_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                            <field key="user_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                            <field key="value" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
                            <field key="ip" dbtype="varchar" precision="40" phptype="string" null="false" default="" index="index" />
                            <field key="date" dbtype="datetime" phptype="datetime" null="true" index="index" />
                                    
                            <aggregate alias="Item" class="artItem" local="item_id" foreign="id" cardinality="one" owner="foreign" />
                            <aggregate alias="User" class="modUser" local="user_id" foreign="id" cardinality="one" owner="foreign" />        
                        </object>
                         
                         
                    </model>
                    


                    Name your MIGX - configuration for example: 'artitems'

                    create a new grid.config.inc.php file under core/components/artvoting/migxconfigs/grid/grid.config.inc.php

                    with:

                    <?php
                    
                    $gridcontextmenus['voteImage']['code'] = "
                            if (n.Vote_id == null) {
                                m.push('-');
                                    m.push({
                                        className : 'vote'
                                        ,text: 'vote'
                                        ,handler: 'this.voteImage'
                                    });    
                            }      
                    ";
                    $gridcontextmenus['voteImage']['handler'] = 'this.voteImage';
                    
                    $gridfunctions['this.voteImage'] = "
                    voteImage: function() {
                            MODx.Ajax.request({
                                url: this.config.url
                                ,params: {
                                    action: 'mgr/migxdb/process'
                                    ,processaction: 'voteimage'
                                    ,object_id: this.menu.record.id
                    				,configs: '[[+config.configs]]'
                                }
                                ,listeners: {
                                    'success': {fn:this.refresh,scope:this}
                                }
                                
                            });
                        }
                    ";
                    


                    create a new artitems.config.inc.php - file under core/components/artvoting/migxconfigs/artitems.config.inc.php

                    with

                    <?php
                    
                    $user_id = $this->modx->getLoginUserId('mgr');
                    
                    $this->customconfigs['joins'] = '[{"alias":"Vote","classname":"artVotes","on":"user_id='.$user_id.' and item_id=artItem.id"}]';
                    


                    create a new processor in core/components/artvoting/processors/mgr/default/voteimage.php

                    with:
                    <?php
                    
                    if (empty($scriptProperties['object_id'])) {
                    
                        return $modx->error->failure('missing object_id');
                    
                    }
                    
                    $config = $modx->migx->customconfigs;
                    
                    $prefix = $config['prefix'];
                    $packageName = $config['packageName'];
                    
                    $packagepath = $modx->getOption('core_path') . 'components/' . $packageName . '/';
                    $modelpath = $packagepath . 'model/';
                    
                    $modx->addPackage($packageName, $modelpath, $prefix);
                    $classname = 'artVotes';
                    
                    if ($modx->lexicon) {
                        $modx->lexicon->load($packageName . ':default');
                    }
                    
                    $user_id = $modx->getLoginUserId('mgr');
                    
                    if ($object = $modx->getObject($classname, array('user_id' => $user_id, 'item_id' => $scriptProperties['object_id']))) {
                        //vote exists allready, do nothing
                    } else {
                        $object = $modx->newObject($classname);
                        $object->set('user_id', $user_id);
                        $object->set('item_id', $scriptProperties['object_id']);
                        $object->set('date', strftime('%Y-%m-%d %H:%M:%S'));
                        
                        
                        if ($object->save()) {
                            if ($itemObject = $object->getOne('Item')){
                                $itemObject->set('votes',$itemObject->get('votes')+1);
                                $itemObject->save();    
                            }
                        }
                    }
                    
                    
                    
                    //clear cache for all contexts
                    $collection = $modx->getCollection('modContext');
                    foreach ($collection as $context) {
                        $contexts[] = $context->get('key');
                    }
                    $modx->cacheManager->refresh(array(
                        'db' => array(),
                        'auto_publish' => array('contexts' => $contexts),
                        'context_settings' => array('contexts' => $contexts),
                        'resource' => array('contexts' => $contexts),
                        ));
                    
                    return $modx->error->success();
                    
                    ?>
                    



                    have in your MIGX - configuration this columns (edit raw):

                    [{"MIGX_id":"1","header":"ID","dataIndex":"id","width":"","sortable":"false","show_in_grid":"1","renderer":"","clickaction":"","selectorconfig":"","renderchunktpl":"","renderoptions":"[]"},{"MIGX_id":"2","header":"Name","dataIndex":"name","width":"","sortable":"false","show_in_grid":"1","renderer":"this.renderRowActions","clickaction":"","selectorconfig":"","renderchunktpl":"","renderoptions":"[]"},{"MIGX_id":"3","header":"Artist","dataIndex":"artist","width":"","sortable":"false","show_in_grid":"1","renderer":"","clickaction":"","selectorconfig":"","renderchunktpl":"","renderoptions":"[]"},{"MIGX_id":"4","header":"","dataIndex":"Vote_id","width":"","sortable":"false","show_in_grid":"0","renderer":"","clickaction":"","selectorconfig":"","renderchunktpl":"","renderoptions":"[]"}]
                    


                    select the new ActionButton - checkbox: 'voteImage'

                    my Test was working, good luck!
                      -------------------------------

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 44195
                      • 293 Posts
                      Thanks very much for this Bruno. I really appreciate it!
                      When you say to name my MIGX configuration, does that mean the unique MIGX id?
                        I'm lead developer at Digital Penguin Creative Studio in Hong Kong. https://www.digitalpenguin.hk
                        Check out the MODX tutorial series on my blog at https://www.hkwebdeveloper.com