Neil,<br><br>It is clear you like vtiger, I have one question, what made your company choose Sugar instead of vtiger?, so sooner someone can make vtiger offer such things.<br><br>Regards,<br><br>Jorge<br><br><div><span class="gmail_quote">
On 6/10/07, <b class="gmail_sendername">Neil Temperley</b> &lt;<a href="mailto:neil.temperley@exemail.com.au">neil.temperley@exemail.com.au</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Dear Developers,<br><br>In the end my company went with Sugar, but I still keep an eye on vtiger<br>because I love you guys :-).<br><br>Anyway here is an idea that I will post on a Sugar forum, but I&#39;d thought<br>I&#39;d post it here first so that if you choose to adopt it you can&#39;t be
<br>accused of copying :-).&nbsp;&nbsp;While I haven&#39;t checked the vtiger code for a while<br>I suspect this issue is applicable to you too.<br><br>-----------------------------------<br><br>Storage of Multi-Select Items for Quicker MYSQL Searching
<br><br>Consider a custom multi-select field with items:<br>cat<br>dog<br>horse<br>bobcat<br>cattle<br><br>An example of a selection of the above is stored in the database as a string<br>like this (ignore the &quot;&quot;):
<br>&quot;cat#,#horse#,#bobcat#,#cattle&quot;<br><br>And if &quot;cat&quot; is the only item the string saved looks like:<br>&quot;cat&quot;<br><br>This storage scheme has some problems when it comes to doing an SQL searches
<br>on strings formatted this way.&nbsp;&nbsp;To search for uniquely for &quot;cat&quot; we have to<br>search for four different possibilities: (The MYSQL search string is shown<br>in &quot;&quot;):<br><br>1) cat at the beginning of the multi-select database string, &quot;cat#%&quot;,
<br>2) cat in the middle, &quot;%#cat#%&quot;,<br>3) cat at the end, &quot;%#cat&quot;, and finally,<br>4) cat by itself, &quot;cat&quot;.<br><br>If there are 1000 records and none have &quot;cat&quot; selected, the search needs to
<br>check all four conditions on each record before rejecting each as &#39;not<br>matching&#39;.<br><br>However if we choose to store the selection differently we only need to<br>search for one match not four matches per record.
<br><br>Choosing &#39;#&#39; as the bounding character, we store the multi-selected items as<br>a string like this instead (ignore the &quot;&quot;):<br>&quot;#cat##horse##bobcat##cattle#&quot;<br><br>And if &quot;cat&quot; is the only item the string saved looks like:
<br>&quot;#cat#&quot;<br><br>The advantages of this system are:<br><br>* Now the one MYSQL search &quot;%#cat#%&quot; will match &quot;cat&quot; regardless of where it<br>is in the string or whether it is the only item.<br>
<br>* A side benefit is that is possible to delete (or replace) the &quot;cat&quot; item<br>using a simple PHP string operation, e.g.<br>str_replace( &quot;#cat#&quot;, &quot;&quot;, &quot;#cat##horse##bobcat##cattle#&quot; );
<br><br>* Also MYSQL searches are simpler -- if/when you ever need to do a search<br>using a database admin tool.<br><br>Note that to search for &#39;no selection&#39; you need to check for ## or an empty<br>string.<br><br>
I suggest the best way to implement the change is with dedicated explode()<br>and implode() functions and using a minimum of hardwired strings.&nbsp;&nbsp;Examples<br>are given below.<br><br>that&#39;s all,<br>regards and good luck,
<br>Neil<br><br><br>Sample Code...<br><br>/* ########################################################## */<br>define(&quot;MULTIPLE_SELECT_BOUNDING_CHAR&quot;, &#39;#&#39;);<br>define(&quot;MULTIPLE_SELECT_BOUNDING_CHAR_RE&quot;, &#39;\#&#39;); // Char for regexps.
<br><br>/**<br> * Formats a string of multi-select items for saving to a database.<br> *<br> * @param array $multiple_select_array<br> * @return string formatted multi-select string<br> *<br> */<br>function MultipleSelectImplode( $multiple_select_array ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;$bounding_char = MULTIPLE_SELECT_BOUNDING_CHAR;<br>&nbsp;&nbsp;&nbsp;&nbsp;return $bounding_char . implode(&quot;$bounding_char$bounding_char&quot;,<br>$multiple_select_array) . $bounding_char;<br>}<br><br>/**<br> * Splits a formatted string of multi-select items into an
<br> array. Returns an empty array if there are no multi-select items.<br> *<br> * @param string $multiple_select_string<br> * @return array multi-select array<br> *<br> */<br>function MultipleSelectExplode( $multiple_select_string ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;$bounding_char&nbsp;&nbsp;&nbsp;&nbsp;= MULTIPLE_SELECT_BOUNDING_CHAR;<br>&nbsp;&nbsp;&nbsp;&nbsp;$bounding_char_re = MULTIPLE_SELECT_BOUNDING_CHAR_RE; // Char for<br>regexps<br>&nbsp;&nbsp;&nbsp;&nbsp;// Remove $bounding_char at each&nbsp;&nbsp;end of the string:<br>&nbsp;&nbsp;&nbsp;&nbsp;$trimmed_string = preg_replace( array(&quot;/^\s*$bounding_char_re/&quot;,
<br>&quot;/$bounding_char_re\s*$/&quot;), &#39;&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$multiple_select_string );<br>&nbsp;&nbsp;&nbsp;&nbsp;if ( empty($trimmed_string) ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// (An explode() here would return a one element array with empty
<br>element):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return array();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;return explode(&quot;$bounding_char$bounding_char&quot;, $trimmed_string);<br>}<br>/* ########################################################## */<br><br>_______________________________________________
<br>Reach hundreds of potential candidates - <a href="http://jobs.vtiger.com">http://jobs.vtiger.com</a><br></blockquote></div><br>