CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Support »
  • Using CiviCRM »
  • Using Core CiviCRM Functions (Moderator: Yashodha Chaku) »
  • checkbox field query
Pages: [1] 2

Author Topic: checkbox field query  (Read 2976 times)

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
checkbox field query
March 25, 2012, 04:43:09 pm
I have several custom checkbox fields defined in my database; of course, since one or more value can be checked, the field can have none, one, or more than one value (up to the limit of how many available choices there are for the field).

What I would like to be able to do, but can't quite figure out how to do so using Search Builder, is define smart groups whose criterion are something like "where field X has 1 or more values," "where field X has 2 or more values," "where field X has 3 or more values," etc.  For purposes of these particular queries, the field value themselves are not important.

Any ideas?

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: checkbox field query
March 25, 2012, 05:13:12 pm

Pretty sure u'll need to write a custom search for doing what u need

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
March 25, 2012, 07:21:21 pm
Hmm.

What's the actual internal format of a CiviCRM checkbox field?  Is it
a) "token [delimiter token]*" or
b) "delimiter token [delimiter token]* delimiter"   
(i.e. if a field has N boxes checked, does the field contain N tokens and N-1 delimiters, or N+1 delimiters and N tokens)?

Reason I ask is, I found the following suggestion for counting the number of words a given SQL Server string contains:

Quote
Assuming that the space character separates each word, counting the number of words in a string can be performed using the following query on the given definition of a Health Insurance:

DECLARE @String VARCHAR(4000)
SET @String = 'Health Insurance is an insurance against expenses incurred through illness of the insured.'

SELECT LEN(@String) - LEN(REPLACE(@String, ' ', '')) + 1

A technique similar to this might work for my purposes, if the actual internal format of a checkbox field is as in (a) above -- but I would also need to know what separator character is used by CiviCRM.  Of course, if the actual internal format of a checkbox field is as in (b) above, then I would need to subtract 1 instead of add 1.

Of course, I am still faced with never having written a custom CiviCRM search (i.e. I do not have a working example to go by).  All I know is the name of the MySQL table that contains my checkbox field, and of course the name of the particular checkbox field in question. 

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: checkbox field query
March 25, 2012, 08:53:48 pm

we use technique b. the delimiter is CTRL-A (or octal 001)

writing a custom search is documented here:

http://wiki.civicrm.org/confluence/display/CRMDOC41/Creating+A+Custom+Search+Extension

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
April 23, 2012, 11:05:35 pm
Well, instead of having to select on something like:
   LEN(@String) - LEN(REPLACE(@String, ' ', '')) + 1

via phpMyAdmin I was able to determine that I really only need to do the following:
   where LENGTH(`fieldName`) >= N
for only a few different values of N

Unfortunately, my knowledge of PHP is too limited to be able to make much sense out of the "Creating A Custom Search Extension" link :-(

I just want to select Individual (i.e. as opposed to Household/Organization/Activity) records; at one point I was hoping that a "quick and dirty" solution would be to formulate a query (e.g. "where `fieldName` IS NOT NULL"), save it as a new smart group, and just edit the where_clause of the corresponding civicrm_saved_search to replace the "where `fieldName` IS NOT NULL" with "where LENGTH(`fieldName`) >= N". 

Yes, I know that's probably not supported... but is there any reason this approach would not work?  are there any other "interconnects" that I would have to edit?

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
April 24, 2012, 09:32:27 pm
> are there any other "interconnects" that I would have to edit?

Apprently, the civicrm_mapping and civicrm_mapping_field tables (for starters). 

> is there any reason this approach would not work?

I can't see how (or even where) to specify SQL's LENGTH function in the civicrm_mapping_field table.



I know how to use Search Builder to create a query to include contacts where
<Individual>  <CustomDataSetTableName.CustomFieldName> <operator> <value>
but I can't figure out how to hardcode this same search criterion in a custom query.

If someone could post here the script file(s) that would accomplish that, I could then at least see where I'd have to change the SQL from
<Individual>  <CustomDataSetTableName.CustomFieldName> <operator> <value>
to
<Individual> LENGTH(<CustomDataSetTableName.CustomFieldName>) <operator> <value>
so as to match what I was able to determine using phpMyAdmin... and of course I would be eternally grateful :-)

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: checkbox field query
April 25, 2012, 08:41:25 am

hey erich:

do u wanna get on irc and discuss this. Not sure i follow what u r trying to do etc.

The mapping field basically stores the user input in a structured manner and not a lot of the query stuff, which is dynamically generated by CRM/Contact/BAO/Query.php

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
April 25, 2012, 09:34:17 am
> The mapping field basically stores the user input in a structured manner ...

Well, that probably explains why I couldn't figure out how the query itself was being generated!

> Not sure i follow what u r trying to do

I want to create a number of Smart Groups (since I know how to do that -- but custom queries, if they are my only option, will have to suffice I suppose) where the membership criterion in the group is not the usual:

