
Developer
Wikimedia Foundation
Civi is one of those pieces of software that makes you wonder how early humans could have survived without it. Every nonprofit seems to be using Civi for some aspect of their fundraising, and I'm always surprised at the creative ways different people find to make it work for their needs. Happy to be able to help out a bit. There's a lot of energy going into this project--definitely checkout the forums and the IRC channel if you're curious.


Administrator, Implementor
Professional Exchange Service Corporation
PESC uses CiviCRM as pillar in maintaining many nonprofits throughout California and Nevada.


Developer


Integrator
l'AtelierWeb.Org
I chose to learn to use CiviCRM to learn how to help NPOs :) And because it seems to be a meeting point and a continuity of my values, my skills, and what I think we should develop for the next step of our humanity.


Implementor, Administrator, end-user, Trainer
MC3
I've been working with CiviCRM since 2006 or thereabouts. The community is outstanding in providing support and sharing expertise, which combines with a strong product to enable me in turn to deliver better results for the organisations that I work with. I only hope that over time I will be able to repay the debt by supporting other newcomers to CiviCRM.


Administrator
Concordia Welfare & Education Foundation
CWEF is deploying CiviCRM on Wordpress to build and manage a database of our staff, volunteer, recipient, donor and partner contacts.

Consultant
nfpservices
We use CiviCRM for our own business functions. Nfpservices participate in the development of CiviCRM and contribute enhanced functionality to the community.


Developer and Implementor
Tech to the People
Over the past 15 years I've been involved in several open source communities.
CiviCRM is without any doubt the one that has the strongest focus in welcoming "newbies" and letting everyone feel at home here. Another impressive feature is the focus on shipping. No matter what you think of CiviCRM today, you are almost sure that there will be a newer and better version in a few months.


Developer, Implementor
Réseau Koumbit
As non-profit consultants working for non-profit organizations, we found CiviCRM to be particularly well suited to answer the common needs of activist associations, charities and other medium-sized groups. Based in Montréal, we've helped local and international organizations migrate to CiviCRM to manage their memberships, events, communications and fundraising campaigns. We empower our clients and assist them when they need us.


Implementor
Ginkgo Street Labs
CiviCRM enables me to empower my clients with a database that suits their unique needs.


Implementor, Developer
Skvare, LLC
Helping non-profits, membership organizations, and professional associations to make the most out of their resources with open-source tools.


Implementor, Developer
Third Sector Design
Being part of the CiviCRM community is really something to shout about! Not only is CiviCRM an amazing software package, its designed for organisations that make a difference in the world. We help non-profits across the UK gain control of their data through the power of CiviCRM.
It is without a doubt the best piece of software I've ever worked with, and I'm constantly discovering cool new features. More recently I've been working on CiviMobile as part of a project for my course at University. I'm really looking forward to seeing this being used by organisations across the globe.


