We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I’m writing a module along with several Snippets that I consider (perhaps erroneously) "children". That is, the Snippets inherit shared parameters.

    I’m wondering if my Snippets can make calls to functions in the "parent" module? Is this possible? I can achieve this type of thing using a shared parameter and put "shared code" in an include file, but I thought it would be more secure if I could control access via MODx’s groups/roles instead of just hoping that nobody looks at whatever file I include.

    Anybody have thoughts on this? OpenGeek, I have a hunch you’ll weigh in on this with your wisdom wink
      • 22303 MODX Staff
      • 10,725 Posts
      IMO, this is what a Model in MVC is for. You develop your model classes with all the functions you need to interact with your model, then create a module and snippets that can share parameters and the model classes as needed. The module and snippets represent view controllers (in the back-end and front-end respectively) into your model.
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        I can see where you’re coming from. So, in the realities of the implementation, the model would have to be a file included by both the Snippet and Module, right? Or is there some other way to share code / calls between them? I guess in the spirit of models, the code to be shared might also live in the database... not sure how to load that up from within a Snippet or a Module without evoking an eval command.
          • 3749
          • 24,544 Posts
          You need to think of it from an object-oriented (OO) perspective. You create a class that embodies the object you are dealing with (DB table, user, form, menu, or whatever). The class includes member variables for data and control options as well as the methods (functions) needed by the object. The class information, including those functions and variables is all in once file (the class file). Your module can "include" the class file and instantiate an object of that class. Then it will have access to those member functions. A snippet can do exactly the same thing.

          As an example, the captcha file veriword.class.php (in Revo) is the class file for a captcha image object.

          Any module, plugin, or snippet that needs to put up a captcha image can do it with just the following code:

          require_once 'path_to_veriword_file' . 'veriword.class.php';
          
          $vword = new VeriWord($modx);
          
          $vword->output_image();
          $vword->destroy_image();


          IOW, everyone can "share" the functions in the veriword class file by including the file, creating the object (with new) and calling the functions with $obj->function.

          My apologies if you know all this already.

          If not, you could post exactly what you’re trying to do and we could try to suggest an OO way to do it. The more MODx code is designed as OO, the more robust and easier to maintain and upgrade MODx will be. smiley
            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
            • 9207 ☆ A M B ☆
            • 2,475 Posts
            What I’m trying to do is to build a CRUD tool for MODx so MODx can access and update custom database tables or remote databases.

            So in my parent CRUD class, I’d have default and global functions, then each table would have a class that was a child of the parent CRUD class.

            Each table will have an object associated with it... and it will probably need a configuration file for it. What are your thoughts about where the configuration file should live... is it a model? Regular expressions would probably live in the model (e.g. stripping out quotes from strings before inserting them into the database). The templates would be Views (either files in a "views" directory or chunks accessible in the database). Where do SQL queries traditionally live in MVC frameworks?

            My goal is to have something that has an EASY interface and is secure. I’d like it to be robust and OO, but not at the expense of a clear and simple user interface. I was sketching out interface ideas for Snippets. Imagine a page (i.e. a controller) that will show a single record from a database.

            [!MySnippet &function=`read` &table=`some_custom_table` &id=`value_of_primary_key` &view=`name_of_template_file` !]


            The "function" parameter specifies which controller to use... say you’ve got a "read" function that corresponds to a "SELECT *" query and a "read_short" that corresponds to a "SELECT id, one_column" query.

            Do you see where I’m going with this?

              • 22303 MODX Staff
              • 10,725 Posts
              Quote from: Everett at Jan 08, 2009, 05:00 PM

              Do you see where I’m going with this?
              Yes. See xPDO...
                • 4172
                • 5,888 Posts
                Hi Everett, what you want to do, sounds a little bit like my system Xett.

                this is an example call:

                [!Xett? &project_path=`fewo`&service=`belegplanlong`&canedit_webgroups=`testuser,editoren`&config_path=`config`!]

                In short words how it works:
                1. looks in the path fewo->belegplanlong->includes to the file getdatas.php
                2. the file getdatas.php can have something like that:

                $roomsparent=$this->xetconfig['docids']['rooms'];
                // Wohnungen suchen
                $tablename1 = $modx->getFullTableName('site_content').' sc'; 
                
                $query="select sc.id as room_ID,sc.pagetitle as room_title";
                $query.=" from ".$tablename1;
                $query.=" where parent= ".$roomsparent;
                $query.= " and description <> 'noroom' ";
                $query.= " order by room_title ";
                
                $rows = $this->getevents($query);
                
                
                $rooms=array();
                
                foreach ($rows as $room)
                {	$days=array();
                    //$room_id=$room['room_ID'];
                	foreach($cal['days']as $key=>$day){
                		$day=array_merge($day,$room);
                	    $day['getDatasOnRender']='1';
                		$days[$key]=$day;	
                	}
                	$room['innerrows']['day']=$days;
                	$rooms[]=$room;
                }
                
                }
                $monthdata['tsmonth']=$timestampfirstday;
                $monthdata['innerrows']['rooms']=$rooms;
                $monthdata['innerrows']['monthdays']=$cal['days'];
                $monthdata['cacheaction']=$cacheaction;
                $monthdata['cachename']=$cachename;
                $monthdata['cacheoutput']=$cacheoutput;
                
                $outerdata['innerrows']['monthlist']=$monthlist;
                $outerdata['innerrows']['month'][]=$monthdata;
                $xettdatas = $outerdata;	


                So here in getdatas.php you create your individual array for Xett to work with.
                The outer Template is always xetouterTpl.html here in the path fewo->belegplanlong->includes
                then you can have nested inner Templates
                If you have something like $xettdatas[’innerrows’][’rooms’] Xett looks for an Template roomsTpl.html
                and Xett replaces the placeholders in roomsTpl.html for example
                [+xett.row.roomname+],[+xett.row.roomsize+],[+xett.innerrows.events+]
                for each datarow of $xettdatas[’innerrows’][’rooms’] takes this output and replaces [+xett.innerrows.rooms+] in xetouterTpl.html with this.

                You can get all nested arrays in getdatas.php or you can say
                [’day’][’getDatasOnRender’]=’1’ somewhere in the array.
                Then Xett looks later for the file dayGetdatas.php and works with this array.

                If you have forms in your templates Xett processes this forms in the file onsavedatas.php for saving, mail sending or what else you want to do whith this datas.

                In the next version I have included a little cache-class, So I can cache different views of each Template.
                For example different month-views of event-calendars and so.

                One example you can see here: http://www.meine-goldschmiede.de/testmodx/index.php?id=1122 and there: http://www.meine-goldschmiede.de/testmodx/index.php?id=1151

                I’m sure there is a lot of work to do and to rewrite, but it is working very well and I use it for very different projects.

                Bruno

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

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!
                  • 3749
                  • 24,544 Posts
                  I’ve written CRUD tools (a long time ago in the pre-OO days) and IMHO, you’ll find that the hard part is the user inferface. Compared to the UI, everything else is a piece of cake, especially with xPDO to do the heavy lifting. For one of the CRUD tools I developed, it was actually easier to write code that would read from and write to MS Excel files and then use Excel as the front end UI. Be aware that you’re facing a very difficult and time-consuming programming task.

                  You might want to consider doing the project for Revolution. It will almost certainly be released by the time you’re done. wink

                  Here are some resources that might help:

                  Using xPDO in Revolution: http://svn.modxcms.com/docs/display/~splittingred/2008/06/25/PHP+Coding+in+MODx+Revolution%2C+Pt.+I
                  (note the "next" link at the end of the article - it’s in three parts.

                  Database Schemas/components: http://svn.modxcms.com/docs/display/~splittingred/2008/06/26/Writing+a+3rd+Party+Component+in+MODx+Revolution%2C+Pt.+I

                  Custom Manager Pages: http://svn.modxcms.com/docs/display/~splittingred/2008/07/10/Creating+Custom+Manager+Pages+for+a+3rd+Party+Component%2C+Pt.+I

                  MODx MVC Implementation: http://modxcms.com/transforming-modx-oo-mvc-orm.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
                    • 9207 ☆ A M B ☆
                    • 2,475 Posts
                    Bruno, thanks for the post!
                    Bob, thanks for the links -- yeah, I’ve actually spent most of my time so far on the interface portion... trying to figure out exactly what my client and the site visitors will need. I’m aware it’s a big time commitment... but I’m measuring it against how long I think it’ll take me to do by hand.
                    Jason, I’ll have a look into xPDO with this in mind. Since I’ve got a clear goal on what I need it to do, I think I can better evaluate it.

                    I’m without internet for another few days (good-bye weekend coding), but it made me spend a lot of time sketching out how I imagined the UI and the back-end code would look. What I realized is that the Controller calls (in Snippets on the front-end or in the Module on the back-end) can simply specify a model, arguments to that model, and a view for displaying the results (if necessary)... and that’s all it needs to do. In a simplified example, the Snippet call may look like this:

                    [!CRUD &model=`model_for_my_database_table` &id=`34` &view=`name_of_template_or_chunk` !]


                    Some models may require more arguments, e.g. a model that returns multiple rows might need a max and min id. A model might represent tables joined together. I realized a model might even represent a delete action (sorry if I’m a little slow)... the controller sends some arguments to the model, the model throws something at the database, and the model returns something (either an error message or a success string), and that can be displayed in a view.

                    Anyhow, this has been a really interesting discussion... I’ve learned a lot more about MVC through this, and I get the strong feeling that someone smarter than me has already figured out a good way to do this (tip of the hat to Jason and others).