field operator value (e.g. "field > 3")

but:

LENGTH(field) operator value (e.g. "LENGTH(field) > 3")

In my particular case, the field in question is not one of the standard CiviCRM fields for an Individual, it's a custom field in a custom data set... so the field identifier has to be prefixed with the table name of the custom data set.  I know this from having run some queries directly to the database using phpMyAdmin.

Using the CiviCRM Search Builder, I can specify the record type (Individual, Household, Organization, Activity, etc... I want Individual), the field (via the dropdown menu that appears once I select Individual as the record type), the operator (=, !=, >, <, etc. -- this appears to be an enumeration), and the value.  I cannot specify any string functions (in particular, LENGTH)!

I'm somewhat familiar with simple SQL syntax, and barely familiar with PHP; if a "quick and dirty" way to get the result I want is to use Search Builder to specify something like "field > 3" and then use phpMyAdmin to edit the corresponding CiviCRM tables to change "field" to "LENGTH(field)" that would work for me... since I am not interested in changing the fields that show up in the resulting output. 
« Last Edit: April 25, 2012, 07:16:04 pm by Erich »

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
April 27, 2012, 07:51:15 pm
>> Not sure i follow what u r trying to do

> Smart Group (or other) query where the results of interest are those records where:
> LENGTH(field) operator value (e.g. "LENGTH(field) > 3")

Does this sufficiently describe what I am trying to do?  Or do you need more info?

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
May 07, 2012, 08:53:59 pm
Quote from: Erich on April 25, 2012, 09:34:17 am
I'm somewhat familiar with simple SQL syntax, and barely familiar with PHP; if a "quick and dirty" way to get the result I want is to use Search Builder to specify something like "field > 3" and then use phpMyAdmin to edit the corresponding CiviCRM tables to change "field" to "LENGTH(field)" that would work for me... since I am not interested in changing the fields that show up in the resulting output.

Looking at the civicrm_group table for the last query I added, I see that the select_tables field is:

a:12:{s:15:"civicrm_contact";i:1;s:15:"civicrm_address";i:1;s:22:"civicrm_state_province";i:1;s:15:"civicrm_country";i:1;s:13:"civicrm_email";i:1;s:13:"civicrm_phone";i:1;s:10:"civicrm_im";i:1;s:19:"civicrm_worldregion";i:1;s:33:"`civicrm_group_contact_cache_100`";s:136:" LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_100` ON contact_a.id = `civicrm_group_contact_cache_100`.contact_id ";s:6:"gender";i:1;s:17:"individual_prefix";i:1;s:17:"individual_suffix";i:1;}

and the where_tables field is:

a:2:{s:15:"civicrm_contact";i:1;s:33:"`civicrm_group_contact_cache_100`";s:136:" LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_100` ON contact_a.id = `civicrm_group_contact_cache_100`.contact_id ";}

Unfortunately, I don't know what a:12 and s:15 and i:1 or any of the "letter:number"  combinations refer to... so I don't know how to decode this.

The corresponding entry in the civicrm_mapping_field table:
id=511
mapping_id=76
name=custom_50
grouping=1
operator >
value 6

The form_values field in the corresponding entry in the civicrm_saved_search table is:

a:8:{s:5:"qfKey";s:37:"7fb7052ace254c3dd14ab421ae7fb4bd_9219";s:6:"mapper";a:2:{i:1;a:1:{i:0;a:2:{i:0;s:10:"Individual";i:1;s:9:"custom_50";}}i:2;a:1:{i:0;a:1:{i:0;s:0:"";}}}s:8:"operator";a:2:{i:1;a:1:{i:0;s:1:">";}i:2;a:1:{i:0;s:0:"";}}s:5:"value";a:2:{i:1;a:1:{i:0;s:4:"6";}i:2;a:1:{i:0;s:0:"";}}s:4:"task";s:2:"13";s:8:"radio_ts";s:6:"ts_all";s:11:"uf_group_id";s:0:"";s:14:"component_mode";i:1;}

I was hoping that I would see something obvious, where I could try changing (for example) some substring xyz in the above to "LENGTH(xyz)" but I don't know where to begin and where to end.  The only thing I see that I recognize is "operator", the ">", "value", and "6"

What do the a's, i's, and s's refer to?  I'm going to guess that they refer to tables, and the numbers refer to column id's in those tables... but I'm not sure.  The particular custom field whose length I am interested in is #13 in its corresponding custom data set table name... but I don't see any 13's in the above form_values field.

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
May 14, 2012, 02:36:46 pm
Anyone?

