Welcome to
'Confessions of a Culture Shock Junkie' ™
Home >> Technology >> Joomla! >> How Groja.com Uses the Joomla! MVC API

Site Style

Who's Online

We have 23 guests online
 
How Groja.com Uses the Joomla! MVC API Print
Technology - Joomla!
Written by Tom H.   
Tuesday, 03 February 2009 00:00

The functionality of groja.com's Draw option is an original joomla! component named com_groja. The design of this component is based on joomla's Model-View-Controller (MVC) Application Programming Interface (API).

Joomla's MVC API gives developers a framework for developing complex applications.

  • Models are specialized classes that know how to do something, such as store and retrieve data from cookies or a database.
  • Views are classes that know how to display something, such as groups of forms that allow users to send data to the server in a request.
  • Controllers are classes that know how to accomplish a task, such as validating and storing data from a form.

This article describes how groja.com uses joomla's MVC API.

This article makes no effort to describe concepts such as the MVC design pattern and object oriented design (OOD). There is already a great deal of information about MVC and OOD on the web; google and the wikipedia are good places good to start.

Class Diagrams

The following class diagrams show how the com_groja component uses the joomla! Model View Controller (MVC) Application Programming Interface (API). These diagrams show only important public and protected data members and methods.

  • Clicking on any diagram opens a full-sized view of it in a new window.
  • Classes with names beginning with "J" are part of the joomla! framework API.
  • All other classes are Copyright © 2008-2009 Tom Hartung.
  • Classes with names beginning with "C" were ported from previous versions of the site.

Controller Classes

This diagram shows the controller classes, which inherit from the joomla! framework classes JObject and JController.

Diagram of classes GrojaControllerListPage and GrojaControllerDrawPage inheriting from GrojaController, which inherits from JController, which inherits from JObject; see text for details


The JController class automatically sets its $_task variable to the value of the task request variable, which is set when a user submits a form.

The GrojaController class defines protected data members that contain data storage models shared by both the list and the draw pages. When the user is logged in, these models store image, profile, and user data in the database. When the user is not logged in they store this data as cookies.

The JController class automatically calls a method with the same name as the task request variable. When the task request variable is not set, JController calls the subclass' display() method.

The GrojaControllerListPage class defines methods that process tasks that come as requests from the forms on the list page. Examples of tasks that the list page performs are save_profile() and publish_image().

The GrojaControllerDrawPage class defines methods that process tasks that come as requests from the forms on the draw page. Examples of tasks that the draw page performs are draw() and save_image().

View Classes

Diagram of class GrojaViewGroja inheriting from JView which inherits from JObject; see text for details

This diagram shows the GrojaViewGroja class, which inherits from JObject and JView. This class diagram is trivial because the view relies heavily on templates and code ported from earlier versions of the site.

Joomla's JView class uses program files called view templates rather than subclasses to implement the component's views. The class diagram does not show these templates.

The list and draw pages each have a corresponding template that contains methods that determine the basic layout of the page. These templates use classes ported from previous versions to print the lists, forms and images on the pages. These templates also contain the code that uses javascript and mootools to implement the tabs and sliders on the pages.

The classes that were ported from previous versions of the site have names starting with "C." They are defined outside of the joomla! framework and operate independently of it.


Page Model Classes

This diagram shows the page model classes, which inherit from the joomla! framework classes JObject and JModel.

Diagram of classes GrojaModelListPage and GrojaModelDrawPage inheriting from GrojaModelGroja which inherits from JModel which inherits from JObject; see text for details


The groja component's list and draw pages have very little in common. Therefore the parent class, GrojaModelGroja, contains only some information about the user, encapsulated in a CGrojaUser object.

GrojaModelListPage, the list page model class, contains a data member defining each list and form on the page. Most of these data members are objects instantiating classes ported from earlier versions of the site.

The GrojaModelListPage class also contains methods that help the controller process quiz data. Additionally, the controller uses methods such as userChangingProfile() and postArticle() to process requests that come from forms on the page.

GrojaModelDrawPage, the draw page model class, contains a data member defining the image and each form on the page. Most of these data members are objects instantiating classes ported from earlier versions of the site.

The GrojaModelDrawPage class contains methods that can create and draw an image. These methods can draw a new image or redraw a saved image, and whether the score and image data comes from cookies or the database is irrelevant to this class. The controller uses other methods in GrojaModelDrawPage, such as updateDrawOptionsFromRequest() and setPrintOptionsInPage(), to process requests that come from forms on the page.

Top-level Storage Model Classes

This diagram shows the top-level storage model classes, which inherit from the joomla! framework classes JObject and JModel.

Diagram of classes GrojaModelCookies and GrojaModelDatabase inheriting from JModel which inherits from JObject; see text for details


The com_groja component stores profile and image data for logged in visitors in the database, and saves data for visitors who are not logged in as cookies in the visitor's browser.

Because storing data as cookies is so totally different from storing it in a database, allowing users who are not logged in to save profiles and images as cookies was one of the most challenging features implemented in this version of the site. Using Object Oriented Design (OOD) and joomla's MVC API helps keep all this code organized.

Design Goals

The goals for using this design are as follows:

  • The code that uses cookies to store data must be completely separate from that which uses the database
  • Only storage models know how the data is being stored
  • Although other models in the component may sometimes need access to the visitor's level - and thus whether the visitor is logged in - how the storage models actually store the data is irrelevant to these other models

These are base classes only. Subsequent diagrams illustrate the subclasses that handle the different types of data (profile, image, etc.).

