Published
Friday, August 21, 2009 - 08:38
Written by
I continue my work on deploying CiviCRM for my kids school. In previous blog posts i documented how to use hooks and custom templates to schedule parent teacher conferences and extended care activities and how to expose relationship information in a profile view. In this blog post I'll describe some more advanced features. I'll also describe the code and directory structure.

New Code Structure and Directory Layout

As I added more functionality to the module, the code base was getting a bit out of control. Being a big fan of structure and directories, i switched the sfschool module to using a similar structure like the civicrm module. Thus i created a top level SFS directory under which most of the php code is. The module which resides under the drupal directory basically makes calls to the SFS module. The sql and templates directory hold the files that belong there. The bin directory is where scripts exposed to the outside world reside. Most of these scripts are auth controlled. They mainly are wrapper scripts around functionality in the SFS directory. You can browse the new directory structure here. I also created a Form directory to hold the standalone form that i'll describe later in this post

Sending reminder emails and a cron script

In a meeting with some of the school staff, we figured it would be useful to send an email to all the parents whenever an action was done on behalf of a child. This serves as a reminder and also lets the other parents know the action taken by one parent (and potentially avoids both parents doing the work). Sending an email was fairly easy, i just added it to the end of the postProcess clause which does most of the work. I also reused the CiviCRM Mail library (CRM/Utils/Mail.php) to do the actual sending of the email. In general it is good practice to keep an archive of all emails sent, so we bcc all emails to an archive address. For the parent teacher conferences we decided to send two email reminders to the parents. We decided to send the reminders 3 days and 1 day before the meeting. Unfortunately CiviCRM does not have this functionality, so i wrote a php script to do so. I reused the reminder email code above in the cron job above. I also had to ensure that we dont send the parents too many reminders if the cron job was activated multiple times. I reused the phone_number field in civicrm_activity to keep track of how many days before the meeting, an email was sent to the parent. A useful trick when building / testing CiviCRM mail related code is to use the mail logging setting. Add
define( 'CIVICRM_MAIL_LOG', 1 );
to your civicrm.settings.php file. In this case all mail is logged under files/civicrm/mail/upload instead of being sent to the actual recipient

Signing out students from Extended Care

Another feature that was requested was a daily sign out sheet for the students. The person picking up the student enters their name and the names of the students they are picking up. This information is used at a later stage for billing purposes. We could not do a lot of validation for the person picking up since other parents / family could pick up the student. We also wanted the process to be fairly fast and efficient. I decided to build a standalone form in the SFS name space (civicrm/sfschool). I injected this menu item into the civicrm menu using the hook_civicrm_xmlMenu. The xml file is here. The Record form is a simple CiviCRM Form (based on QuickForm) that adds the form elements. Initially i was planning on using javascript and ajax to load the students. On further thought i figured it was easier and faster to use the hierselect form element (built into quickform). The set of students is pretty small (260-280), and the hierselect implementation is fairly efficient compared to multiple ajax requests to the server. The code for the form is here. I've used a custom group with multiple values to store who picked up the student and at what time.

Issues with adding modules to extend CiviCRM

There are a few annoying things that make extending CiviCRM programmatically a bit more difficult than it should be:
  • We should have a hook_civicrm_Config to allow modules to extend the include path and template path programmatically rather than having to do it via the UI. This means one less setting via the UI for the admin/user and also allows different modules to have different paths. I plan on adding this for CiviCRM v3.0.x.
  • We should allow the advanced user to control the table name / column name of the custom tables created (for custom groups). This will enable us to have queries with easily remembered names (like name, start_date, has_cancelled) rather than (name_3, start_date_7, has_cancelled_13). Our current scheme is cool in the sense that it avoids duplicates, but makes it a pain to write queries for custom modules.
  • The migrate scripts are great and work really well for custom / profile information. Would be good to extend the migration script to other types of data (relationship types, activity types etc). Would be really nice to have an incremental script that migrates only certain custom groups / fields etc rather than the entire set.

Next Steps

We are currently working on Reports for the above features. I'll describe those in the next blog post. I'd also like to get started on keeping the Student Directory online and generating a PDF version from the online data (hence allowing parents to edit the data when needed etc). At a later stage we'll start to invoice parents for extended care based on the data in the system.
Filed under