Comments
Thanks for sharing
Reallly nice examples,
If you have already custom token in 3.4 or 4.0, I would encourage of all you to modify them to benefit from that extra param $tokens to skip fetching a lot of informations for a token that isn't use.
The $cids param might be an array or a single id, isn't it? Or has it changed since 4.0?
$cids is always an array
As of 4.1. No more writing two versions of the same thing. Hooray!
Where goes it?
Thanks much for this writeup, the stuff on donor thank-you letters is spot on for what I need. One question though, if we want to implement custom hooks & tokens, where do we stick the code? Some directory somewhere?
Adding custom code
Depends on your CMS. See the instructions for implementing hooks for a how-to.
If using drupal, create a "mysite" module - IMO every site should have one of these. Then just add your hooks to it. You can copy-paste the code directly from this article, just replace the word hook with mysite or whatever you decided to name your module.
Colemanw,
Colemanw,
Great examples, I'm putting them to use! I want to make some changes to the donation token.
I want to be able to do a search for all contacts that have made a donation in the last year and the token cycle through those contacts instead of only the ones that don't have a thank you sent.
if (in_array('unthanked', $tokens['donor']))
{
$dao = &CRM_Core_DAO::executeQuery("
SELECT cc.contact_id, cc.total_amount, cc.receive_date, cc.check_number, con.display_name,
hon.display_name as honoree, pi.label AS payment_instrument, ht.label AS honor_type
FROM civicrm_contribution cc
INNER JOIN civicrm_contact con ON con.id = cc.contact_id
LEFT JOIN civicrm_contact hon ON hon.id = cc.honor_contact_id
LEFT JOIN civicrm_option_value ac ON ca.account_18 = ac.value AND ac.option_group_id = 103
LEFT JOIN civicrm_option_value pi ON cc.payment_instrument_id = pi.value AND pi.option_group_id =
(SELECT id FROM civicrm_option_group WHERE name = 'payment_instrument')
LEFT JOIN civicrm_option_value ht ON cc.honor_type_id = ht.value AND ht.option_group_id =
(SELECT id FROM civicrm_option_group WHERE name = 'honor_type')
WHERE cc.is_test = 0 AND cc.contribution_type_id = 1 OR cc.contribution_type_id = 2
OR cc.contribution_type_id = 6 AND cc.contribution_status_id = 1
AND cc.contact_id IN ($contacts_and_spouses) ORDER BY cc.receive_date");
$header = '
<table class="donations">
<thead><tr>
<th>Date</th>
<th>Donor</th>
<th>Amount</th>
<th>Paid By</th>
<th>Notes</th>
</tr></thead>
<tbody>';
while ($dao->fetch())
{
$cid = $dao->contact_id;
$row = '
<tr>
<td>' . date('m/d/Y', strtotime($dao->receive_date)) . '</td>
<td>' . $dao->display_name . '</td>
<td>$' . $dao->total_amount . '</td>
<td>' . ($dao->payment_instrument ? $dao->payment_instrument :
'In Kind') . ($dao->check_number ? ' #' . $dao->check_number : '') . '</td>
<td>' . ($dao->honoree ? "<br />{$dao->honor_type} {$dao->honoree}" :
'') . '</td>
</tr>';
if (in_array($cid, $cids))
{
$values[$cid]['donor.unthanked'] = woolman_aval($values[$cid],
'donor.unthanked', $header) . $row;
}
if (isset($spouses[$cid]))
{
$values[$spouses[$cid]]['donor.unthanked'] = woolman_aval($values[$spouses[$cid]],
'donor.unthanked', $header) . $row;
}
}
foreach ($cids as $cid)
{
if (!empty($values[$cid]['donor.unthanked']))
{
$values[$cid]['donor.unthanked'] .= '</tbody></table>';
}
}
}
hat's a portion of the code. I just want to make sure I'm doing it correctly before I run it on my db.
Basically, I removed the bit in the SQL toward the end <code>AND cc.thankyou_date IS NULL</code>
I'm not sure what the line
LEFT JOIN civicrm_option_value ac ON ca.account_18 = ac.value AND ac.option_group_id = 103 is. Could you help me out on what it is doing?
Also, I'd like to get a token called donor.totalcontributions which would total all the contributions from the result.
woolman_aval
Can you explaiin the woolman_aval function in your example? Did I miss where it was defined?
BTW, thank you for a great explanation of the token functions. It highly simplified a project that I was working on.
Hooks in Joomla
Can someone give me pointers on getting Coleman's sample code to run in Joomla. I tried it via teh plugin way as well teh civicrm.Hooks.php way. It looks like the code is totally ignored. Am I missing out a step in the implementation ?
How to add event tokens?
Thanks for the great tutorial and examples. I need to add some tokens for events. I'm confused by the function. It seems to use contact IDs ($cids) but it seems to me that I need to use event IDs. Can you provide some basic tips about setting up Event tokens?
Thanks.
Error in Code Example
Please note the code as used in the example given will not work. The in_array() test fails (at least in my code) since the values being searched for are array keys and not array values and in_array() only checks values.
The array in the example would have something like: $tokens['donor']['unthanked'] = 1 when you dump the tokens array.
This may account for others who had issues with nothing happening when a mailing was sent.
@ehlondon sorry you're having
@ehlondon sorry you're having trouble getting the code to work, but I haven't had the problem you describe. That section of the $tokens array looks like $tokens['donor'] = array('unthanked', 'set_thank_you') - perhaps you're thinking of another variable?