Although these classes could share a couple of data members, such as $_id and $_row, in a parent class, they are so different that there is little benefit to having an extra level of inheritance.

Cookie Model Classes

When the visitor is not logged in, the com_groja component stores data as cookies in the visitor's browser.

Profile and Image Data

This diagram shows the classes that store image and profile data as cookies. These classes can save up to one image and profile for each score type (quiz, percentages, etc.).

Diagram of classes GrojaModelImageCookies and GrojaModelProfileCookies inheriting from GrojaModelCookies which inherits from JModel which inherits from JObject; see text for details


The GrojaModelProfileCookies class stores each profile score in a separate cookie. This class contains the methods storeImageData() and getDrawParametersFromStorage() so it can store image data when the user is drawing an unsaved image.

The GrojaModelImageCookies class stores each saved image in three cookies: one containing the image string, one containing the image options, and one containing the original score (the user might change the profile after saving the image).

Cookies cannot be longer than 512 characters; this limits the resolution of images when a user is not logged in.

Quiz and User Data

This diagram shows the classes that store quiz and user data as cookies.

Diagram of classes GrojaModelAnswerCookies, GrojaModelQuizCookies, and GrojaModelUserCookies inheriting from GrojaModelCookies which inherits from JModel which inherits from JObject; see text for details


The GrojaModelAnswerCookies class stores all quiz answers in a single cookie. The storeNewAnswerRows() method updates this data when the user changes one or more quiz answers.

The GrojaModelQuizCookies class stores the quiz tiebreakers in a cookie. The site uses quiz tiebreakers when the visitor's score is perfectly balanced between one or more pair of opposites.

The GrojaModelUserCookies class stores options for printing an image.

Note that all of these cookie models must override the getRow() method, because each stores its data in a unique way.

Database Model Classes

When the visitor is logged in, the com_groja component stores the visitor's data in the database.

Diagram of classes TableAnswerDatabase, TableContentDatabase, TableImageDatabase, TableProfileDatabase, TableQuizDatabase and TableUserDatabase inheriting from JTable, which inherits from JObject; see text for details

Table Classes

This diagram shows the database table classes. There is one table class for each database table that this component uses. Each table class contains data members corresponding to the columns in its corresponding database table.

The joomla! framework API facilitates encapsulation by keeping these lists of column names in a single place.

Saving data in a database means storing a row of column values. Because these table classes define the columns specific to each table, database subclasses do not need to override basic methods like getRow(). That is, these subclasses of JTable act as interfaces to specific database tables and can rely heavily on methods defined in the parent class.

The bind() method in the JTable class accepts data in the form of an associative array. When the array contains an element with the same name as a column, the bind() method automatically copies the data from the array to the column.

If, for example, the names of all form variables match the names of database column, and a database model passes an array of this request data to the bind() method, no additional processing is necessary. When one or more of the form variable names do not match database column names, the table class must provide additional processing before storing the data by overriding the bind() method.

These classes can also override JTable's check() method to ensure the values for all columns are valid.


Content, Profile and Image Data

This diagram shows the classes that store content, image, and profile data in the database.

Diagram of classes GrojaModelContentDatabase, GrojaModelImageDatabase, and GrojaModelProfileDatabase inheriting from GrojaModelDatabase which inherits from JModel which inherits from JObject; see text for details


The grojaModelContentDatabase class is the com_groja component's interface to joomla's content table. It allows visitors to post a groja to the site's content area. The component uses the setState() method to publish and unpublish a posted image.

Although the classes that store image and profile data perform much differently from their counterparts on the cookies side, the API to these classes parallels those classes.

Sortable lists is a feature available only to visitors who are logged in. The protected method _buildQueryWhere() implements this feature. Clicking on a heading in a list of profiles or images causes the framework to use the _buildQueryWhere() method to build an SQL WHERE clause that sorts the data based on values for that database column.

Quiz and User Data

This diagram shows the classes used to store quiz and user data in the database.

Diagram of classes GrojaModelAnswerDatabase, GrojaModelQuizDatabase, and GrojaModelUserDatabase inheriting from GrojaModelDatabase which inherits from JModel which inherits from JObject; see text for details


The com_groja component uses two tables to store quiz data. The GrojaModelAnswerDatabase class stores and retrieves data for a single answer. Like its counterpart on the cookie side, it contains a storeNewAnswerRows() method to store changed answers.

In addition to storing any tiebreakers needed for the quiz, the GrojaModelQuizDatabase class supplies a quiz_id that identifies which rows in the answer table belong to it.

The main purpose of the GrojaModelUserDatabase class is to store options for printing images.

Conclusion

The com_groja component uses joomla's MVC API to organize code into model classes, view classes, and controller classes.

Following this design pattern is not a simple matter. It requires a lot of concentration and quite a bit of work up front. However when done properly, this technique results in code that is easier to maintain because it gives the developer a way to divide the code up into specialized classes. This means that changes to one feature of the component are less likely to affect other features.

This component stores profile, quiz, image, and user data either as cookies or in the database, depending on whether the visitor is logged in. The com_groja component handles this complexity by breaking up the data storage functionality into two trees of model classes.

Each type of storage (cookies or database) has a parent class to handle code shared by the different types of data. The component uses a separate class to store each type of data (profile, image, etc.). This helps to greatly reduce code redundancy, thus facilitating changes to functionality and other code maintenance tasks.

Last Updated on Monday, 21 December 2009 00:22