Following along the line of the HelloWorld example, here is an example of a chat application for OpenGoo. It is not a very useful application, but it will help us get to know more about hacking OpenGoo (we call it "hacking OpenGoo" and not "developing for OpenGoo" because of the lack of a formal API). Let's call our little application ChatUp.

+

Following along the line of the HelloWorld example, here is an example of a chat application for Feng Office. It is not a very useful application, but it will help us get to know more about hacking Feng Office (we call it "hacking Feng Office" and not "developing for Feng Office" because of the lack of a formal API). Let's call our little application ChatUp.

===== Designing ChatUp =====

===== Designing ChatUp =====

-

ChatUp will consist of a new tab in OpenGoo's main interface, were a user will be able to see and join ongoing chats or create a new chat and wait for users to join. Once he joins a new chat he will see which users have joined the chat and what anyone has said since the chat begun, and he can now send messages to the chat and will also keep receiving other users chat messages as they are being sent. We'll keep the app simple for educational purposes, but we'll later see that we could do lots of things to make the app more useful and usable.

+

ChatUp will consist of a new tab in Feng Office's main interface, were a user will be able to see and join ongoing chats or create a new chat and wait for users to join. Once he joins a new chat he will see which users have joined the chat and what anyone has said since the chat begun, and he can now send messages to the chat and will also keep receiving other users chat messages as they are being sent. We'll keep the app simple for educational purposes, but we'll later see that we could do lots of things to make the app more useful and usable.

Our model will consist of:

Our model will consist of:

Line 14:

Line 14:

===== Introduction to models =====

===== Introduction to models =====

-

There are several things we need to do to create our two objects (Chat and ChatLine) in OpenGoo. We will start by defining the PHP classes that will represent these two objects but before we do that lets see a brief introduction of models (the M in [[MVC]]) in OpenGoo. If you take a look at the 'application/models' folder you will see many folders, each representing one object in OpenGoo. For example, the 'contacts' folder defines the classes for OpenGoo contacts. If you take a look inside that folder you will see this file structure:

+

There are several things we need to do to create our two objects (Chat and ChatLine) in Feng Office. We will start by defining the PHP classes that will represent these two objects but before we do that lets see a brief introduction of models (the M in [[MVC]]) in Feng Office. If you take a look at the 'application/models' folder you will see many folders, each representing one object in Feng Office. For example, the 'contacts' folder defines the classes for Feng Office contacts. If you take a look inside that folder you will see this file structure:

* base/

* base/

* BaseContact.class.php

* BaseContact.class.php

Line 23:

Line 23:

The code is separated in 'base' classes and non-base classes because this is how the original framework, that was inherited from activeCollab, defined objects. We now continue defining objects like this to be coherent with the rest of the code, and because it makes the code more readable as you'll see.

The code is separated in 'base' classes and non-base classes because this is how the original framework, that was inherited from activeCollab, defined objects. We now continue defining objects like this to be coherent with the rest of the code, and because it makes the code more readable as you'll see.

-

The BaseContact class basically defines all [[getters and setters]]. Take a look at that the file to see for yourself. Most of the functions in that class are called like getSomething and setSomething. There are however two elements that are not getters and setters. At the beginning there's a property called $objectTypeIdentifier. This property defines a two character code to identify the type of this object. For contacts this is 'ct', for companies 'co', etc. There's also another interesting function called 'manager' at the end of the file. All objects in OpenGoo have this function, and it returns the objects manager. An object manager is a class in charge of performing queries against the database. In the case of contacts, the manager is the Contacts class.

+

The BaseContact class basically defines all [[getters and setters]]. Take a look at that the file to see for yourself. Most of the functions in that class are called like getSomething and setSomething. There are however two elements that are not getters and setters. At the beginning there's a property called $objectTypeIdentifier. This property defines a two character code to identify the type of this object. For contacts this is 'ct', for companies 'co', etc. There's also another interesting function called 'manager' at the end of the file. All objects in Feng Office have this function, and it returns the objects manager. An object manager is a class in charge of performing queries against the database. In the case of contacts, the manager is the Contacts class.

-

Now let's take a look at the BaseContacts class. This class is in charge of mapping OpenGoo Contact objects to the MySQL database. It does that by implementing a few functions called 'getColumns', 'getColumnType', 'getPkColumns' and 'getAutoIncrementColumn', as well as other functions ('finders') that are usually the same among all objects, but changing the name of the object. In the constructor we call the parent constructor, passing it two strings: the first one is the name of the object's class ('Contact') and the second is the name of the table that is mapped to this object ('contacts'). The 'getColumns' function returns the columns in that table that will be used by our object. The function 'getColumnType' returns the type of the column passed as an argument. To simplify these two functions, we define the columns as an array whose keys are the column names and the values are the column values. By doing this the 'geColumns' and 'getColumnType' functions are the same across all objects and just return the array and the value for a key in the array respectively. The 'getPkColumn' usually just returns the column 'id', but could return an array of column names that conform the objects Primary Key. Finally, the 'getAutoIncrementColumn' function returns which column increments automatically (if there is one).

+

Now let's take a look at the BaseContacts class. This class is in charge of mapping Feng Office Contact objects to the MySQL database. It does that by implementing a few functions called 'getColumns', 'getColumnType', 'getPkColumns' and 'getAutoIncrementColumn', as well as other functions ('finders') that are usually the same among all objects, but changing the name of the object. In the constructor we call the parent constructor, passing it two strings: the first one is the name of the object's class ('Contact') and the second is the name of the table that is mapped to this object ('contacts'). The 'getColumns' function returns the columns in that table that will be used by our object. The function 'getColumnType' returns the type of the column passed as an argument. To simplify these two functions, we define the columns as an array whose keys are the column names and the values are the column values. By doing this the 'geColumns' and 'getColumnType' functions are the same across all objects and just return the array and the value for a key in the array respectively. The 'getPkColumn' usually just returns the column 'id', but could return an array of column names that conform the objects Primary Key. Finally, the 'getAutoIncrementColumn' function returns which column increments automatically (if there is one).

-

A further note on columns: All [[Content Objects]] in OpenGoo have some common columns, which are 'id', 'created_on', 'created_by_id', 'updated_on', 'updated_by_id', and may contain 'trashed_on' and 'trashed_by_id'. These columns are required for some functionality to work correctly, and so our Chat object will contain them. ChatLine is not really a [[Content Object]] and so will not contain these columns.

+

A further note on columns: All [[Content Objects]] in Feng Office have some common columns, which are 'id', 'created_on', 'created_by_id', 'updated_on', 'updated_by_id', and may contain 'trashed_on' and 'trashed_by_id'. These columns are required for some functionality to work correctly, and so our Chat object will contain them. ChatLine is not really a [[Content Object]] and so will not contain these columns.