First I was told that I would need to write a custom search.  Then I was told that queries are dynamically generated by CRM/Contact/BAO/Query.php (recall that I only want to change the search criteria to use the SQL LENGTH() function, I don't want to change what fields are displayed in the report output or anything like that).

Basically, I just want to create a set of queries where the results are those records in my database where:
"LENGTH(custom_data_set.custom_field) operator value" (e.g. "LENGTH(custom_data_set.custom_field) > 3")

The example at http://wiki.civicrm.org/confluence/display/CRMDOC41/Creating+A+Custom+Search+Extension describes how to retrieve a specific field for individual contacts, which is not what I want to do.  I want to retrieve individual contacts based on the length of a specific field (i.e. not the value of a specific field, which is all that the Query Builder allows me to do)

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: checkbox field query
May 14, 2012, 08:11:25 pm

I think writing a custom search is still the easiest / fastest way out. The custom search is basically a SQL query, what is in that query and what is returned depends on what you want. You should adapt the sql in the example to meet your specific needs

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
June 11, 2012, 10:11:46 pm
> You should adapt the sql in the example to meet your specific needs

What I want is a set of queries that returns Name/Address/City/State/Postal/Country/Email/Phone (i.e. the same columns as all the other CiviCRM searches) for all contacts where the search criteria is simply:
   LENGTH(`civicrm_value_custom_group_1.column_name`) >= N
for different values of N.  Basically, N=3 for query1, N=6 for query2, N=9 for query3, and so on. 

As I understand custom queries, I'll eventually need separate files for query1, query2, query3, etc.  Fair enough.

I specified a Custom PHP Path Directory via CiviCRM » Administer CiviCRM » Global Settings, and I created a CRM/Contact/Form/Search/Custom directory below that.

I looked at all the php files in administrator/components/com_civicrm/civicrm/CRM/Contact/Form/Search/Custom and it appeared to me that the Basic.php file was the only one that had the right set of fields in the __construct function.  So, I copied Basic.php to my newly-created <Custom_PHP_Path_Directory>/CRM/Contact/Form/Search/Custom under a new name, and updated the class definition in the copied file.  So far, so good. 

Since I have no need to edit my search criteria for this particular set of queries, I tried completely deleting the buildForm function in my copied file, but I got the following error message:

Fatal error: Class CRM_Contact_Form_Search_Custom_1R contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (CRM_Contact_Form_Search_Interface::buildForm) in <Custom_PHP_Path_Directory>/CRM/Contact/Form/Search/Custom/1R.php on line 132

So, I added back a buildForm function that is just:

    function buildForm( &$form ) {
    }

and now get just a "Search" button in my Edit Search Criteria section.  Not ideal, but at least I know I'm invoking my custom query script.

Finally, using the "Creating a Custom Search Extension" example as a guide, I added my required selection criteria as follows:

    function where( $includeContactIDs = false ) {
        $clauses = array( );
        $clauses[] = "LENGTH(`civicrm_value_custom_group_1.column_name`) >= 3";


        if ( $whereClause = $this->_query->whereClause( ) ) {
            return $whereClause;
        }
        return ' (1) ' ;
    }

But I'm clearly missing something, as all rows in my database are being returned, and not just the rows that meet the selection criteria.

What am I missing in my where function?  And how do I completely remove the need for the buildForm function (i.e. when I select my custom search from CiviCRM » Find Contacts » Custom Searches, I want to go straight to the results)?  Finally, I noticed that the "Actions" column heading is missing from above the column with the View/Edit/Map links... how do I add it back?

Erich

  • I post occasionally
  • **
  • Posts: 84
  • Karma: 1
Re: checkbox field query
June 13, 2012, 09:59:27 pm
Well, I had better luck when using PostalMailing.php (instead of Basic.php) as my starting point.  I was able to get my query to work, and I was even able to add and delete columns in the search results!

However, as I mentioned in my previous post, I would still like to completely get rid of the need for the buildForm function (i.e. when I select my custom search from CiviCRM » Find Contacts » Custom Searches, I want to go straight to the results), as I have no need to edit the search criteria for my custom queries.

When I comment the buildForm function out, I get:

Fatal error: Class CRM_Contact_Form_Search_Custom_Test1 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (CRM_Contact_Form_Search_Interface::buildForm) in <Custom_PHP_Path_Directory>/CRM/Contact/Form/Search/Custom/Test1.php on line 105

I made minimal changes to the PostalMailing.php script to get my custom query, but since the above message is quite meaningless to me, the only way I could get rid of it is by changing the buildForm function so that it reads as follows:
    function buildForm( &$form ) {
    }

Unfortunately, this results in an "Edit Search Criteria" window with nothing in it except *two* search buttons -- instead of the one search button I got when I did the same thing using Basic.php as my starting point.

Any ideas?

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: checkbox field query
June 14, 2012, 07:59:11 am

just append the parameter force=1 to the url.

something like:

http://drupal.demo.civicrm.org/civicrm/contact/search/custom?csid=5&reset=1&force=1

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Pages: [1] 2
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Support »
  • Using CiviCRM »
  • Using Core CiviCRM Functions (Moderator: Yashodha Chaku) »
  • checkbox field query

This forum was archived on 2017-11-26.