Friday, September 24, 2010 - 05:38
Written by

Slight change in plans - I was promising the recipe on packaging payment processors, but we'll do custom reports first. They are second in the hierarchy of complexity after custom searches, and they smoothly introduce small new concept that will be described below.


Again, you need the very custom report first - a php class, as it is handled right now. Usual custom report is made of PHP class and the template. Once we have it, we can go ahead and package it.


In order not to repeat the information which was already described on packaging custom searches, here's quick summary:

  •  prepare the info file (see the sample file at the end of this blog post). The key that we'll choose is:

  • create directory

  • Put the report PHP class file in the directory. Remember to call it the same way as the callback attribute in your info.xml, also don't forget to follow the convention in class naming ("Extension_<Type>_<key>_<callback>" - Extension_Report_org_civicrm_report_grant_Grant in this case).

  • create directory and put your report's template file there


Now, here's a promised novelty. Report needs some additional information compared to custom search and we need to define it somewhere. Therefore, we'll create another XML file called report.xml, quite simple, that will provide the extension framework with all the necessary information needed for adding it to the system. Here's how it looks like:


 <?xml version="1.0" encoding="UTF-8" ?>
  <report_template key="">


Attributes explained:

  • report_url  - the url under which this report will be server within CiviCRM. It's relative to CiviCRM's base URL.

  • component - the name of the component this report works with. Currently accepted options are: Contact, CiviEvent, CiviContribute, CiviMember, CiviMail, CiviGrant, CiviPledge, CiviCase. If unknown value is put here, "Contact" is assumed.


We should have following direcytory structure containing following files:
|-- Grant.php
|-- info.xml
|-- report_template.xml
`-- templates
    `-- Grant.tpl


Looks similar to what you have on your sandbox? Than last thing required is putting it in the archive - "zip" it and call the file after the key defined at the beginning: Congratulations, you packaged your first custom report. :-)


As always, more than glad to receive feedback in blog comments and on Extensions forum board. Coming up next, this time without change of plans, payment processor packaging.


Sample info.xml file for CUSTOM report


<?xml version="1.0" encoding="UTF-8" ?>
<extension key="" type="report">
  <name>Grant Report</name>
  <description>Grant Report allows you to see the summary of grants that
  have been admitted to your consitutents by your organisation.</description>
  <maintainer>CiviCRM Core Team &lt;;</maintainer>
  <comments>For support, please contact project team on the forums. (</comments>
Filed under



1) Class naming convention:

("Extension_<Type>_<key>_<callback>" - eg: Extension_Report_Extension_org_civicrm_report_grant_Grant 


My first reaction: beurk! Don't speak french ?



Are you really sure you need to have twice extension, twice report and twice grant in the name of that poor class ? I'd want to have at least 2 or 3 time the name of the organisation/domain name thrown in for good mesure :)

Alternatively, can't we simply use the key as class name ? A key isn't unique enough?


class org_civicrm_report_grant extends ... is much nicer looking, isn't it?

2) How to put it in the navigation menu? 
How to define where it's going to be put in the navigation ?
I'd really like to be able to add it in the navigation menu directly so after you install the package, that's ready to use.

3) <maintainer>CiviCRM Core Team &lt;;</maintainer>
Concatenating fields defies the purpose of xml and takes away one of the few things it's good for
I'd go for
<maintainer><name>CiviCRM Core Team</name><email></email></maintainer>

or if you want to keep it one level, like a regular unix config file, but without its simplicity and an extra layer of xml verbosity ;) :
<maintainer_name> ..

4) What's the point of putting an email address ? especially if noreply? that's for the example, right? You are supposed to reach the maintainer through that ?

5) I'd add a <support_url> (optional) explicitly instead of burying it in the comment

6) That's it. The next round is on me. See you in London ;)


Hi Michal,


I just had a couple of thoughts on payment processors because I have been looking at them again. Mostly I'm just wondering whether existing payment processors with code sitting in custom_php override directories will continue to function without hitch. I know quite a few organisations out there are using payment processors which are not in core in this way.

Also, will some still be in core (Paypal?) and will it still use the same extern directory? I'm assuming the new ones will not be using that directory for the IPN files