CiviCRM Bootcamp New Orleans, March 18 and 19, 2008

2008-03-25 16:38
Written by

Day 1: Technically, day 1 was a fabulous dinner hosted by CiviCRM at Herbsaint in the warehouse district of New Orleans. This is Susan Spicer's restaurant, and it was delicious -- they even made the vegetarian (me) a special-not-on-the-menu meal! We took this time to get to know each other and talk a bit about CiviCRM, what we liked/disliked, and the development community in general.

Day 2: 9 AM start at the Sheraton on Canal Street. Dave took us through a CiviCRM tour to go over new 2.0 features and other features/settings we may have not been familiar with. Went through the Global Settings piece by piece...some of the new or under-used pieces include fiscal year start in the Date settings and a new "Case" feature in CiviCRM that can be turned on under Site Preferences (this is in early stages). Walked through the "Tell a Friend" option that comes as a setting on any membership/donation/event form. We looked at the new contribution widget (you can control what it says, and supposedly how it looks but you may need Flash for that). Demoed "Pay Later".

This was followed up by a long discussion about debugging. Most basic debugging is to turn on backtrace and debugging in Global Settings > Debugging. You can also customize the debugging template file so that it gives a more user-friendly message or looks different. How to do this is part of customizing CiviCRM through custom templates, which I will talk about later.

More debugging tips: if you are stumped on a page (especially useful during custom template coding, etc), you can add "&smartyDebug=1" to the end of whatever URL you're looking at (make sure you enable pop-ups). This will pop up a window that shows you all of that template's variables and their values...very useful. You can debug your session by adding "&sessionDebug=1", you can reset your session with "&sessionReset=1", and you can view raw html snippet output by "&snippet=1". For more info on debugging, there is a wiki page here:

The rest of Day 1 is more pertinent once you know about Day 2, so we're moving right along. We stayed in our cave until at least 7 PM, so we must have done a lot!

Day 2: 9 AM start again. Got right to business with Lobo explaining the CiviCRM directory structure. All of the main classes of CiviCRM mirror the directory structure (sweet). So if you're looking in a file and see a class like:


you can find that file in /CRM/Contact/Page/ and the file will be called View.php. Nice and simple! To make it even easier, all of the templates that you can customize (more on this in a minute) will also mirror this structure, but they will be in the 'templates' directory. So you will notice that there is also a /templates/CRM/Contact/Page/View directory, and within that directory are loads of template files.

The CRM directory holds all of the code files, CiviCRM classes, etc. Then the templates diretory holds all of the Smarty templates that theme the main files (which is why they mirror each other). Within the CRM directory, there is another directory called "Core". This does what it sounds like; holds the main core files/classes. Lobo went over in detail the major classes, which for Page includes

CRM_Core_Page (again, to find this file, you would look in /CRM/Core and open up Page.php.

Forms and Wizards is another core feature of CiviCRM, built primarily from a base class of CRM_Core_Form (built largely on HTML Quickform). Other main classes for forms are CRM_Core_Controller, preProcess(), buildQuickForm, setDefault(), validate(), and postProcess(). Pretty much everything Lobo reviewed can be found in detail on the CiviCRM architecture series here:

We then reviewed the 2.0 database schema. There's been a lot of changes for this release; one of the most notable (I think) is the restructuring of custom data types, which now looks more like the Drupal cck system. For each new data type, there is a new group entry tracked in the custom_group table, the field structure is tracked in the custom_field table, but then each new custom group gets a table of it's own (prefixed by custom_value_1_$customGroup) where its data is stored. For a comprehensive guide to the CiviCRM schema (including a database diagram), check it out here:

At this point, we began looking at specific programming projects, questions, and requests in our group. One of the bigger areas we covered was building custom searches and templates. The 2.0 release makes it much easier for developers (even the really amateur techies like me :) ) to build their own searches where CiviCRM may fall short. It's also a great opportunity for community contributions where the searches we build can be given back. While in the bootcamp, I worked with Lobo to create a custom activity search that is now part of the 2.0 release.

The CiviCRM wiki already explains custom search building and profile building very clearly. The docs are here:

Basically, the search we built displays activities and related info in the results listings, and provides a bunch of parameters to limit your search. I learned that the best way to go about this is to check other searches or other pages that have something similar and copy, copy, copy! The advanced search template has the most options, so I recommend checking that out first. Note: In case you haven't been checking out all the links I've provided, it's very easy to find out what template/page you need. Just go to the page you want to edit (let's say Advanced Search), and do a view source. Then just search for a line that will look like this (you can search for '.tpl'):

.tpl file invoked: CRM/Contact/Form/Search/Advanced.tpl. Call via form.tpl if we have a form in the page.

There's the template file (whenever you see ".tpl" it's root directory is the templates directory), and since the templates structure mirrors the code structure, to see the code page, you'd look in CRM/Contact/Form/Search/Advanced.php for the code.

