29 December, 2006
Filed under v1.7, Architecture

I just checked in a few changes that allows a CiviCRM install to use a memcached server if available. We use the php memcached integration to make this possible.

To use this feature you'll need to do the following

  • Compile php with the --enable-memcache flag
  • Download and install memcached. Get the memcached daemon running on localhost and the default port (11211)
  • Define the CIVICRM_USE_MEMCACHE constant in your civicrm.settings.php file

Thats all there is to it. Currently we are storing the Config object and all the PseudoConstants in memcached and are seeing some performance improvements. As we figure out more bottlenecks, we'll migrate a few more core objects to the memcached partition.

We'll need to tweak things a bit to move this to production, but this looks like a pretty good first step. Overall, I'm quite happy with the integration...

Read more
27 December, 2006
Filed under v1.7, Architecture

I've spent a fair amount of time in the past two weeks figuring out how we could optimize and improve CiviCRM. Its been an interesting few days and I suspect will become more interesting over the next few days as we start implementing a few things. All this is in preparation for doing a pretty major load test for the Branner project.

I did read a few articles on the web about optimizing LAMP. The article was fairly helpful, but I disagree quite a bit with some of the conclusions. I think there is also a big difference between building something for one site vs building an open source product. I do agree that PEAR DB, QuickForm and Smarty add a lot of overhead to CiviCRM. On the other hand, I also think we get an incredible increase in productivity because of these components. If I was building stuff...

Read more
14 December, 2006
Filed under v1.7, Architecture, CiviCRM

One of our major goals for this year is to optimize CiviCRM to handle load in a graceful manner. This is extremely important for us with the Branner Project. One of our main goals for the project this year is to optimize CiviCRM to be able to handle the last weekend load nicely (similar to the slashdot effect, the application process has most of the applications being filed and completed the weekend it is due)

The application is a multi-step form, made up of approx 25-30 forms. We have data from last year that we can scramble and potentially get a good random data set that is fairly accurate. Writing a functional test for this is potentially quite painful, but there is the wonderful testing tool Selenium. We've been using it for testing CiviCRM with pretty decent results. We hope to make it part of our...

Read more
06 December, 2006
Filed under CiviMail, Architecture, CiviCRM

CiviMail, described in general previously, is our component for mass-mailing the CiviCRM contacts. In this entry, we’d like to get a bit more into the details on how CiviMail exactly works ‘under the hood’.

Recipients List Building

Getting the final list of recipients is not as easy as it may seem. If you look into the getRecipients() method of the CRM_Mailing_BAO_Mailing class, you’ll see that we’re building some temporary exclude (X_*) and include (I_*) tables, based on

  • the user’s selection – excluded/included CiviCRM groups,
  • the user’s selection – excluded/included previous mailings’ recipients,
  • whether the contacts already received this mailing in...
Read more
17 November, 2006
Filed under Architecture, CiviCRM

It is important for CiviCRM to have a full fledged un-structured search engine in addition to the current structured query. I don't think MySQL full text searching (MFTS) is a good model for a couple of reasons. Firstly MFTS is restricted to myisam tables and CiviCRM uses innodb tables. Secondly MFTS is still a table level search and i don't think it can handle hierarchical data. CiviCRM contacts are hierarchical data sets.

Would be great to integrate something like Lucene into CiviCRM. A potential work flow could be as follows:

1. Publish an xml specification of the CiviCRM data model. We have done a fair amount of this work for the Branner project. We could extend and automate this quite nicely using our code generator. Also xml fits quite nicely since we can represent hierarchical data

2. Extend the logging functionality so we are aware of all modifications to any...

Read more
14 November, 2006
Filed under Architecture, CiviCRM
This installment of our architecture series will introduce the templating system used by CiviCRM as the presentation layer (e.g. to actually render forms and pages). Every CiviCRM screen is "composed" from one or more template files. These files contain a combination of HTML tags, text, variables and (often) some code to control presentation logic. CiviCRM uses an open-source templating engine called Smarty. If you are planning on examining, debugging and/or and modifying CiviCRM screens - you'll want to spend some time reviewing Smarty's online documentation.

Finding the Template(s) Used by a Form or Page

The easiest way to find the base template used to render a particular CiviCRM screen is to do a "View Source" while on that screen. Then search for the string '.tpl file'. This will take you to a commented HTML line that looks like this (this is the Edit Contact form):... Read more
14 November, 2006
Filed under Architecture, CiviCRM

CiviCRM Forms and Wizards (multi-page forms) are based on PEAR's HTML_QuickForm_Controller. (QFC). QFC in turn is based on HTML_QuickForm (QF). It was easier for us to model a single form as a one page wizard, and hence all CiviCRM forms are instances of QFC

The basic Form object is CRM_Core_Form. All forms are derived from this class. Each derived class is expected to implement the following functions

  • function preProcess( ): This function is called before a form is built. All objects needed to build the form should be built in this function.
  • function buildQuickForm( ): This function builds the form. There are some helper functions in CRM_Core_Form to build some elements (Radio, Select, Yes/No etc). Classes typically call a mixture of these helper functions and QF functions directly
  • function setDefaultValues( ): Default values when the form is first rendered. Typically we use the same form...
Read more
11 November, 2006
Filed under Architecture, CiviCRM

We now move onto the more interesting stuff of what really happens when a request is made and the objects that are responsible for building the response. The top level CiviCRM objects are:

  • Form (CRM_Core_Form): CiviCRM forms are based on HTML_QuickForm. For drupal folks, this is more of an object representation of the much loved form api
  • Wizard (CRM_Core_Controller): A set of CiviCRM Forms that collectively make up an action (Import Wizard, Mailing Wizard etc). For simplicty sake a one page Form is represented as a Wizard (CRM_Core_Controller_Simple)
  • Page (CRM_Core_Page): A Page represents all html pages that are not of the above two types
  • Selector (CRM_Core_Selector): A selector is a tabular/grid representation of the database data. Selectors are not high level objects, but are embedded in either a Page or a Form object.

Each of these objects offer a...

Read more
11 November, 2006
Filed under Architecture, CiviCRM

CiviCRM uses the PEAR package DB_DataObject to access the mysql database. Doing so reduces the amount of sql we need to write to fetch / store values for a single table. For queries involving more than one table, we write them manually since since it was fairly painful to try to force complicated queries using DB_DataObject (we did use DB_DO for multiple table queries when we wrote EmailNow, in the end we felt the hoops we had to jump through was not worth the effort and hence the current scheme)

The basic PHP classes that represent a table are called DAO's (Data Access Objects). These are generated automatically by (xml/GenCode.php) which also generates the sql structure for that specific table. The xml files representing the schema is stored under CIVCRM_ROOT/xml/schema. The sql file generated (civicrm_41.mysql and civicrm_40.mysql) are stored under CIVICRM_ROOT/sql (note that the generated files are not present in the svn repository). The DAO files are stored under...

Read more
06 November, 2006
Filed under Architecture, CiviCRM

Make sure you read the Introduction Chapter of this series for a better understanding of the below. Developers might be interested in installing CiviCRM from our svn repository

Some of the important directories under CiviCRM svn root are:

  • CRM: Most of the CiviCRM specific source code is stored in the directory. This directory is further sub-divided into other directories based on functionality (Core, Utils, Contact, Contribute, Mailing etc).
  • xml: CiviCRM schema and the base Data access objects (DAO) are automatically generated from a simplified xml scheme which contains a fair amount of sql and type information. This makes it relatively easy for us to change the sql code, figure out what changes were made in a version and add meta information to a table within PHP.
  • ...
Read more