SugarCRM Developer Blog

New for Sugar 6.5 – Stronger password storage encryption

16 May, 2012
Posted By: John Mertic

Sugar uses MD5 encryption for storing password data in the backend database. This works fairly well, as MD5 is a well understood algorithm and is implemented in just about every programming language, as well as on the database side as well. There’s just one issue, MD5 isn’t the most secure algorithm out there.

So starting with Sugar 6.5, we are using PHP crypt on top of this to store each password as a hashed string. This provides greater security for the passwords stored in the database. It also brings up some questions on administration, so here’s the most common ones and the answers to them…

How do I move over from MD5 password storage to the new crypted storage?

This will happen transparently when you a user’s password is changed, and is not done during the upgrade process. If you want to move over all of your passwords to the new crypt storage, the best bet is to use the password management feature to expire everyone’s password after a period of time, which will force them to change their password and move to the new crypt storage

Can I still use MD5 passwords? I’m used to that and can easily administer passwords in the database using just MD5.

Sugar will still recognize passwords stored in MD5 format, but anytime a password is changed it will convert to the newer format. Unless very old PHP build (5.2) used in a system where better
crypt() is not available, new password will use salted hashing algorithm.

How will I know a user has converted over to the new crypted passwords?

Crypted passwords will be stored in the database prefixed by a dollar sign ($)

Can I update the passwords to store them in a new format outside of Sugar?

Yes, you can use the same method we do for this:


crypt(md5("newpassword"))

There are similar libraries available for other languages as well, such as passlib for Python, which should work as well.

HOWTO: Drop a ListView in anywhere with the ListViewFacade

15 May, 2012
Posted By: John Mertic

I’ve come across requests every so often to embed a ListView into a view you are building. This is actually quite simple to do, thanks to the ListViewFacade class. This class provides a unified interface to getting a ListView, whether the module is using the current Smarty based ListViews or the older XTemplate based ones.

Check out the below code snippet, which will drop the Accounts ListView on any view form. It supports pagination as well as re-ordering like a normal ListView does.

New for Sugar 6.5: In with jQuery, and the beginning of the move away from YUI

14 May, 2012
Posted By: John Mertic

Sugar 6.5 begins another component change for the platform, which is to include jQuery 1.6.4 as a core component going forward. Over time, we will be using jQuery to replace the usage of YUI thoughout the product; the goal is to initially replace YUI 3, and then longer term to replace the use of YUI 2. Many of the developers across our partner and open source developer community are big fans of jQuery, as are we, and we hope the move to jQuery will make working with JS much easier in the product going forward. This will also enable us to make great strides in the UX and UI of the app as a whole over the next year.

With jQuery, comes a bunch of new functionality in the ease of dealing with HTTP requests and script loading. One such example is getting around problems loading scripts with the AJAX UI, as referenced in this blog post:

I add a javascript file to editview

<script type=”text/javascript” src=”custom/modules/zz_css_job/zz_css_job.js?time=1335195528″></script>

this worked fine in 5.5 and works in 6.4 if the ajaxui is disabled

but if I use it with the ajaxui I get all sorts of JavaScript issues

any ideas how I can get round this without disable the ajaxui?

While one way is to leverage metadata to load in the javascript components, another simplier way is to use

jQuery has a nice function called $.getScript(), which will load a script and then execute a piece of code once it’s loaded. This enables adding simple widgets in HTML fields for the various views, such as the DetailView. A great example one is the widget provided by the joind.in project, which is a site for managing conference and speaker feedback for events. They have a simple widget for showing the ratings for a talk which is a simple JS piece of code, which with a small bit of refactoring will drop right into a Sugar HTML with the following code segment ( assume the widget field name is joindin_widget and the talk id is in the joindin_id field )

Hopefully the use of jQuery will make developing Sugar customizations and add-ons much easier for our developer community going forward.

New for Sugar 6.5: SugarHttpClient

11 May, 2012
Posted By: John Mertic

One of the biggest complaints I’ve heard recently is around the changes made to the Module Scanner in the product, which is strictly enforced in our On-Demand environment, namely about the inability to use curl or file_get_contents() directly to do outbound web service calls. For example, check out this example of making an outbound call from PHP to the Sugar Web Services API using curl:

Not only are there potential issues with curl usage on OD, but there’s a lot of code to make this happen. Pretty inefficient…

Now in Sugar 6.5, we’ve helped out developers out by adding the SugarHttpClient object, which is a simple way to make POST HTTP calls in Sugar without having to get down in the weeds with curl or file_get_contents(). Check out the above example re-written to use this instead:

