Adding custom CiviCRM search tasks

I needed to be able to add a new activity record to every contact in my search results.

Here's how I used a CiviCRM hook to add a function to the list of tasks you can perform on a set of search results.

Nb. CiviCRM comes with a task to add an activity to the search results, but it adds one activity record with all the contacts together in the With field. This pretty much breaks the UI when you're talking thousands of people.

Step 1: implement hook_civicrm_searchTasks()

I use Drupal, and civicrm hooks are done just like any other drupal hook. It's different if you're on Joomla/Wordpress.

So just create a drupal module (e.g. called mymod) and within the .module file create a function called mymod_civicrm_searchTasks.

You can verify that this is working by doing a search and looking in the select box for your new task. (Not there? did you enable your drupal module? did you drush cc all?)

Step 2: create a class and a template for this task

So now you need to create the file <your customisation path>/CRM/Contact/Form/Task/MyTask.php and within it, define the CRM_Contact_Form_Task_MyTask class (note the directory structure maps the class name).

Your class must extend CRM_Contact_Form_Task, which means it's also inheriting from CRM_Core_Form and HTML_QuickForm_Page.  It's all these layers of inheritance that prompted me to write this post, because documentation is split between projects (CiviCRM and Pear's HTML_QuickForm).

The template file must be in <your templates path>/CRM/Contact/Form/Task/MyTask.tpl

Step 3: Ask user for extra information required for processing

So we wanted to record which newsletter was to be sent. We'll ask the user with a text field.

To add fields to the as-yet blank form, we override the buildQuickForm() method:

This defines elements within the form, but to get these to display to the user we need to edit the template file:

Step 4: Complete the task

Once we have this information we can do the updates in the postProcess() method of our class.

You have access to the contact ids in $this->_contactIds and access to the submitted form data in the associative array returned by $this->controller->exportValues();

Something like this:


At the time of writing the hook only copes with contact search results. If, like me (different project), you need to add a task for something else (e.g. contributions), you have to patch the relevant file, e.g. CRM/Contribution/Task.php
Pull Out: 

Key CiviCRM resources


hey rich:

thx for another interesting article. I think what might be super useful would be to add a new option (checkbox?) to the current add activity to contacts to choose if we should create one activity and associate it with all contacts or create one activity per contact.

Would be great if you can submit a patch that does this :) Kinda incorporates what you've done to the core and this has been requested a few times in the past


Donald Lobo replied on

@lobo yes, that occurred to me, too! I'm doing something quite specific for a client at the mo (above is abstracted/simplified), but I would love to contribute more to CiviCRM, so if I get chance I'll do so and let you know. Thanks and Happy Christmas!

Rich replied on

Thanks for sharing this.
Is there a method that can be used to assign the created activity to more than one contact at the same time?

Nick A. replied on

@NickA: It looks from the CRM/Activity/BAO/Activity.php class that you can specify an array of values for target_contact_id. However, I haven't tested this via the API.

Rich replied on