New userEdit version
It has come to our attention that under some circumstances the userEdit plugin wouldn’t let the users logout.
New version (beta2) has been posted: com_moldingsoft_useredit-beta2.zip
New assignContact beta version
it has come to our attention that the assignContact plugin does not configure properly (joomla error appears in the plugin configuration) when the userEdit plugin is not present. The bug has been fixed in the following version:
Hands-on development with the Moldingsoft framework pt1
So, in our introduction we mentioned all about integration to Joomla and easy access to your infusionsoft data with automated caching. How can I get that you will ask me.
This is the purpose of this post. We will take one of the sample plugins and review the important code lines while discussing the do’s and dont’s for the framework.
So, in our introduction we mentioned all about integration to Joomla and easy access to your infusionsoft data with automated caching. How can I get that you will ask me.
This is the purpose of this post. We will take one of the sample plugins and review the important code lines while discussing the do’s and dont’s for the framework.
1) A quick introduction to the base framework elements
The core Joomla framework (/libraries/joomla) provides all the basic objects and helpers that drive the entire CMS. Here we can find the JFactory, JUser and JTable classes that we will almost exclusively be working on.
- JTable: This is the core class that the component builds upon. In it’s basic form it represents a single row of an abstract database table. By extending it, the joomla framework represents rows in the Users, acl tables and so forth. For our uses, we extend and create our own abstract table named JTableMoldingsoft, which is to be used for referencing both the local and remote database tables (more on this later).
- JFactory: This static class implements most of the functionality for Joomla’s factory design paradigm. Since we’re trying to make a perfect meld with Joomla, we are extending JFactory with our JFactoryMoldingsoft which contains our additions on top of the traditional class.
- JUser: This object’s functionality is pretty self-explanatory. It contains information about a user, and more frequently than not, the user that is currently loading the page. Since the framework has the ability to assign contacts to users, we have our own extension of this object named JUserMoldingsoft.
For all joomla-generic purposes, a JUserMoldingsoft is exactly the same as a JUser. The same applies with JFactoryMoldingsoft and JFactory.
2) The JTableMoldingsoft
The extension of the JTableMoldingsoft is the heart of the framework. It allows you to access local and remote (in infusionsoft) table rows without the need to know where they reside exactly. By having a careful database design, it also allows you to use two sets of keys in the tables. You have access to both the local primary key (id) and the infusionsoft key (idis), so you can read/write entries with whichever key you desire.
So, as long you access the infusionsoft tables with the appropriate JTableMoldingsoft, you have the power ignore the data’s actual location. Once something is loaded, you can be certain that it resides in the local cache, and ontop of that:
- Any relationships between the table entries are automatically translated to the local primary keys (e.g. a contact.CompanyID points to another contact by the local id, not idis)
- Any referenced items are automatically cached. While loading “John Doe”, the system will make sure that his company, “John Doe Co.” is also there
- Foreign key relationships are strictly enforced without the need of any further action. If for any reason “John Doe Co.” ceases to exist on your infusionsoft application (and the component is made aware of this of a forced or timed-out cache), all the employers will be automatically be disassociated immediately.
- Transactions guarantee that write attempts to the infusionsoft application are kept in sync with your local data. If for example a write fails because the IS API is down, your local entries are automatically rolled back to their last proper state.
Once you load something through the appropriate JTableMoldingsoft, you immediately have access to a near-identical table&entry on your local database. This means that you can run any kind of complex SQL query safely, because as we mentioned before, all referenced items are also loaded as well. Data mine away!
Bear in mind though, that direct SQL access to the tables bypasses the entire caching system. Expired rows are still present in the database until they are accessed from a JTableMoldingsoft. At that point, the row is either refreshed or dropped (because for some reason it was deleted in infusionsoft). A good rule-of-thumb to follow is the usage of the IsContact view with an HTTP post every time an actionset is run on an infusionsoft contact that updates some of his information. This way you know that even expired entries are most likely up-to-date.
3) Coding examples:
As mentioned in the introduction document, the framework on it’s own does next to nothing (only the isContact/isContactUser views perform functions). So, it is at the hand of our extensions to start using (and therefore importing) information about contacts.
As time passes, the component will be accompanied by a variety of plugins that take some very basic tasks automated, like the com_moldingsoft_assignContact plugin:
3.1) Assigning contacts to users
It is mentioned earlier that the JUserMoldingosft contains extra information about the user concerning infusionsoft data. And what more obvious thing to contain than a relevant contact?
So we start with a simple plugin that takes care that all users have appropriate contacts assigned to them. Take your time to install the plugin in your framework and see it’s configuration.
It’s pretty self-explanatory, and the code itself is even simpler.
By looking at the code, anyone who has written a plugin itself will notice the few basic things:
- This is a plugin of the authentication group
- It employs the onAuthenticate and onLogin callbacks (onLogin does not traditionally belong to the authentication group, but this is one of those “undocumented” joomla things).
The only thing that’s different in terms of a classic plugin is the inclusion of our framework’s factory class:
require_once(JPATH_ADMINISTRATOR.DS.‘components’.DS.‘com_moldingbox’.DS.‘JFactoryMoldingsoft.php’);
This way we have access to all the extended objects we need.
Moving to the onLoginUser callback, we have a simple task: Each time a user logs in, if he has no contact assigned to him, attempt to do so now. This task is performed in whole in the following function:
private function _assignContactToUser($username){
jimport(‘joomla.user.helper’);
$result = JUserHelper::getUserId($username);// $this->_getUserByUsername($username);
if (!$result) return false; //If we could not find a user with that username, abort with false
$user =& JFactoryMoldingsoft::getUser($result);
if($user->getContact()) return true; //get(‘id_contact’,false)) return true; //Do not attempt to re-assign a contact if one exists
//If the user has no contact assigned to him and the configuration requests a match attempt on login, do so.
$contact = JFactoryMoldingsoft::getContactByEmail($user->email);
if($contact && $contact->id){
$user->set(‘id_contact’,$contact->id);
$user->save();
return true;
}
return false;
}
As you can see, this is done in a handful of lines:
- Import the joomla JUserHelper
- Discover the id of the user with the provided username. If none exists, stop (this shouldn’t happen since onLoginUser happens after the authentication has succeeded)
- Use JfactoryMoldingsoft::getUser exactly as we use it with JFactory. This gives us a JUserMoldingosft object back according to the provided id
- JUserMoldingosft->getContact() does a pretty obvious thing: It either returns us a contact or false. It’s worth noticing here that we get back a moldingsoftContact row, which is the extension of the JTableMoldingsoft for the contact table.
- Given the user’s email, try to find a relevant contact. Please bear in mind that JfactoryMoldingsoft::getContactByEmail is currently a non-cached query, since we do need to check if there’s someone with this email we currently don’t know about in the infusionsoft database. This line is also the only data entry point for our entire plugin.
- If the contact returned is valid (redundant error checking present as you can see), associate this JUserMoldingosft with the contact. The current beta of the component has a simpler way to associate users with contacts, but this plugin was written a couple versions earlier. So one can go ahead and use: $user->associate($contact->get(‘id’));
That’s all! Now any plugin in the system can request the JUserMoldingsoft object and retrieve it’s associated contact and start playing around.
For the curious, take an extended look at the sources of the plugin, you can immediately notice that the references to infusionsoft are kept to just a few lines of code, and those are done in a joomla/OO-friendly way.
In the next blog update, we will see a more complex example that has more functionality displayed than a simple “fetch me a contact with the provided email and associate it with a user”.
Joomla Infusionsoft Beta Test Support Site
Here is the beta-1b2 component file DOWNLOAD
Here are some sample plugins:
Assign contacts to user upon their login and disallow depending on tags: DOWNLOAD
Update infusionsoft information when a joomla user changes his details: DOWNLOAD
Are you participating in the beta and have some problems/found a bug? Don’t hesitate to contact us or directly mail our development team directly:
nonickch <at> gmail [dot] com
“G. Nt” / “nonickch” on skype