You can see the code is now much cleaner, without all the bits around curl out of the picture.

We recommend that if you are doing any simple outbound web service calls in your customizations, you should use SugarHttpClient in Sugar 6.5 versus curl or file_get_contents() directly to avoid Module Loader restrictions. If you have more in-depth requirements such as needing to pass OAuth tokens, then building a Sugar Connector and leveraging the External API will add the additional features such as a user configuration UI that you’ll want to use.

Longer SugarCRM Sessions

10 May, 2012
Posted By: Matthew Poer
In most server-setups, we find that the SugarCRM Session only lasts about half an hour. This is something I’ve gotten complaints about — users wanting longer sessions to ease the work day. I had spent time looking through the session-management code to find an answer and just wasn’t getting anywhere. I back-burned it until I stumbled on the solution today: SugarCRM sets session length according to a PHP configuration variable. As it often does, the SugarCRM Forums held the question and answer. In extending the 30 minutes session timeout forum user Duzoid posts the question and it is eventually correctly answered by user Sunside. The solution is to modify the PHP configuration variable session.gc_maxlifetime. Sunside suggests placing the changed configuration in an .htaccess file due to accessibility and hosting environment limitations, but having access to my core php.ini I went ahead and changed our local Sugar instance globally.
If it is allowed on your host, then you may very well change this in the .htaccess file: php_value session.gc_maxlifetime 14400 This should set the session lifetime to 4 hours. Please note that if session files are shared between different scripts in different directories on your server, then you need to make this setting in each of the script directories’ .htaccess file. That is because other scripts may erase your Sugar session files if they have a shorter session lifetime. You could also create a separate directory for Sugar session files and set this with php_value session.save_path /my/new/sugarsessiondir in the .htaccess that you put in your Sugar root directory. You should NOT create this directory anywhere under your htdocs, but further up in the directory structure, so that these files cannot be accessed by the webserver for security reasons. The preferred way of setting the garbage collector’s maxlifetime would be to do it serverwide in the php.ini, but this may not be possible in some shared hosting environments.

Next week’s community webinar will showcase Starfish ETL

09 May, 2012
Posted By: John Mertic

If there’s one thing that’s crucial to moving to a new CRM solution, it’s bringing in your data. While Sugar out of the box has some simple tools for doing this, anyone doing a large scale data migration knows that you need a dedicated tool to handle this. Starfish ETL™ is a premiere import/export tool with extreme flexibility, power and speed. Starfish ETL™ can connect your SugarCRM database with nearly any data source imaginable.

Looking to learn more about it? Then join us on May 16th at 11:00am US Eastern Time at https://sugarcrm.webex.com/sugarcrm/j.php?ED=152787562&UID=492952802&RT=MiMxMQ%3D%3D.

HOWTO: Add more info hover links to any record link in a subpanel

08 May, 2012
Posted By: John Mertic

In a follow-up to an earlier blog post, Sugar Professional customer and avid community member Blake Robertson asked this question:

I think most people would prefer to have it so when you hover over the link field it displayed more info.  Thoughts on extending SubPanelDetailViewLink widget to handle on hover events?

This actually pretty easy; you just need to add a new widget that extends from the existing one in the custom/include/generic/SugarWidgets/ directory. So for this example, let’s add a new widget named  SubPanelDetailViewLinkHover, which will build from the SubPanelDetailViewLink widget and be defined in the SugarWidgetSubPanelDetailViewLinkHover.php file as shown below:

require_once("include/generic/SugarWidgets/SugarWidgetSubPanelDetailViewLink.php");

