We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 42082
    • 72 Posts
    Hi guys me here again,
    I am starting off into the creation of extras for modx and I am having trouble. In fact I have had more trouble then progress, it is really quite discouraging. Anyhow I was wondering If you guys could take a look at my code and see what I have wrong. I am using the tutorial posted here:http://rtfm.modx.com/revolution/2.x/case-studies-and-tutorials/developing-an-extra-in-modx-revolution on a localhost using wamp. I use the easyPHP system for easier use. I have already tried using just plain wamp and xamp but it makes no difference.
    So here is what I have done:

    • Created a dir in my root (wich appears to be called localweb)called modx
    • unzipped and setup modx like usual
    • did some windows cmd workarounds to name the ht.access file .htaccess (using windows 7 btw
    • setup freindly urls and started to develope the extra
    • Created the needed system settings for my pluggin
    • and made a static snippet that links in my php file called slideDat (the name of my extra)
    • connected the snippet to a rescource
    • and tried to use the snippet to create the table needed

    And thats where I am cannot get the tables to generate. Here is My code:
    SlideDat:
    <?php
     * @package slideDat
     */
    $slideD = $modx->getService('slideDat','SlideDat',$modx->getOption('slideDat.core_path',null,$modx->getOption('core_path').'components/slideDat/').'model/slideDat/',$scriptProperties);
    if (!($slideD instanceof SlideDat)) return '';
    /* setup default properties */
    $tpl = $modx->getOption('tpl',$scriptProperties,'rowTpl');
    $sort = $modx->getOption('sort',$scriptProperties,'name');
    $dir = $modx->getOption('dir',$scriptProperties,'ASC');
     
    $output = '';
    $m = $modx->getManager();
    $created= $m->createdObjectContainer('SlideDat');
    return $created? 'Table created.': 'Table not created.';
    return $output;
    

    slideDat.mysql.schema.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <model version="1.1" package="slideDat" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM">
        <object class="sdSlides" table="slideDat_slides" extends="xPDOSimpleObject">
            <field key="name" dbtype="varchar" precision="55" phptype="string" null="false" default=""/>
            <field key="desc" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
            <field key="show_name" dbtype="tinyint" precision="1" phptype="boolean" attributes="unsigned" null="false" default="1"/>
            <field key="show_desc" dbtype="tinyint" precision="1" phptype="boolean" attributes="unsigned" null="false" default="1"/>
            <field key="date" dbtype="datetime" phptype="datetime" null="false" default=""/>
            <field key="image" dbtype="varchar" precision="100" phptype="string" null="false" default=""/>
            <field key="class" dbtype="varchar" precision="30" phptype="string" null="false" default=""/>
            <field key="link_to" dbtype="varchar" precision="100" phptype="string" null="" default=""/>
            <composite alias="slideGroup" class="sdSlideGroupList" local="id" foreign="slide_id" cardinality="many" owner="foreign"/>
        </object>
        <object class="sdGroups" table="slideDat_groups" extends="xPDOSimpleObject">
        	<field key="name" dbtype="varchar" precision="55" phptype="string" null="false" default=""/>
            <field key="desc" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
            <field key="permission" dbtype="varchar" precision="70" phptype="string" null="false" default="Administrator"/>
            <field key="date" dbtype="datetime" phptype="datetime" null="false" default=""/>
            <composite alias="slideGroup" class="sdSlideGroupList" local="id" foreign="group_id" cardinality="many" owner="foreign"/>
        </object>	
        <object class="sdSlideGroupList" table="slideDat_slideGroupsList" extends="xPDOSimpleObject">
        	<field key="group_id" dbtype="varchar" precision="55" phptype="string" null="false" default=""/>
            <field key="slide_id" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
            <aggregate alias="group_id" class="sdGroup" local="group_id" foreign="id" cardinality="one" owner="foreign"/>
            <aggregate alias="slide_id" class="sdSlide" local="slide_id" foreign="id" cardinality="one" owner="foreign"/>
        </object>
    </model>
    
    
    


    Thank you all in advance.
    ModxNooby
      • 4172
      • 5,888 Posts
      creating a package-directory, the tables and classes can be very easy done with help of MIGX with a view mouse-clicks, as soon as you have MIGX installed correctly.

      btw.:
      its good practice to name your package all lowercase:

      package="slidedat"
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 3749
        • 24,544 Posts
        First, have you created the class and map files for your three objects using parseSchema()?

        Second, createObjectContainer() creates a single table for a single object, so you would need to call it three times, once for each object/table, rather than once for the package.

        Here's some code from an extra I'm working on that might be useful:

        public function generateClassFiles() {
                /** $generator xPDOGenerator */
                $path = $this->modelPath . 'schema/';
                $this->generator->parseSchema($path . $this->package . '.mysql.schema.xml', $this->modelPath);
        }
        
        public function createTable() {
            $success = $this->modx->addPackage($this->package, $this->modelPath, $this->prefix);
            if (! $success) {
                $this->modx->log(modX::LOG_LEVEL_ERROR,'addPackage failed';
                return;
            }
            $manager = $this->modx->getManager();
            if (! $manager) {
                $this->modx->log(modX::LOG_LEVEL_ERROR,'getManager failed';
                return;
            }
            $manager->createObjectContainer($this->tableName);
        }


        FYI, for a resolver, you would have to add this line in the class constructor so $this->modx would be available:

        $this->modx =& $xPDO;


        Also, you're probably going to want to have some indexes in your schema.

        You might also look at this method, which allows you to generate the schema from existing DB tables, it will do the indexes for you if they exist in the tables:

        http://bobsguides.com/custom-db-tables.html

        Once you've generated the schema, you'll have to add your composite and aggregate aliases before generating the class and map files with parseSchema();
          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
          • 42082
          • 72 Posts

          First off I want to thank you all for the help and tips it is really great. Second i want to answer bobs question:
          First, have you created the class and map files for your three objects using parseSchema()?

          Yes, I have generated six files in all three in the mysql and the other in the main model/slideDat/ file. Another thing..I am pretty new with the whole extra creation so I am not quite familiar with resolvers and so on. Is the code you posted up above in the /slideDat/core/components/slideDat/elements/snippets/snippet.slideDat.php file ( of course it the extra name would be whatever extra you are working on). In other words I have no doubt that this information can really help me out, but I am not quite sure how to use it. I am really sorry yall. I am really quite new to this..If you guys get some time I could really use a short tutorial..

          Thank you all so very much,
          Modx nooby


            • 28042 ☆ A M B ☆
            • 24,524 Posts
            I would recommend working through the Doodles tutorial at least once before trying for any modifications.
              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
              • 42082
              • 72 Posts
              That is what I was doing before I came across these issues

              Thanks,
              ModxNooby
                • 3749
                • 24,544 Posts
                Is the code you posted up above in the /slideDat/core/components/slideDat/elements/snippets/snippet.slideDat.php file?

                No (unless that's a utility snippet you made just for creating the class and map files and the table). The code would go in a resolver that's part of the transport package for your extra or in a utility snippet that you only run once.

                You only need to create the class and map files and the table once, but as I said above, you do need to call createObjectContainer() once for each object/table.
                  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
                  • 42082
                  • 72 Posts
                  Okay hi guys I'm back, Tha
                  nks for all the help you have provided, it is so so helpful. Thanks. So I went back to the documents on the modx rtfm (http://rtfm.modx.com/revolution/2.x/case-studies-and-tutorials/developing-an-extra-in-modx-revolution) and found that thy had been updated. Not sure if that was one of you guys or someone else but who ever it was changed things up a bit. So I put in all the needed code and I think I am starting to get some where. I got some very neat messages when I regenerated the class files and maps with the new code. That went very well.. although i did get a error code

                  "Could not load class: SlideDat from mysql.slidedat."

                  I have gone through my code and seen lots of places where I made uppercase SlideDat and lowercase slideDat for the code like:
                  $slideD = $modx->getService('slideDat','SlideDat',$modx->getOption('slideDat.core_path',null,$modx->getOption('core_path').'components/slideDat/').'model/slideDat/',$scriptProperties);
                  

                  I thought that since the doodles snippet had upercase and lowercase names I would place mine the same way...So my thoughts are that I may have mixed the uppercase and lower case name slideDat around... Here is my code, if any of you can help that would be great!




                  build.config.php:
                  <?php
                  /**
                   * Define the MODX path constants necessary for installation
                   *
                   * @package slideDat
                   * @subpackage build
                   */
                  define('MODX_BASE_PATH', 'C:/Program Files (x86)/EasyPHP-DevServer-14.1VC11/data/localweb/modx/');
                  define('MODX_CORE_PATH', MODX_BASE_PATH . 'core/');
                  define('MODX_MANAGER_PATH', MODX_BASE_PATH . 'manager/');
                  define('MODX_CONNECTORS_PATH', MODX_BASE_PATH . 'connectors/');
                  define('MODX_ASSETS_PATH', MODX_BASE_PATH . 'assets/');
                  
                  define('MODX_BASE_URL','/modx/');
                  define('MODX_CORE_URL', MODX_BASE_URL . 'core/');
                  define('MODX_MANAGER_URL', MODX_BASE_URL . 'manager/');
                  define('MODX_CONNECTORS_URL', MODX_BASE_URL . 'connectors/');
                  define('MODX_ASSETS_URL', MODX_BASE_URL . 'assets/');
                  



                  snippet.slideDat.php:
                  <?php
                   * @package slideDat
                   */
                  $slideD = $modx->getService('slideDat','SlideDat',$modx->getOption('slideDat.core_path',null,$modx->getOption('core_path').'components/slideDat/').'model/slideDat/',$scriptProperties);
                  if (!($slideD instanceof SlideDat)) return '';
                  /* setup default properties */
                  $tpl = $modx->getOption('tpl',$scriptProperties,'rowTpl');
                  $sort = $modx->getOption('sort',$scriptProperties,'name');
                  $dir = $modx->getOption('dir',$scriptProperties,'ASC');
                   
                  $output = '';
                  $slidedat = $modx->getCollection('SlideDat');
                  $output = count($slidedat);
                  return $output;
                  



                  build.schema.php:
                  <?php
                  require_once 'C:/Program Files (x86)/EasyPHP-DevServer-14.1VC11/data/localweb/slideDat/_build/build.config.php';
                  include_once MODX_CORE_PATH . 'model/modx/modx.class.php';
                  $modx= new modX();
                  $modx->initialize('mgr');
                  $modx->loadClass('transport.modPackageBuilder','',false, true);
                  $modx->setLogLevel(modX::LOG_LEVEL_INFO);
                  $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
                  $sources = array(
                      'model' => $modx->getOption('slideDat.core_path').'model/',
                      'schema_file' => $modx->getOption('slideDat.core_path').'model/schema/slideDat.mysql.schema.xml'
                  );
                  $manager= $modx->getManager();
                  $generator= $manager->getGenerator();
                   
                  if (!is_dir($sources['model'])) { $modx->log(modX::LOG_LEVEL_ERROR,'Model directory not found!'); die(); }
                  if (!file_exists($sources['schema_file'])) { $modx->log(modX::LOG_LEVEL_ERROR,'Schema file not found!'); die(); }
                  $generator->parseSchema($sources['schema_file'],$sources['model']);
                  $modx->addPackage('slideDat', $sources['model']); // add package to make all models available
                  $manager->createObjectContainer('SlideDat'); // created the database table
                  $modx->log(modX::LOG_LEVEL_INFO, 'Done!');




                  slideDat.class.php:
                  <?php
                  /**
                   * @package -extra names
                   */
                  class SlideDat {
                      /**
                       * Constructs the -extra names object
                       *
                       * @param modX &$modx A reference to the modX object
                       * @param array $config An array of configuration options
                       */
                      function __construct(modX &$modx,array $config = array()) {
                          $this->modx =& $modx;
                  
                          $basePath = $this->modx->getOption('slideDat.core_path',$config,$this->modx->getOption('core_path').'components/slideDat/');
                          $assetsUrl = $this->modx->getOption('slideDat.assets_url',$config,$this->modx->getOption('assets_url').'components/slideDat/');
                          $this->config = array_merge(array(
                              'basePath' => $basePath,
                              'corePath' => $basePath,
                              'modelPath' => $basePath.'model/',
                              'processorsPath' => $basePath.'processors/',
                              'templatesPath' => $basePath.'templates/',
                              'chunksPath' => $basePath.'elements/chunks/',
                              'jsUrl' => $assetsUrl.'js/',
                              'cssUrl' => $assetsUrl.'css/',
                              'assetsUrl' => $assetsUrl,
                              'connectorUrl' => $assetsUrl.'connector.php',
                          ),$config);
                  
                          
                      }
                  	
                  	$this->$modx->addPackage('slideDat',$this->config['modelPath']);
                  	
                      }    
                     


                  Thank you all so very much and my apologies If I am taking from your time to often. I do not wish to appear lazy or someone who just wants everyone else to do the work. I am really trying but I just need some helpful guidance. I really wish to contribute to the community and do my part.

                  Thank you all,
                  ModxNooby
                    • 3749
                    • 24,544 Posts
                    First, look at all the getOption() calls. They refer to System Settings and need to match the System Settings in case.

                    Also, in your snippet, your getCollection() call is for 'SlideDat' but you have no object in your schema by that name.
                      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
                      • 42082
                      • 72 Posts
                      Thanks Bob for the replies and yes I did relies the getOptions() call refers to system settings. I made sure I was there. Also I think there is not entry in the schema because im not at that step yet..but im not sure if i just missed that part or what. But any way. I am at this part in the tutorial:

                      " Know Your Objects!
                      In this example, we are retrieving a collection of "Doodle" objects. Most of the time when using xPDO.getCollection, you will be retrieving the built-in MODX objects (e.g. pages are "modResource", templates are "modTemplate"), so you may find it quite handy to keep open your core/model/schema/modx.mysql.schema.xml file so you can review your object names.

                      That's going to grab an array of Doodle objects, or in non-xPDO terms, a bunch of rows from the database. Go ahead and save your snippet, then run it in the browser at http://localhost/modx/doodles.html (or wherever the Resource was). You should get this:

                      0

                      Ha, tricked you! In reality, the first time it runs it wont grab anything, since we don't have any data in the table. Let's go put some data in the table.

                      Use whatever DB editing software (such as phpMyAdmin) you want, and find the 'modx_doodles' table in your database. Add a few rows to it (just add name/description values for now). That should give you some data. Let's assume you added 2 rows. Go ahead and run your snippet, and you should get:

                      2 "

                      But when i run the snippet i get this:
                      Fatal error: Call to a member function addPackage() on a non-object in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\slideDat\core\components\slideDat\model\slideDat\slideDat.class.php on line 29"

                      So i took a look and found this in that line:
                      $this->$modx->addPackage('slideDat',$this->config['modelPath']);

                      No idea what I'm doing wrong here...
                      Please help.
                      Thanks