There's a bunch of other custom searches that are now built in to CiviCRM; you just need to tap into them. You do this by going to a URL like this: civicrm/contact/search/custom?csid=7&reset=1 where csid is the custom search id. To find which ids are available right now, you can just do a quick SELECT statement on your civicrm db:

SELECT * FROM `civicrm_option_value`
WHERE option_group_id = (
SELECT id FROM civicrm_option_group
WHERE name = 'custom_search'

You can plug any of the custom search ids into that url, and voila, new searches!

In any case, I highly recommend you check out the documentation on this:

After this, we worked mostly on individual projects. Here are some of the pieces we covered:

1. Dharmatech was very interested in creating a CiviCRM tab on a contact which could pull in that person's legislative districts based on their address. They worked with Dave to tap into the Sunlight API which aims to "create an up-to-date database for the 110th Congress that provides basic clerical information about members of congress (phone, email, district etc.) via API. Moreover, we provide converter methods to convert between the different IDs, thereby facilitating bringing together data about the same person from different sources. To complete the package, we have provided basic API methods that tie cities to zipcodes to districts to latitude/longitude, perfect for those web-based mashups ("

So, by passing longitude and latitude info from a contact to the Sunlight API, it would return their legislator info (the end goal is to then tie this into some kind of Action Alert module). They made great progress on this, and the only major snag they ran into was an intermittent lag time in return from Sunlight.

2. The other big project Dharmatech worked on was integrating the Drupal ubercart module with CiviCRM. Essentially, when a person orders something through ubercart on the Drupal side, they want the order info to show up in a CiviCRM contact tab. This is awesome! You can track the progress on this, and use the module they are contributing to do this here (keep in mind it's still in development):,2707.0.html.

3. I worked with Lobo on custom searches as mentioned above. We also decided that it would be best for the custom search entries to be part of the general CiviCRM administration area. As it stands right now, you have to check the db to see what custom searches are available, and you have to update the db if you create any custom searches of your own. This will be built-in to the 2.1 release, and you can follow the issue here:

4. We talked about moving the current built-in CiviCRM mailing subscribe pages to configurable profiles. This would allow for adding more fields to these pages, like name and address info, or you could just keep it as an email address and the mailing list subscription options. You can track this issue here:

5. There is an awesome module out there by the folks at UAS/Ninjitsu which lets you turn a bunch of Drupal nodes into a newsletter for CiviMail. However, the current form of this module generates a .txt and .html template for your newsletter, and you then have to cut and paste it into CiviMail. I thought it would be cool to integrate the newsletter generation directly into CiviMail instead. Lobo and I hacked the Ninjitsu module a little so that it will now write out the template files to the server and pass the file parameters to CiviMail, thus pulling them directly in. This will be part of CiviCRM 2.1 release, and in the meantime I will be contributing my patch to the Ninjitsu guys. Info on this:

UAS/Ninjitsu module is here:
This is not officially released on Drupal yet, but I will at least be starting a CiviCRM forum topic on this integration (will post URL once I start it :) ). It's a bit raw, and you have to do some taxonomy creation to get it working, but it's an incredibly useful integration. Just check out the README.txt for instructions.

You can follow the CiviCRM side of this issue here:

6. I wanted to give users the ability to view ALL contacts upcoming activities without them having to have the "Administer CiviCRM" permission. This is useful for my clients in that the staff members all schedule upcoming activities, and they want to follow each other. However, it's not a good idea for them all to have total CiviCRM access. Lobo and I fixed this one up quickly, and it should be released in the next revision of 2.0 (around the time of this blog posting). You can see this issue here:

7. One of the biggest projects I had is a need to tie organizational memberships directly to an organization record rather than an individual (which is currently the case). The conclusion is that it's a big revamp, but one that can and will be done for 2.1! A person will be able to sign up or renew a membership on behalf of an organization (they will have to have a permission set to do so). This is the very truncated version of this issue, but the long version will soon be posted on CiviCRM issues by a member of the CiviCRM team. Once it's up there, I'll update this blog entry.

Whew! Those are the "biggies" that we worked on. It was a LONG but REWARDING two days. The moral of this story is that I've been dabbling in CiviCRM for about two years at this point. I've configured, debugged, and tried my darndest to understand what's going on. I am not a PHP programmer; in fact, I can barely wrap my head around the OOP side. But working with Dave and Lobo for two days gave me a very solid foundation of both front and back end CiviCRM, and my understanding of CiviCRM has grown infinitely. It was also a huge benefit to those of us attending that they built in time for our personal projects. I am now able to figure out where to look when I'm having a problem, how to read the code, how to write some of my own code, and equally as important, I feel more confident in providing help back to the rest of the community. I highly recommend and shamelessly promote this bootcamp to anyone who wants to extend their CiviCRM knowledge.

Lastly, a huge thank you to Dave and Lobo for their effort, time and dedication to these bootcamps. Keep up the good work!

Filed under