class SugarWidgetSubPanelDetailViewLinkHover extends SugarWidgetSubPanelDetailViewLink
{
	function displayList(&$layout_def)
	{
		global $focus;

		$module = '';
		$record = '';

		if(isset($layout_def['varname']))
		{
			$key = strtoupper($layout_def['varname']);
		}
		else
		{
			$key = $this->_get_column_alias($layout_def);
			$key = strtoupper($key);
		}
		if (empty($layout_def['fields'][$key])) {
			return "";
		} else {
			$value = $layout_def['fields'][$key];
		}

		if(empty($layout_def['target_record_key']))
		{
			$record = $layout_def['fields']['ID'];
		}
		else
		{
			$record_key = strtoupper($layout_def['target_record_key']);
			$record = $layout_def['fields'][$record_key];
		}

		if(!empty($layout_def['target_module_key'])) {
			if (!empty($layout_def['fields'][strtoupper($layout_def['target_module_key'])])) {
				$module=$layout_def['fields'][strtoupper($layout_def['target_module_key'])];
			}
		}

        if (empty($module)) {
			if(empty($layout_def['target_module']))
			{
				$module = $layout_def['module'];
			}
		else
			{
				$module = $layout_def['target_module'];
			}
		}

        //links to email module now need additional information.
        //this is to resolve the information about the target of the emails. necessitated by feature that allow
        //only on email record for the whole campaign.
        $parent='';
        if (!empty($layout_def['parent_info'])) {
			if (!empty($focus)){
	            $parent="&parent_id=".$focus->id;
	            $parent.="&parent_module=".$focus->module_dir;
			}
        } else {
            if(!empty($layout_def['parent_id'])) {
                if (isset($layout_def['fields'][strtoupper($layout_def['parent_id'])])) {
                    $parent.="&parent_id=".$layout_def['fields'][strtoupper($layout_def['parent_id'])];
                }
            }
            if(!empty($layout_def['parent_module'])) {
                if (isset($layout_def['fields'][strtoupper($layout_def['parent_module'])])) {
                    $parent.="&parent_module=".$layout_def['fields'][strtoupper($layout_def['parent_module'])];
                }
            }
        }

		$action = 'DetailView';
		$value = $layout_def['fields'][$key];
		global $current_user;
		if(  !empty($record) &&
			($layout_def['DetailView'] && !$layout_def['owner_module']
			||  $layout_def['DetailView'] && !ACLController::moduleSupportsACL($layout_def['owner_module'])
			|| ACLController::checkAccess($layout_def['owner_module'], 'view', $layout_def['owner_id'] == $current_user->id)))
        {
            $linkIdTag = 'aip_' . $record;
            $mouseEvents = ' id="' . $linkIdTag . '" onmouseover="javascript:SUGAR.util.getAdditionalDetails(\'' . $module . '\',\'' . $record . '\',\'' . $linkIdTag . '\');" onmouseout="javascript:cClick(); SUGAR.util.clearAdditionalDetailsCall();"';
            $link = ajaxLink("index.php?module=$module&action=$action&record={$record}{$parent}");
            return '<a href="' . $link .'"' . $mouseEvents .' >'."$value</a>";
		}else{
			return $value;
		}
	}
}

With the field defined, you can enable this for any listview field by changing the ‘widget_class’ attribute from ‘SubPanelDetailViewLink’ to ‘SubPanelDetailViewLinkHover’ and the link will now show the more info popup when you hover over the link.

SugarCRM Code Search Engine

07 May, 2012
Posted By: eric

Often times you need to find a specific chunk of code in SugarCRM’s code base.  Traditionally, developers will result to using grep or maybe their IDE to try to track down whatever they are searching on.  However, this process tends to be slow; it can take several minutes for grep to search through all of the code.

Epicom has recently launched a search engine that returns results almost immediately.  Most searches come back in less than 5ms.  You can now quickly run a search across many versions of Sugar simultaneously to track down what you are looking for.  Once you get the result back you can then filter down the results to only a certain version of Sugar or to a particular file type (like php, tpl, css or js).

The initial results page displays both the filename as well as all of the lines that contain your initial search phrase, highlighting the actual search term.

If you click on the filename, you are redirected to the full source code for that page which will highlight both the lines that contain your results as well as the actual phrase.


Not only are you able to quickly search and find all references to a certain function, you can also use the search engine to search trends in the Sugar code base.  Here are some example cases:

  • curious how many references to jquery there are in different versions? (hint – 6.5 has significantly more references than any previous version)
  • how often does Sugar use heredoc? (they’ve been steadily removing heredoc references since Sugar 4.5.1, but they just started using EOT (compared to EOQ from before) on sugar 6.5)
  • how often do they use print_r? (that has slowly been on the rise, but probably growing much slower than the overall codebase)

We hope you find this as a useful tool that will save you time when looking for functions and related code in your SugarCRM code base.  

http://codesearch.epicom.com/

New for Sugar 6.5 – Enhanced Formula Builder

04 May, 2012
Posted By: John Mertic

For those of you who are developers by trade ( like myself ), you enjoy the features of your favorite IDE to make development easier. And when we looked at Formula Builder, we saw the same thing and said to ourselves “What simple things can we do to make the experience of creating Sugar Logic formulas easier?”. Our engineering team tackled this for 6.5, and came back with a few nice enhancements I’ll detail in this blog post.

