Hello,
The answer you (hopefully 😉) need:
1. If we're talking simply about crits - it's possible. Just specify crits like
$crits = array( (...), '>=birth_date'=>'1980-01-01', (...));
If we're talking about filter for end-user it's more tricky. You'll need what I've written here, plus what I say about custom_filters at the end of this post.
2. If enabling filtering is all you want - use custom filter. Again - details at the bottom of the post. If not - remove the old field (delete_record_field()) and add new one that is based on CommonData with 'filter'=>true.
3. That's custom filter again, read on past point 4.
4. There's a module Utils/RecordBrowser/Reports but it is a bit experimental and we do not have a non-commercial module that could serve as example. It has graphs using OpenFlashChart. The format is a bit different - usually having days/weeks/months/year as table header and each row is one record for which data is displayed.
If that's the kind of thing you'd need, I can prepare short doc of that module for you - would look good on wiki too. 😉
Now, for the custom filters... good news is all you mentioned can be served using this technique.. the bad - well, you'd need to modify CRM/Contacts body method. That, or remove from CRM_ContactsCommon menu entry for contacts and add one, with proper body(), in your custom module. The latter is easier when it comes to updating epesi - you just need to remove old menu entry again.
Now for the filters itself:
Let's take a look at (surprise 😉) Projects/Tickets module. You can find there:
$sts = Utils_CommonDataCommon::get_translated_array('Premium_Ticket_Status',true);
$trans = array('__NULL__'=>array(), '__ALLACTIVE__'=>Premium_Projects_TicketsCommon::active_tickets_crits());
foreach ($sts as $k=>$v)
$trans[$k] = array('status'=>$k);
$this->rb->set_custom_filter('status',array('type'=>'select','label'=>$this->t('Ticket status'),'args'=>array('__NULL__'=>'['.$this->t('All').']','__ALLACTIVE__'=>'['.$this->t('All active').']')+$sts,'trans'=>$trans));
For the code to be more clear let me rephrase it:
$sts = Utils_CommonDataCommon::get_translated_array('Premium_Ticket_Status',true);
$options = array('__NULL__'=>'['.$this->t('All').']','__ALLACTIVE__'=>'['.$this->t('All active').']')+$sts;
$translate_to_crits = array('__NULL__'=>array(), '__ALLACTIVE__'=>array('!status'=>4));
foreach ($sts as $k=>$v)
$translate_to_crits[$k] = array('status'=>$k);
$definition = array('type'=>'select','label'=>$this->t('Ticket status'),'args'=>$options,'trans'=>$translate_to_crits);
$this->rb->set_custom_filter('status',$definition);
So, what we are doing here is custom "HTML select" filter element.
First - I define what options that select should have - in this case it's two custom values (NULL and ALLACTIVE) and all statuses taken directly from CommonData table - please be advised that default is always __NULL__, it's kinda rough atm, please forgive me that. 😉
Next we create "dictionary" - set of rules that translate selected value (key) into crits (value).
Than I put that together in one neat variable and set the custom filter.
If you want to filter by cities, you can leave them as text fields and use Utils_RecordBrowserCommon::get_possible_values($tab, $field);
For another example, see this:
$cities = Utils_RecordBrowserCommon::get_possible_values('contact', 'city');
$options = array('__NULL__'=>'---');
$trans = array('__NULL__'=>array());
asort($cities);
foreach ($cities as $city) {
$options[$city] = $city;
$trans[$city] = array('city'=>$city);
}
$definition = array('type'=>'select','label'=>$this->t('City'),'args'=>$options,'trans'=>$trans);
$this->rb->set_custom_filter('city',$definition);
For this to work thou, you have to enable filtering by city:
Utils_RecordBrowserCommon::new_filter('contact', 'City'); // watch the capital C here
Kind regards,
Arek