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

    I am having trouble trying to create my own CMP. I have been using Quip as a reference and this tutorial helped me out when I got stuck:
    http://rtfm.modx.com/display/revolution20/Developing+an+Extra+in+MODX+Revolution+-+MODX+2.1+and+Earlier
    (I am working with modx 2.2.8 though)

    I have gotten to the point that I have my connector and my first processor (getlist). This won't work though.

    The following errors come up in the error log when trying to access the CMP
    [2013-07-25 03:03:25] (ERROR @ /assets/components/inschrijvingen/connector.php) Could not get table class for class: inschrijvingen
    [2013-07-25 03:03:25] (ERROR @ /assets/components/inschrijvingen/connector.php) Could not get table name for class: inschrijvingen
    [2013-07-25 03:03:25] (ERROR @ /assets/components/inschrijvingen/connector.php) Could not get table class for class: inschrijvingen
    [2013-07-25 03:03:25] (ERROR @ /assets/components/inschrijvingen/connector.php) Could not get table name for class: inschrijvingen
    [2013-07-25 03:03:25] (ERROR @ /assets/components/inschrijvingen/connector.php) inschrijvingen::getSelectColumns() is not a valid static method.


    Quip uses classes for it's processors whereas in the tutorials this code is being used: (also my current getlist.php)
    <?php
    $isLimit = !empty($scriptProperties['limit']);
    $start = $modx->getOption('start',$scriptProperties,0);
    $limit = $modx->getOption('limit',$scriptProperties,10);
    $sort = $modx->getOption('sort',$scriptProperties,'name');
    $dir = $modx->getOption('dir',$scriptProperties,'ASC');
     
    /* build query */
    $c = $modx->newQuery('inschrijvingen');
    $count = $modx->getCount('inschrijvingen',$c);
    $c->sortby($sort,$dir);
    if ($isLimit) $c->limit($limit,$start);
    $inschrijvingen = $modx->getIterator('inschrijvingen', $c);
    
    /* iterate */
    $list = array();
    foreach ($inschrijvingen as $inschrijving) {
        $inschrijvingArray = $inschrijving->toArray();
        $list[]= $inschrijvingArray;
    }
    return $this->outputArray($list,$count);



    My model/inschrijvingen/inschrijvingen.class.php is as follows:
    <?php
    	class Inschrijvingen {
    		public $modx;
    		public $config = array();
    		
    		function __construct(modX &$modx, array $config = array()) {
    			$this->modx = & $modx;
    			
    			$basePath = $this->modx->getOption('inschrijvingen.core_path',$config,$this->modx->getOption('core_path').'components/inschrijvingen/');
    			$assetsUrl = $this->modx->getOption('inschrijvingen.assets_url',$config,$this->modx->getOption('assets_url').'components/inschrijvingen/');
    			$this->config = array_merge(array(
    				'basePath' => $basePath,
    				'corePath' => $basePath,
    				'modelPath' => $basePath.'model/',
    				'processorsPath' => $basePath.'processors/',
    				'chunksPath' => $basePath.'elements/chunks/',
    				'jsUrl' => $assetsUrl.'js/',
    				'cssUrl' => $assetsUrl.'css/',
    				'assetsUrl' => $assetsUrl,
    				'connectorUrl' => $assetsUrl.'connector.php',
    			),$config);
    			$this->modx->addPackage('inschrijvingen',$this->config['modelPath'], 'evd_');
    		}
    		
    		public function initialize($ctx = 'web') {
    			switch ($ctx) {
    				case 'mgr':
    					$this->modx->lexicon->load('inschrijvingen:default');
    					if(!$this->modx->loadClass('inschrijvingenControllerRequest',$this->config['modelPath'].'inschrijvingen/request/',true,true)) {
    						return 'Could not load controller request handler.';
    					}
    					$this->request = new inschrijvingenControllerRequest($this);
    					return $this->request->handleRequest();
    				break;
    			}
    			return true;
    		}
    	}
    ?>



    I am really lost right now, so I hope I gave some clear information.

    Thanks in advance,
    Erwin

    This question has been answered by might-e. See the first response.

    [ed. note: might-e last edited this post 13 years, 2 months ago.]
      • 3749
      • 24,544 Posts
      In your initialize method, you have the default context to initialize as 'web' but your loadClass() code only executes if you're in the 'mgr' context. Are you calling initialze('mgr') somewhere? If not, your loadClass() call will never execute. That could be the problem.

      Does your custom DB class work with xPDO in a snippet (so we know your class and map files are good)? It's often a good idea to develop some of the CMP code in a snippet first because it's easier to debug.

      It may be too late for this to be of use, but if you only have one custom DB table, this method will create the schema and the class and map files for you: http://bobsguides.com/custom-db-tables.html


      Also probably too late, but the new version of MyComponent will create skeleton CMP files for you and the Example project that comes with it creates a simple, working CMP that might serve as another example for you.
        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
        • 40944
        • 78 Posts
        Quote from: BobRay at Jul 24, 2013, 11:28 PM
        In your initialize method, you have the default context to initialize as 'web' but your loadClass() code only executes if you're in the 'mgr' context. Are you calling initialze('mgr') somewhere? If not, your loadClass() call will never execute. That could be the problem.
        It seems I did not do that. I only called the initialize method in my 'controllers/index.php' file. But I guess that file doesn't get included when calling the connector. In my connector file I now added the following line:
        $modx->inschrijvingen->initialize('mgr');

        But this doesn't seem to do anything.

        Does your custom DB class work with xPDO in a snippet (so we know your class and map files are good)? It's often a good idea to develop some of the CMP code in a snippet first because it's easier to debug.

        It may be too late for this to be of use, but if you only have one custom DB table, this method will create the schema and the class and map files for you: http://bobsguides.com/custom-db-tables.html
        My custom DB did work, but the tutorial said I had to change my 'model/inschrijvingen/inschrijvingen.class.php' file. I did use your tutorial to create a custom db etc, but I wanted to add an CMP to manage the subscriptions (to contests). I had to change this line created by your custom-db-xpdo-tool
        class Inschrijvingen extends xPDOSimpleObject {}

        to the third code block in my first post.

        When I change it back it works for the front end (which was broken when I changed the class).

        So I think I am missing a step or changed the wrong file?

        Also probably too late, but the new version of MyComponent will create skeleton CMP files for you and the Example project that comes with it creates a simple, working CMP that might serve as another example for you.
        I have got a CMP with ExtJS interface. At the moment the connector (actually the processors I guess) don't work as well as lexicon. Lexicon isn't to big of a problem though. For now it will be just a CMP to manage contestants for contests by a small horseclub (mainly setting a start time for registered contestants).

        Again, thanks in advance.
          • 3749
          • 24,544 Posts
          To use xPDO with the classes (which you're doing), you definitely need to have them extend an xPDO Object (almost always xPDOSimpleObject).

          Also, you need to regenerate the class and map files whenever you change the schema. Make sure the schema has the correct table name (minus the prefix).

          You typically want to instantiate the class and do the initialize('mgr') call in the core/components/yourcomponent/controllers/index.php file.

          In the controller file, you usually want to instantiate the class and initialize('mgr').

          In the connector.php file, you want to instantiate the class, call initialize('mgr'), and do lexicon->load().

          $modx->lexicon->load('yourcomponentnamespace:default');
            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
            • 40944
            • 78 Posts
            I really don't get it.

            In the tutorial they create a class (called after your extra) in core/components/yourcomponent/model/yourcomponent.class/php.
            As I used your (Bobs [Thanks!]) tutorial to create my schema etc, that file already exists. And it has the yourcomponent class which extends xPDOSimpleObject.

            When I keep it like that, it works with my front-end extra which I made using the same tutorial. The code for the snippet is:
            <?php
            $pageid = $modx->getPlaceholder('fi.pageid');
            $path = MODX_CORE_PATH . 'components/inschrijvingen/';
            
            $result = $modx->addPackage('inschrijvingen',$path . 'model/','evd_');
            if (!$result) {
              return 'Er is iets mis gegaan bij het laden van de inschrijvingen.';
            } else {
                
                if(!$pageid) {
                    $inschrijvingen = $modx->getCollection('Inschrijvingen',array('pageid'=>$modx->resource->id));
                } else {
                    $inschrijvingen = $modx->getCollection('Inschrijvingen',array('pageid'=>$pageid));
                }
                
                $cat = array('A', 'B', 'C', 'D', 'E', 'Paard');
                
                foreach($inschrijvingen as $inschrijving) {
                    $output .= '<tr>';
                    $output .= $modx->getChunk('InschrijvingenRowTpl',array(
                        'voornaam' => $inschrijving->get('voornaam'),
                        'tussenvoegsel' => $inschrijving->get('tussenvoegsel'),
                        'achternaam' => $inschrijving->get('achternaam'),
                        'paard' => $inschrijving->get('paard'),
                        'vader' => $inschrijving->get('vader'),
                        'categorie' => $cat[$inschrijving->get('categorie')],
                        'klasse' => $inschrijving->get('klasse'),
                        'starttijd' => $inschrijving->get('starttijd')
                    ));
                    $output .= '</tr>';
                }
            }
            return $output;


            I know it's not flexible and all, but that doesn't really matter. What it does is get the ID (pageid) of the contest.

            So the tutorial says I have to create a class named after my component (which happens to be the name of my database). In the tutorial it says nothing about extending xPDOSimpleObject though. When I do that it doesn't work at all either (blank page). Should I name that class differently? And should I put it somewhere else?

            Would it help to just remove everything I have done so far, use an extra like you said earlier and fill in the files with what I've got right now?

            If it helps I could also upload a zip of my current core/components/mycmp/ ? I can image that's a lot of work though and I really don't want to come of as a lazy person and let someone else do all the work.

            PS:
            I believe I initialize the class at the correct places.
              • 4172
              • 5,888 Posts
              what's your current xpdo-schema?
                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!
                • 40944
                • 78 Posts
                My 'model/schema/inschrijvingen.mysql.schema.xml' currently looks like this:
                <?xml version="1.0" encoding="UTF-8"?>
                <model package="inschrijvingen" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
                	<object class="Inschrijvingen" table="inschrijvingen" extends="xPDOSimpleObject">
                		<field key="pageid" dbtype="int" precision="11" phptype="integer" null="false" default="" />
                		<field key="voornaam" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                		<field key="tussenvoegsel" dbtype="varchar" precision="10" phptype="string" null="true" />
                		<field key="achternaam" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                		<field key="email" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                		<field key="telefoon" dbtype="varchar" precision="20" phptype="string" null="true" />
                		<field key="paard" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                		<field key="vader" dbtype="varchar" precision="250" phptype="string" null="true" />
                		<field key="combi" dbtype="int" precision="11" phptype="integer" null="true" />
                		<field key="categorie" dbtype="int" precision="11" phptype="integer" null="false" default="" />
                		<field key="klasse" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                		<field key="bijzonderheden" dbtype="text" phptype="string" null="true" />
                		<field key="starttijd" dbtype="datetime" phptype="datetime" null="true" />
                
                		<index alias="id" name="id" primary="false" unique="false" type="BTREE" >
                			<column key="id" length="" collation="A" null="false" />
                		</index>
                	</object>
                </model>
                  • 3749
                  • 24,544 Posts
                  I'm guessing, but I suspect that if you rename your pageId field to id and make it an autoincrement field (and the primary key), the script will extend xPDOSimpleObject when it creates the schema and your trouble may go away.

                    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
                    • 40944
                    • 78 Posts
                    Quote from: BobRay at Jul 30, 2013, 03:19 AM
                    I'm guessing, but I suspect that if you rename your pageId field to id and make it an autoincrement field (and the primary key), the script will extend xPDOSimpleObject when it creates the schema and your trouble may go away.

                    I do already have an 'id' column, but I made it an index because when I used your createclasses snippet it said
                    [2013-07-30 13:19:27] (WARN @ /index.php)

                    No indexes were found in table evd_inschrijvingen
                    so I figured a index would serve.

                    Right now I made it a primary key and edited the schema manually:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <model package="inschrijvingen" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
                    	<object class="Inschrijvingen" table="inschrijvingen" extends="xPDOSimpleObject">
                    		<field key="pageid" dbtype="int" precision="11" phptype="integer" null="false" default="" />
                    		<field key="voornaam" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                    		<field key="tussenvoegsel" dbtype="varchar" precision="10" phptype="string" null="true" />
                    		<field key="achternaam" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                    		<field key="email" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                    		<field key="telefoon" dbtype="varchar" precision="20" phptype="string" null="true" />
                    		<field key="paard" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                    		<field key="vader" dbtype="varchar" precision="250" phptype="string" null="true" />
                    		<field key="combi" dbtype="int" precision="11" phptype="integer" null="true" />
                    		<field key="categorie" dbtype="int" precision="11" phptype="integer" null="false" default="" />
                    		<field key="klasse" dbtype="varchar" precision="250" phptype="string" null="false" default="" />
                    		<field key="vereniging" dbtype="varchar" precision="250" phptype="string" null="true" />
                    		<field key="bijzonderheden" dbtype="text" phptype="string" null="true" />
                    		<field key="starttijd" dbtype="datetime" phptype="datetime" null="true" />
                    
                    		<index alias="PRIMARY" name="id" primary="true" unique="true" type="BTREE">
                                		<column key="id" length="" collation="A" null="false" />
                            	</index>
                    	</object>
                    </model>


                    Apart from the primary key change I added another column which isn't related to the problem.

                    I still think it has something to do with the Inschrijvingen class (my_cmp) though because the tutorial says I have to create one, and the class has the same name and file location as the one created by the createclasses snippet. Unlike the generated one, they say nothing about extending xPDOSimpleObject. Obviously I didn't put the two in one file together, but replaced them when testing.
                      • 3749
                      • 24,544 Posts
                      When you create an index and say <column key="id", there also needs to be a line with <field key='id' to create the field. Since you're not extending xPDOSimpleObject, there isn't a field with that key.

                      Here's an example:

                      <object class="modAccessibleObject" extends="xPDOObject" />
                      
                      <object class="modAccessibleSimpleObject" extends="modAccessibleObject">
                          <field key="id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" index="pk" generated="native" />
                      
                          <index alias="PRIMARY" name="PRIMARY" primary="true" unique="true" type="BTREE">
                              <column key="id" length="" collation="A" null="false" />
                          </index>
                      </object>
                      [/code/

                      IOW, any object that descends from xPDOObject must have a *field* whose key is 'id'.

                      When you extend xPDOSimpleObject, there is automatically a field whose key is 'id' so you don't use the "field" line and can still name 'id' as an index.

                      As I said, I would try renaming your pageID field to 'id' in PhpMyAdmin, making it autoincrement, and specifying it as an index and primary key, then run the script again (after deleting the schema) and see what the schema looks like.
                        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