As you can see, it’s similar to before but there’s a few changes we’ve made to make editing formula easier. Let’s take a look at them.

You’ll notice two buttons at the top of the editor ‘Related Field’ and ‘Rollup’. These fields make it super easy add related and rollup fields by showing a list of all the options available and using that to build the formula. For related fields, the popup asks you for the module the field you are looking for is in and the field to pull in.

For editing rollups, you can specify the function to use as well as the module and field to operate on.

Clicking ‘Insert’ on either of these dialogs will put the formula in the editor window, without you having to know the details of the relationships or fields like you did before.

Speaking of the editor window, the other nice feature we add was type-ahead hinting and autocomplete. So now when you start typing a function name or field, it will try to autocomplete what you are typing, including adding function hints on the functions in the list. See the image below.

This makes formula building much easier, as the editor helps support you in getting the formulas right the first time.

And for those of you who are writing complex formulas, you all know how much easier it is to break it apart on multiple lines and tab indent the formula to make it easier to read. Now in Sugar 6.5, this is possible.

We hope these enhancements make it easier to edit formula. Have any other feedback on what we can do to make the Formula Builder easier to use? Sound off in the comments below.

Opening the Cloud: Open Source Implementation at Every Level

03 May, 2012
Posted By: Clint Oram

This article was originally posted on the OpenSource Delivers blog.  Enjoy! –Clint

In last month’s Open Source and Innovation webinar, Editor-in-Chief of CRM Outsiders Chris Bucholtz, and I had the opportunity to speak with the Olliance Group’s Greg Olsen, about various aspects of the cloud including its future, the issue of security in the cloud, and the cloud’s role in the open source community. Naturally I was most intrigued by the relationship between open source and the cloud – two of the biggest technologies in business today.

Companies operating at every layer of the cloud have an interest in creating open source models and initiating open source implementations of cloud technologies. What we are seeing is a movement to make open source ubiquitous in the cloud environment. But why is it that open source is so influential in this space? Why does it matter if the cloud is built with open source software?

The primary reason for the popularity of open source in the cloud environment is the complexity of the cloud itself and the demand for standardization at each layer of the cloud.

At the base level, the innovation of the open source community has made cloud assembly possible and has continued to foster progress. Furthermore, with so many connected elements at the base level, a certain amount of openness is absolutely essential to enable code sharing, thereby facilitating the entire assembly process.

The next layer of the cloud is infrastructure as a service (IaaS). Using open source at this level is the most efficient and most natural way of standardizing infrastructure services, much of which initially grew from open source roots. By openly sharing both code and implementation, developers can take advantage of cloud portability (the ability to seamlessly move applications from one cloud to another) and cloud interoperability (the ability for applications to incorporate more than one cloud). OpenStack and Eucalyptus are two great examples.

At the platform layer – platform as a service, aka PaaS – most application developers are focusing the bulk of their attention on big data applications and web applications, which emphasizes the importance of standardization even more. Once again, by using open source and sharing code, developers can effortlessly move an application from one platform to another. Open source technologies like Linux, Apache, PHP and MySQL allow PaaS platforms like EngineYard, Red Hat OpenShift and Google AppEngine to deliver true application portability.  Sharing within the application developers’ community also stimulates community extension to your existing platform, encouraging further growth and higher levels of integration.

Next, at the layer of software as a service (SaaS) and applications, open source enables companies to quickly and effectively modify a cloud application to suit their changing needs. As an example, SugarCRM has focused seven years of open source development on making it easy to extend the SugarCRM platform and applications.  For instance, companies can integrate multiple systems like Sugar, Drupal and Alfresco within the cloud to make solving business problems easier. Cloud applications can evolve with the company, rather than the other way around.

Finally, end users benefit from the use of open source in the cloud. The open source developer community is quite prolific, but surprisingly the end users of open source have created a sharing community as well. More than users of commercial products, open source end users actively share their experiences, creating a flourishing ‘community’ of their own like the Sugar Community, and enriching their cloud experience.

It is clear open source software (OSS) adds value to the cloud on every layer. OSS represents the most reliable, most secure, and most innovative set of tools available, especially when applied to the booming cloud space. Not only does open source foster integration and standardization – two essential components of cloud operations – but it also encourages innovation, creativity, and communication. Open source and the cloud are a match made in heaven.

Have feedback for us? Drop us a line.
Terms & Conditions | Privacy | Trademark Info | Contact Info | FAQs | SugarCRM Inc.© 2004 - 2009 All rights reserved.