Quantcast
Channel: Sugar 7 – Sugar Developer Blog – SugarCRM
Viewing all 93 articles
Browse latest View live

TethrOn presents their Sugar Integration process

$
0
0

About TethrOn

TethrOn is a mobile field sales and service enablement platform that has a number of different pre-built integrations to back-end systems. The team behind TethrOn recently decided to become a SugarCRM Technology Partner in order to provide connectivity to Sugar with their mobile platform. Their architect gave the experience rave reviews:

Sugar was by far the easiest CRM system to integrate in our experience to date. This is mainly due to the robust set of APIs provided out of the box to support integrations over REST combined with clear documentation on best practices for extending the Sugar v10 REST interface.   In addition, what is provided out of the box is well thought out with respect to useful integration patterns.

TethrOn created a proof of concept in 3 weeks and released their production Sugar connector in just 8 weeks!

Sugar Object Mapping within TethrOn

Sugar Object Mapping within TethrOn

If you want to learn more about TethrOn, please visit http://www.tethron.com/.

Below David Valko from aMind Solutions, the company behind TethrOn, shares the successful pattern they applied for building their integration to Sugar.

Methodology for integrating with Sugar

Integration to our TethrOn platform is achieved through the construction of “connector” module that conforms to a uniform interface that TethrOn understands. That module must implement all data operations supported. Here are the 4 steps we followed for rapidly building the SugarCRM connector for TethrOn.

Step 1: Understand the Integration Points that Sugar provides for you 

Our development team did not have a lot of exposure to SugarCRM, however due to the robust content available on SugarCRM usage, development and integration, our team was able to come up to speed rapidly. We leveraged the many hours worth of recorded online tutorials from Sugar University, as well as online documentation such as the Sugar Developer Guide and other helpful online resources.

Specifically in our case, the v10 REST API was a match to our needs, so after grounding the team in Sugar usage and development, we focused much of our attention on the specification for these APIs to get a complete picture of what capabilities are accessible using this method.

Step 2: Build the sequence of events and validate

To ensure our design was viable, we identified the sequence of API calls that would need to occur to complete each of our integration scenarios. From that we constructed actual calls to the SugarCRM RESTful APIs using a REST client (like cURL or Postman) to ensure our design would function as desired.   These sequences of calls were then translated into actual implementation code and corresponding tests used with our continuous integration environment.

Step 3: Identify any gaps in the Sugar RESTful API and extend the APIs only as necessary

Over 95% of the functionality we needed was already available in the v10 REST API.   Building out the sequence of events as outlined above helped us to identify the remaining 5%. For these cases, we established a SugarCRM deployable package for our product. The package contains the additional web service endpoints we needed to complete our integration scenarios and is now available through Sugar Exchange.

For steps on how to create and modify SugarCRM service endpoints, we followed the instructions for Extending Web Services from the Sugar Developer Guide.

Step 4: When extending Sugar, follow the best practices

The documentation for extending web services describes in a step-by-step way what is needed to create or modify REST endpoints. However, it is also important to keep in mind other constraints in play that could affect the design of your custom endpoints:

In the case of compatibility with Sugar upgrades we took an approach that ensures we make as few assumptions about the current state of Sugar as possible. Specifically we followed these rules:

  • When extending Sugar avoid changing any core code of Sugar
  • Add only the minimal set of new endpoints needed to support the integration scenarios.
  • Given the option of using a “lower level” API or a “higher level” API, choose the “higher level” API. Example: where possible use SugarQuery instead of raw SQL queries to implement your endpoint.

Regarding the restrictions on PHP code in Sugar OnDemand environments, we found the most practical approach was to deploy our package to the SugarCRM On-Demand environment provided to us as a SugarCRM Technology Partner and configure our continuous integration tests to run against that environment.

Additional best practices for SugarCRM Package development can be found at in the Sugar Exchange Package Guidelines.



CreateActionsView changes in Sugar 7.7.0

$
0
0

If you have been participating in the Sugar 7.7 Beta then you may have noticed that SugarCRM Engineering has refactored how CreateViews work in the Sugar application.

This post explains the motivations for the change and what Sugar Developers need to know and the actions they need to take to migrate their customizations in future Sugar 7.x releases.

Differences between Create and CreateActions

Historically, there has been some confusion in the Sugar Developer community (see here and here) around the existence of two different Create dialog layouts in the Sugar application.

CreateActionsLayout

The CreateActionsLayout includes the CreateActionsView.  This view included additional action metadata that gave the user additional options for saving a new record.  This particular layout was used for the majority of usage flows that created new records in Sugar.  Sugar Developers were taught to customize this view in order to change the behavior of the Create dialog but in reality this was never sufficient to customize the behavior of all possible Create flows.

Create with actions

Create with actions

CreateLayout

The CreateLayout includes the CreateView.  This view did not provide these additional actions.  It was used in certain flows such as when a user chooses to Quick Create a record at the top right corner of the page.  But it was not used nearly as often so a lot of Developers did not customize it or even know about it in some cases.

Create without actions

Create without actions

Relationship between Views

While CreateActionsView extends from the CreateView, they were used on separate layouts.  So while it was possible to customize the base CreateView and have those customizations appear in all possible Create dialogs in the application – a module level customization of the CreateView did not have a similar effect.  This is because the Module’s CreateActionsView ultimately extended from the base CreateView and not the module’s CreateView.  So Sugar Developers were stuck customizing a module’s CreateActionsView in order to change the behavior of most create record flows for a module.  Only sometimes would Sugar Developers separately customize the module’s CreateView when they noticed the Quick Create flow didn’t work the same way.

Relationship between CreateActionsView and CreateView in Sugar 7.6 and previous

Relationship between CreateActionsView and CreateView in Sugar 7.6 and previous

Deprecation of CreateActionsView in Sugar 7.7

It was clear that we did not need to have a separate layout and view to handle small differences in behavior that also created customization challenges.  Plus after some research, we discovered that the additional create actions (such as Save and View) were hardly ever used!  We decided to eliminate some code and confusion.  So in Sugar 7.7, we’ve started the process of merging these views together.  When you set the Sugar log level to WARN in Sugar 7.7 (using the Administration Panel), you will see warning messages that the CreateActionsView and CreateActionsLayout are deprecated in your JavaScript console whenever they are used.

Screen Shot 2015-11-16 at 5.32.25 PM

They will be completely removed in a future release (currently planned for Sugar 7.8).

CreateActionsView is deprecated in Sugar 7.7 and is planned to be completely removed in Sugar 7.8.

The benefit is that Sugar Developers will only need to customize a single view to change the behavior of all create record flows.

Migrating customizations to CreateView and CreateLayout

The action that every Sugar Developer needs to take is to migrate their CreateActionsView  (clients/base/views/create-actions/) customizations to the CreateView (clients/base/views/create/).  This will prepare you for when CreateActionsView is removed completely.

This can be as easy as the following two steps:

  1. Copy each custom|modules/.../create-actions/create-actions.js file to custom|modules/.../create/create.js
  2. Change extendsFrom: '*CreateActionsView' to extendsFrom: '*CreateView' within the new files

If you were launching the create drawer, then you should use the CreateLayout (create) instead of the CreateActionsLayout (create-actions).

For example, use this

app.drawer.open({
    layout: 'create',
    context: {
        create: true,
        ...
    }
});

not this

app.drawer.open({
    layout: 'create-actions',
    context: {
        create: true,
        ...
    }
});

Sugar Developers need to customize CreateView for their create dialog customizations in Sugar 7.7 and later


CSRF Tokens in Sugar 7.7

$
0
0

What is a Cross Site Request Forgery (CSRF)?

A CSRF is a type of exploit that a malicious website or attacker could employ to have a user send unauthorized commands to a website or application.  It is a type of confused deputy attack against a user’s web browser that tricks it to send malicious HTTP requests to a target website.

Some CSRF techniques are trivial to employ.  For example, it is possible to place an arbitrary URL within an HTML IMG tag which will convince your browser to run an HTTP GET against that URL.

Try out this example that uses RequestBin.  I added an image tag to a page in my local web setup.

<img src="http://requestb.in/vzwvagvz">

When I checked RequestBin then I could see what the request from my browser looked like to the external service.

Screen Shot 2015-11-25 at 11.13.23 AM

CSRF exploit example

A malicious HTTP GET can potentially expose sensitive information.  For HTTP GET requests, the state of the system rarely changes meaning that lasting damage can be limited.  What can be more troubling is when a browser is tricked into performing an HTTP POST using a maliciously designed HTML form.

CSRF Authenticator in Sugar 7.7

Here is some information from Jelle Vink (Security Architect) on the CSRF Authenticator added in Sugar 7.7.  It is used primarily with Sugar 6.x based user interfaces (BWC modules) that include regular web forms since these are potential CSRF attack vectors. As of this writing, the Sugar 7.7 release is in beta.

Note that this is an early implementation and subject to change in future releases and therefore it is currently opt-in only for Sugar 7.7.  But the CSRF Authenticator will be enabled by default in a later Sugar release.

CSRF Authenticator is not enabled by default in Sugar 7.7 but this will change in a later Sugar release!

This will affect the behavior of customizations made to BWC modules that generate HTML that includes web forms.  There are actions that need to be taken to have these custom forms support CSRF authentication.

Enabling the CSRF Authenticator

To opt-in and enable this feature then use this directive in config_override.php:

$sugar_config['csrf']['opt_in'] = true;

How it works

We have added CSRF tokens to each web form that the Sugar application generates.  If the correct token is not included during a form submit then the POST request will be rejected.

The Sugar 7.7 implementation ties the CSRF token used in BWC forms to the user’s PHP session.

The SugarController class is used to determine if it is a modify action. When the SugarApplication class detects a modify action, the CSRF authentication logic in SugarController will be called for all POST requests.

For more details, see the SugarApplication and SugarController classes in the Sugar 7.7 codebase.

The following configuration parameters are available:

Soft Failure Mode

$sugar_config['csrf']['soft_fail_form'] = true/false

This config setting disables CSRF authentication and is only present to mitigate any upgrade issues where customizations are missing the necessary CSRF token inclusion.

Using this settings is not recommended in a production environment! When soft failure is enabled then Sugar will merely log missing CSRF tokens or mismatches.

Token Size

$sugar_config['csrf']['token_size']

The size of the tokens (in characters) being generated.  This value defaults to 32 characters.

Form Token Field

$sugar_config['csrf']['form_token_field']

This is the form field used to transport the token value.  It defaults to ‘csrf’.

Using the CSRF Authenticator

The CSRF Authenticator will be enabled by default in a future Sugar version. Developers should act now to make sure they are ready.

Sugar Developers can enable CSRF authentication in Sugar 7.7 instances in their local development environment.

config_override.php

$sugar_config['csrf']['opt_in'] = true;

Then you will see FATAL errors in the Sugar log when users use forms that do not have CSRF tokens added to them properly.

sugarcrm.log

Wed Jul  1 06:47:46 2015 [710][1][FATAL] CSRF: attack vector detected, invalid form token detected
Wed Jul  1 06:47:46 2015 [710][1][FATAL] CSRF: auth failure for Users -> Save

Sugar Developers should add the following Smarty tag to their custom forms used with BWC modules.

{sugar_csrf_form_token}

For example,

customform.tpl

<form name='myCustomForm' action="index.php" method="POST">
  {sugar_csrf_form_token}
  <input type='hidden' name='id' value='{$id}'>
  <input type='hidden' name='module' value='{$module}'>
  ...
</form>

 


Leveraging Backbone Events in Sugar

$
0
0

Sidecar and Backbone.js

The Sidecar user interface framework is built on a variety of browser side technologies.  Being proficient in these underlying technologies is important for any developer writing Sugar 7 user interface code.

They key JavaScript component that pulls Sidecar together is Backbone.js. Backbone provides the underlying structure to Sidecar as well as providing a rich set of base features and APIs that are heavily used throughout the Sugar 7 application.

Sugar 7.6.x uses Backbone 0.9.10.

If you’ve ever created a Sugar Dashlet or any other user interface component in Sugar 7 then you will familiar with Backbone concepts such as customizing a View or working with a Model. However, many loosely coupled customizations or integrations with Sugar 7 user interface are possible through the use of Backbone Events.

For server side code, recall that you can use Logic Hooks to trap a Module’s save events instead of overriding a module’s SugarBean.  The same pattern can be applied where instead of overriding a core file, you can listen to essential events and take action as they occur.

We will explore more below.  The code from this example is also available on Sugar Integration Building Blocks project in Github.

Backbone Events

The Backbone.Events module is a lightweight pub-sub pattern that gets mixed in to each Backbone class (Model, View, Collection, Router, etc). This means you can listen to or dispatch custom named events from any Backbone object.

Backbone Events should not be confused with jQuery Events which is an API for working with DOM events. Backbone supports an events hash on Views that can be used to attach event handlers to DOM using jQuery. These are not Backbone Events. This can be confusing since both interfaces include an on() function, allow you to attach an event handler, and other similarities.

The target for jQuery events are DOM elements.  The target for Backbone Events are Backbone objects.

Sidecar classes all extend these base Backbone classes.  So each Sidecar object (Layouts, Views, Fields, Beans, Contexts, etc.) supports Events.

Existing Backbone Event Catalog

All of the existing catalog of Backbone Events are supported and triggered by the Sugar application.

For example, we can listen to built-in Backbone Router events, such as the route event, that are triggered by Sidecar.  Try running the following JavaScript code within your browser’s console.

SUGAR.App.router.on('route', function(){console.log(arguments);});

As you click through the Sugar application, each time the router is called you will see routing events appear in your browser console.

Screen Shot 2015-12-11 at 12.45.57 AM

Can you figure out what layouts were visited?

Example Sidecar Events

In addition to existing built-in Backbone Events, the Sidecar framework makes use of a variety of unique events.  We will show examples of some events that are particularly useful for customization purposes.

Not all Sidecar Events are documented below.  If you are interested, explore further by downloading the Sidecar Dev Tools and use the Application Stream to monitor many Sidecar Events as they are triggered.

Application (Global) Events

Application events are all triggered on app.events (SUGAR.App.events) object. For example, if you wanted to see all global application events printed in your browser console then you could use the following code.

SUGAR.App.events.on('all', function(){console.log(arguments)});

For example,

app:sync:complete

This is a very useful application event to know about. This event is triggered after login and the series of initial synchronization operations is completed.

This is earliest point of the application lifecycle where all metadata, view definitions, Handlebars templates, etc, are available to JavaScript code. So this is a good jumping off point for custom code.

Bean Events

Some events are triggered only on Bean objects.

For example,

validation:complete

Validation tasks are run against a Bean prior to saving a Bean object back to server.  If validation passed, then this event will pass TRUE to listeners. If validation failed, then this event will pass FALSE to listeners.

Context Events

The Context object is often used to facilitate communication between different Sidecar components on the page using Events.

For example,

button:save_button:click

This event is triggered whenever a Save button is clicked.  The Record View uses this event to run save routines without being tightly coupled to a particular save button.

Adding a new Record View button

Here is a demonstration of how you can use Events as an alternative to overriding Sidecar controllers. This approach is more upgrade and customization friendly than overriding a core application file.

The following steps will create a new custom button on the Accounts module’s Record View and wire it to a JavaScript callback function.

Screen Shot 2015-12-11 at 2.26.25 AM

Wiring in our new Button

Step 1: Insert Button Metadata

We need to add Button metadata to the existing Accounts view using a Sidecar Extension.  This defines the Sidecar Event to be triggered as well as the target object for the event.

custom/Extension/modules/Accounts/Ext/clients/base/views/record/custom_button.php

Step 2: Add Event handler JS using JSGroupings

We can add event handling JavaScript into page using a JSGroupings Extension. This is designed to attach a callback function to the appropriate Context object when the application is on the Account module’s Record view.

custom/Extension/application/Ext/JSGroupings/addCustomButtonJS.php

 

 

Step 3: Quick Repair and Rebuild

You then need to run Quick Repair and Rebuild in order to build your new extensions.  You will also need to do a hard refresh of the browser page in order to load the updated JavaScript files.

customButtonResult

Button action all wired together without overriding any Sidecar controllers

 

Sidecar Event Management

As with any single page application, it is important to include memory management considerations when you are coding your solutions. Event handlers can be a common source of memory leaks in JavaScript applications since they can prevent the objects they are attached to from being garbage collected. You do not want to keep old Sidecar Views, Layouts, etc, in memory long after they should have been removed.

Here are a couple tips.

For global objects, make sure your event listener is attached only once. Make sure you understand the lifecycle of the objects you are working with.  Do not guess.

Events get detached from Sidecar created objects. The Context object and any Layouts, Views, Fields that are created by Sidecar are disposed of whenever a new layout is loaded via Sidecar’s built-in controller.  This process detaches any listeners attached on these objects.  This is why it was not necessary for us to remove the Context listener in the example above.

If you created it, then you need to clean it up.  If you have JavaScript code that calls app.view.create* then you are responsible for disposing of it properly.  Calling dispose() on your own components when you are finished with them will remove event listeners as well as detach it from the DOM, etc.  Otherwise the view, your event listeners, and anything else that is attached could stay in memory forever.

Use Backbone’s listenTo() and stopListening() functions where possible.  They are designed to make automatic management of Events easier.


Tips for managing Sugar file permissions

$
0
0

The Sugar application requires that a number of directories be writable in order to properly function.  The precise directories and minimum permissions needed are covered in the Sugar Install Guide.

A common practice for Sugar Developers to work around file permission issues is to make everything writable to the web user.  In practice, this does not cause any functional issues and is an easy way to avoid problems. But this is not desirable in production or sensitive environments from a security point of view because it violates the principle of least privilege. So Developers should really familiarize themselves with setting up secure file permissions for their web servers since this will be more in line with real production environments.

Here are some tips for working with extended file system permissions on your Sugar deployments from Jelle Vink our Security Architect.

Using extended File System ACLs

To have more granular control there is an option to use extended file system access controls.  Normally Linux file systems are mounted with extended attribute support by default. The common file systems all support this (ext2, ext3, ext4, reiserfs, btrfs, jfs, etc) so it is worth investigating this approach if your environment supports it.

You can use the setfacl, getfacl and getfattr commands for extended access control which means that you can actually assign more than one user and/or group to a file or directory and set specific access permissions for each one of them. More information about these extended attributes can be found on the web.

Configuring default Sugar file system permissions

Sugar does not always use same routines to create files and directories. Some use raw fopen to access the file system but most accesses go through sugar_file_utils functions. When the latter are used, the following settings apply for newly created directories and files.

These settings can be configured in config_override.php to allow control over how default file permissions are set:

$sugar_config['default_permissions']['user'] = 'user_goes_here'; //Empty by default
$sugar_config['default_permissions']['group'] = 'group_goes_here'; //Empty by default
$sugar_config['default_permissions']['dir_mode'] = 02770; //(*)
$sugar_config['default_permissions']['file_mode'] = 0660; //(*)

(*) use octal notation, so these integer values look like 1528 and 432 respectively.

You can see for directories that setgid is enabled then, by default, you will ensure new files created in that directory inherit the directory’s group instead of the user’s default group.

You can see that the default permissions are 0660 for files. This ensures that files are readable by the Apache (or web) group.

There is a catch for files created outside of sugar_file_* functions. Those will use the system umask which is often set to 0022. In this case, by changing the umask for web server user to 0002 will result in a file permission that matches the Sugar application default (0660).

Sugar Cron user

Another important check is to see whether the user which is used to run Sugar cron is properly set up. When running cron, there is always a chance that some changes are written to the file system.  For example, part of the cache may need to be rebuilt as part of a scheduled task. If you schedule to run cron.php as root user then any files created during that process will be owned by root instead of the web server user which can cause a lot of headaches when the web server tries to access these files.

In Summary

The proper setup of users and groups is an essential server administration skill. In combination with the possibility of having extended attributes, the permission configuration in $sugar_config, and ability to use setgid on directories you should be able to perform any complex setup to meet security requirements.


Update on CreateActionsView changes in Sugar 7.7

$
0
0

Based on Sugar Developer community feedback, we have an additional update about the CreateActionsView changes in Sugar 7.7.

CreateActions migration script added to Sugar 7.7 Upgrader

During Sugar 7.7 upgrade, the upgrader will identify existing create-actions view/layout customizations and automatically migrate them to create view/layout.  This is a best effort migration that follows the two steps listed near bottom of this blog post.

If a custom create view/layout already exists, then create-actions changes will not be automatically migrated.

This will mitigate impact of this change for existing Sugar customers.


Using Packer to create consistent Sugar platform environments

$
0
0

The “Works On My Machine” Problem.

How often have you reported a software bug and had it rejected with a terse response such as “could not reproduce”?

You press the issue with your colleague and the conversation usually goes something like this:

You:  Here, look at my screen.  You can see the problem happening right here.

Them: Whatever. It works on my machine. L8tr dude.

Doesn’t this drive you crazy?

Ultimately, even if you are both running the exact same source code there are always factors related to configuration and platform environment that can affect how an application behaves.

The flexibility of Sugar that we all love also means that we are often running Sugar in multiple different places and in varying configurations. For example, your team could be running Sugar instances in the cloud or on-premise, on real or virtualized hardware, on different operating systems, database servers, etc.

How do you keep track of all these different configurations, let alone try to make them as consistent as possible to avoid the “works on my machine” problem?

Introducing Vagrant and Packer

Vagrant is a tool built by Hashicorp.  It is a tool designed to make managing development environments really easy.  If an existing Vagrant box exists, you are never more than two commands away from launching a development environment that you need.  But it is a tool designed specifically for developers.  It is not the right tool for hosting customer instances or for doing QA because it does not alone replicate a real operational environment.  Also, if a Vagrant box doesn’t already exist for the platform you want to work with then you need to create one.  This is where Packer comes in.

Packer is also built by Hashicorp, the same folks behind Vagrant.  Here is the definition of Packer straight off their website.

Packer is a tool for creating machine and container images for multiple platforms from a single source configuration

SugarCRM Engineering uses Packer as the base tool for creating all the images we use for development, continuous integration, and QA.

Packer can be used to create Virtualbox or VMWare images, Amazon AMIs, Vagrant boxes, or even Docker containers all from a single source.  Recall Cedric’s recent post on using Docker containers to run Sugar.  There is even a Null builder that you could use to run the same provisioners used to build your images on existing machines.

Below we will explore how you can use Packer to build a consistent Sugar 7 ready LAMP stack for Vagrant or on any other platform of your choice.  The code from this post is all available in a Sugar 7 Ready template Github repository.

Using Packer to create a Sugar 7 LAMP stack

As a basis for these templates, you can start by following the Hashicorp tutorial for “Building Vagrant Boxes with Packer and Atlas”.  This was a good starting place because it builds an Ubuntu 12.04 machine and publishes Vagrant boxes for it on Atlas which makes them available to anyone.  We just need to modify this example to install supported versions of Apache, MySQL, and Elasticsearch and configure them so they are ready for a Sugar 7 install.

You will need Packer installed locally or have an Atlas account in order to run Packer builds.

For local builds, you will need to install Packer.  You will also need to have Virtualbox installed to run the Virtualbox builds.  If you have a VMWare license then you need VMWare Desktop or Fusion installed in order to run the VMWare builds.

If you are using Atlas to run builds then you only need Git installed locally.

This example uses shell scripts to provision the system but Packer supports a variety of provisioning options such as Puppet, Chef or Ansible. It is worth mentioning that SugarCRM Engineering uses Puppet to centrally manage provisioning in our internal environment.  But we will keep things simple by focusing on using shell scripts for now.

Shell scripts for provisioning Sugar 7 dependencies

Most of the provisioning scripts are going to be boilerplate.  For example, the steps for installing a new operating system or configuring user accounts, etc, are going to be more dependent on the selected Operating System rather than being anything that is Sugar specific.  So we will show two scripts below that focus on installing Supported Platform dependencies.

This first script is used to install all the needed Sugar 7 software dependencies on a fresh Ubuntu 12.04 machine.

 

This second script is used to configure Apache 2.2 web server on Ubuntu 12.04 to work with Sugar application.

 

Sugar 7 Ready template repository

The Sugar 7 Ready Packer templates are set up to build Virtualbox and VMWare images and Vagrant boxes.  But extending it to build Docker containers, Amazon AMIs, or any other container technology is possible and encouraged.

Trying it all out

Trying it out is easy if you have Virtualbox installed.  Virtualbox is a popular option because it is free.

Launching the Vagrant box

With Vagrant and Virtualbox installed, navigate to a clean Sugar development directory and run the following command.  By default, these boxes use 3GB of memory but you can customize this within your Vagrantfile.

vagrant init mmarum/sugar7-php54; vagrant up --provider virtualbox

When finished, your current directory will be running at http://localhost:8080/sugar/.  Visiting that URL will launch the Sugar installer.

If you have VMWare installed then you can launch the VMWare provider instead.

vagrant init mmarum/sugar7-php54; vagrant up --provider vmware_desktop

Downloading the Virtualbox Image

The same Packer template used to create the above Vagrant boxes was used to install a GUI desktop for running Sugar within a plain Virtualbox machine.  This is a great option for having an easy to use version of Sugar for training purposes.

Download it from here.  If you have Virtualbox installed, you can unzip it then import the image using Virtualbox  By default, it uses 4GB of memory but you can adjust this within Virtualbox before you launch it.

VirtualBox_packer-sugar7-php54-ubuntu-1450472556_04_01_2016_11_02_28


PHP Session Changes in Sugar 7.7

$
0
0

Below is some details from Andreas Sandberg, Director of Engineering, at SugarCRM.  Andreas is on his second tour of duty at SugarCRM.  He first joined SugarCRM back in 2007 as an Engineering manager.  He was also the Head of Engineering at Stitch prior to their acquisition by SugarCRM.

Below he shares some information about some changes that have gone into Sugar 7.7 that change how PHP sessions are stored and the underlying implementation.  Sugar Developers need to be aware of these changes so that their interactions with $_SESSION variable do not yield any unpredicted results.

What has changed with $_SESSION?

We have refactored PHP Session storage so that it is more configurable and allow more control over PHP session handling.  We have introduced a new SessionStorage class at src/Session/SessionStorage.php which extends from the TrackableArray class at src/Util/Arrays/TrackableArray/TrackableArray.php. This means that the $_SESSION variable is now an object instance of a TrackableArray which implements the ArrayAccess interface. This means that most code that treated $_SESSION like an array will continue to work as before.

However, there are three changes that Sugar Developers need to be aware of when working with the PHP session objects.  Each change is outlined below. Two of them are API level changes and the last is really just an adherence to best practices but may yield unexpected results if ignored.

Session Array Functions

In Sugar 7.7, certain array functions will now throw fatal errors when used on the $_SESSION variable.  PHP’s native array functions are not safe to use against ArrayAccess objects.  To proactively catch these issues, we have added a health check script to Sugar 7.7 upgrader.  This will warn about use of standard PHP array functions against the $_SESSION variable.

Screen Shot 2016-01-08 at 12.15.05 PM

$_SESSION variable health check

We have modified all areas in the core Sugar 7.7 codebase where this would be problem and have introduced new array utility functions that must be used instead of the standard PHP array functions.

These functions can be found in: src/Util/Arrays/ArrayFunctions/ArrayFunctions.php

These Sugar Functions are safe to use with native PHP Arrays and PHP ArrayAccess implementors such as Sugar’s Session object.

Sugar Function
PHP Equivalent
is_array_access
is_array
in_array_access
in_array
array_access_keys
array_keys
array_access_merge
array_merge

 

(Pre|post)(Increment|Decrement) Operators

With the new implementation, pre and post increment or decrement operators will not work as expected and therefore should be avoided.

For example instead of doing something like:

BAD 

$_SESSION['userStats']['pages']++;

Sugar Developers should instead use:

GOOD

$_SESSION['userStats']['pages'] += 1;

 

Assigning unset session references to a variable

There are some improper programming practices that can cause problems. Specifically, when trying to access a session value by key that does not exist.  When that happens, an unexpected value will be assigned.

For example:

BAD

//No session value for key authenticateduser_language exists in this example
$GLOBALS['current_language'] = $SESSION['authenticateduser_language'];

In this example our friend the TrackableArray will be assigned to the GLOBAL array instead of a string.

To ensure this never happens always proactively guard against possible null values:

GOOD

$GLOBALS['current_language'] = !empty($_SESSION['authenticated_user_language']) ? $_SESSION['authenticated_user_language'] : $GLOBALS['sugar_config']['default_language'];

 

Returning a session value that is an array

You can prevent unexpected behavior when you expect a session value to be an array by using array type casting.  This will ensure that an array is always returned.

BAD

return $_SESSION['reports_getACLAllowedModules'];

GOOD

return (array) $_SESSION['reports_getACLAllowedModules'];

 



Adding a new popup view in Sugar 7.x Record View

$
0
0

Here is a guest post from Shijin Krishna from BHEA, an Elite SugarCRM Partner, and active member of the Sugar Developer community.

Are you interested in posting on the Sugar Developer Blog? Contact developers@sugarcrm.com with your idea.

In this post we are going to see how we can add a quick create pop-up view for related modules in record view. This idea is taken from Sugar Portal which comes with Sugar Enterprise, Ultimate and Corporate editions. Sugar Portal’s detail view for Bugs and Cases modules includes an action to add a note to the bug or case. In this post, we are going to see how we can create a similar quick create pop up on the base Sugar 7 web client which will be shown at the click of a button.

We will use Cases and Notes modules as our basis.  We shall place a new ‘Add a Note’ button in Cases record view.  This button will be wired to display a pop-up create view for adding notes on the current case record.

The terms modal and popup are sometimes used interchangeably in Sugar 7 codebase and documentation. A modal dialog requires that a user interacts with it before they can continue. In many frameworks such as Bootstrap, modals are implemented as a child frame that “pops up” on the application screen.  In Sugar 7, Drawers are more commonly used than popups.

Adding a new Record View button

The following steps will create a new custom button on the Cases module’s Record View and wire it to a JavaScript callback function. These steps has been taken from Matt’s blog post on Leveraging Backbone Events in Sugar.

Step 1: Insert Button Metadata

We need to add Button metadata to the existing Cases record view using a Sidecar Extension. This defines the Sidecar Event to be triggered as well as the target object for the event.

custom/Extension/modules/Cases/Ext/clients/base/views/record/add_note_button.php

Step 2: Defining the Sidecar Event to be triggered on click of the button

To define the event to be triggered on click of our custom button, we will override the record view controller for Cases.

custom/modules/Cases/clients/base/views/record/record.js

add_note_button

Adding a new Quick Create View for Notes Module

Our next step is to create a new custom quick create popup view for Notes module. We will extend our custom view from the Baseeditmodal view.

File Structure

We’re going to create a folder in custom/modules/Notes/clients/base/views/ called “quick-create“. Inside that folder we will create 3 files:

  • quick-create.php
  • quick-create.js
  • quick-create.hbs

Your file system should look something like the following screenshot.

file_structure

Step 1: Implement the Quick Create View Metadata (.php file)

The following metadata can be modified according to your needs. If you wish to see more fields in the quick create popup then you can add those fields as well to the fields array.

custom/modules/Notes/clients/base/views/quick-create/quick-create.php

Step 2: Implement the Quick Create View Controller (.js file)

Here is the JavaScript controller for our quick create view. We will extend our view from BaseeditmodalView.

custom/modules/Notes/clients/base/views/quick-create/quick-create.js

Step 3: Implement the Quick Create View Template (.hbs file)

Below is the Handlebars template for our custom quick create view. We need to add some CSS style for the popup to make it look better. We have added a new CSS class ‘quick-create’ for the modal element so that we can selectively apply new styling to our quick create popup without affecting the style of other modal popups being used elsewhere in Sugar.

The template has a form which contains the fields and buttons defined in view metadata. We have used a book icon in the modal header from FontAwesome. If you are trying this example in any sugar version prior to 7.6.x then you may need to make sure you are using a different FontAwesome class name for this icon. Refer to this blog post for more details.

You can find the available list of icons in Sugar Styleguide accessible from the Administration panel of your Sugar instance.

custom/modules/Notes/clients/base/views/quick-create/quick-create.hbs

Step 4: Add custom CSS style for our Popup (.less file)

Feel free to change the style as you wish!

custom/themes/custom.less

Step 5: Define the display labels for our new UI

Our final step is to define the display label for the custom record view button and for the quick create pop up header.

custom/Extension/modules/Cases/Ext/Language/add_note.en_us.lang.php

Step 6: Quick Repair and Rebuild

Finally, you will need to run Quick Repair and Rebuild in order to build your new extensions. You will also need to do a hard refresh of the browser page in order to load the updated JavaScript and CSS files.

After this, you will be ready to use your new quick create popup dialog. Visit the Cases module and click the Add a Note button and you should see a dialog like this one below.

notes_quick_createview


Using Script and CSS loading plug-ins for easy Sugar integrations

$
0
0

Getting 3rd party JavaScript into Sugar

The most common UI integration point between Sugar and external applications is the trusty Sugar Dashlet. This is why we spend so much time talking about Dashlets here on the blog and at our Sugar Developer events throughout the year. However, if you are building something more complicated than an iframe dashlet integration then there is often a requirement to pull 3rd party JavaScript into the page. For example, many integrations are facilitated using JavaScript API client libraries.  Or there is code that a developer is trying to reuse that relies on JavaScript libraries that Sidecar does not already use.

Out of the box, this developer has a couple different options:

Use JSGroupings Extension

Using JSGroupings extension allows you to include additional JavaScript files with the core Sugar application JS that is pulled into the page when the Sugar application is loaded. The drawback is that this JavaScript will get pulled into the page whether or not it is ever used by a user.

Adding script tags to page dynamically

You could add script tags to your Handlebars template or via a Sidecar controller. But this approach adds a bunch of ugly complexity to your code as you have to manage many routine tasks related to loading scripts.

Providing another way!

But Sugar gives us the tools we need to design another way! Below we will explore using the Sidecar plug-in framework to provide an easy way to dynamically load JavaScript and CSS for use with your custom Sidecar components.

Sidecar Plug-in Framework

In Sugar 7, we introduced a plug-in framework that allows you to Mixin additional functionality into your Sidecar component with minimal fuss. If you have created a Sugar Dashlet before then you have already used the Dashlet Sugar 7 plug-in.

Under the Sidecar covers, the plug-in manager uses Underscore extend() to add properties from the plug-in to your component. In the case of the Dashlet plug-in, this adds the necessary APIs that Sugar needs to display and manage your view within Sugar Dashboards.

There are two important facts to keep in mind when working with Sidecar plug-ins.

Sidecar plug-ins are not extensible

You cannot extend a Sidecar Plug-in like you can a standard Sidecar component such as a view, layout, field, etc. So when creating Sidecar plug-ins, we recommend making them as lightweight and granular as possible so you can easily mix, match, and replace plug-in combinations in Sidecar components.

Sidecar plug-ins should be installed using JSGroupings extension

Also, we recommend registering your new custom Sidecar plug-ins using the JSGroupings extension. Below we will provide a couple of examples that shows more details on how this works.

Registering your Sidecar plug-in

Adding a plug-in to Sugar is as easy as calling app.plugins.register(). Lets break down the parameters.

app.plugins.register(name, validTypes, plugin)

Parameter Description
name (String) Plugin name that you want to use
validTypes (String|Array) list of component types this plugin can be applied to.  Limited to view, field, layout, model, and collection as of Sugar 7.6.
plugin (Object) Plug-in object

Plug-ins are registered after the Sugar application has been initialized. When registering a plug-in using JSGroupings extension, you should do so within an app:init event handler. You will see this in both examples below.

To read the full Sidecar plug-in manager documentation, view the doc blocks in sidecar/src/core/plugin-manager.js.

CssLoader Plug-in

Our CssLoader example is quite simple. The Css Loader plug-in is also available over at the Sugar Integration Building Blocks project in Github. It tracks the Stylesheets loaded in the browser and only adds a new link tag to pull in new CSS files as needed.

 

ScriptLoader Plug-in

The Script Loader plug-in is also available over at the Sugar Integration Building Blocks open source project in Github. This plug-in relies on RequireJS to do most of the dirty work related to loading and managing JavaScript libraries.

 

Highcharts and Unicorn Buttons Dashlet Example

Now we can create a simple Dashlet that leverages both of our new plug-ins to easily pull in a couple different external libraries dynamically. In the example below, we use Highcharts and Unicorn UI Buttons but you can adapt this example to use whatever JavaScript or CSS libraries that you need.

 

Easy right? This is what it looks like when it is installed on a Sugar Dashboard.

Screen Shot 2016-01-28 at 11.38.37 AM

Highchart and Unicorn Buttons within a Dashlet

 

 


New Sugar Docs: Sugar 7 On-Site Sizing Guide and more!

$
0
0

Relaunched SugarCRM Support Site!

Have you had a chance to check out the new SugarCRM Support site? It is awesome. I am in there all the time looking up documentation so the new changes have really made my job easier. The new layout looks great but also organizes the content better and the search functionality has been improved.  This means I can find the information I need that much faster.

On top of that, the new Support site includes a couple of recent additions that are welcome to Sugar newbies and those Sugar Developer veterans who have been around the block.

New Sugar 7 On-Site Sizing Guide!

We have revamped our guide to deploying Sugar on premise or in a public/private cloud. We have created a simple process with supporting hard data that will allow you to “right” size the infrastructure needed to host Sugar for any usage scenario or any deployment size: Small to Enterprise.

This is also the first piece of key documentation that will be part of an upcoming Sugar Solution Architect certification. This certification is going to be really key to our SugarCRM Partners and Enterprise Customers so I am excited that this is something that is in flight right now.

Keep in mind that not only do we give you the guide but we also provide the Tools. You can use Sugar designed JMeter scenarios to verify that the deployment you designed can handle the expected load.

These resources will make anyone well equipped to deploy Sugar 7.

New Vagrant Development Environment instructions!

Quick start your Sugar development by using our new Vagrant set up instructions!  With a reasonable internet connection, this will get you up and running for local Sugar development in a matter of a few minutes.

A nice way to kick Sugar’s tires especially for those new to the LAMP stack.


Addressing Subpanel Creep in Sugar 7.7

$
0
0

Subpanel Creep

The Subpanels section is where you find related records for the current displayed Sugar record. This is a vital feature because it allows a user to get a unified view of all the CRM records related to a particular record.  Who are the Contacts associated with the Account? When is the last time I talked to this Customer?  These answers are typically found within the subpanel section.

Screen Shot 2016-02-26 at 3.50.46 PM

A very common customization in Sugar is to create new Custom Modules or to add new types of relationships between existing modules in the CRM.  For example, at SugarCRM we use Sugar to track Sugar Subscriptions within a custom module.  These Sugar Subscriptions are related back to the Account record for each and every customer we have. So there is a Subscriptions subpanel that appears on every Account record for this relationship.

Module relationships and even custom subpanels are slowly added over time to every Sugar instance – but rarely does anybody go back and remove them. This can cause problems since every subpanel has a cost associated with it.

Each subpanel is populated via an API request that queries additional database tables. Also each subpanel adds weight to the client user interface with additional HTML and JavaScript objects associated with them. If you have 15, 20, or more subpanels on your modules then opening a single record can generate a lot of overhead as these panels are rendered and are populated.

Performance is a priority at SugarCRM Engineering. So it was necessary for us to tackle this common issue head on.

If you are in the Sugar Beta program, then you can try out the Sugar 7.7 Beta to observe the following changes.

Sugar Developers who have heavily customized Sidecar Subpanels need to carefully test their customizations when upgrading to Sugar 7.7.

Refactored to improve Subpanel performance

We have (re)introduced record counts on subpanels.

Screen Shot 2016-02-26 at 4.59.37 PM

Subpanels with counts in Sugar 7.7

This is a great UX touch! It also helps avoid situations where users open subpanels just to see if there are new related records.

We have also optimized the rendering of Subpanels so that subpanel lists are rendered only when subpanel is expanded. Previously, they would be rendered as hidden HTML which would impact client side performance unnecessarily.

A full related record query that selects all fields in list view is only used when the subpanel has been expanded.

These changes necessitated a refactor of functions related to toggling and rendering of subpanels. Sugar Developers who have heavily customized Sidecar Subpanels need to carefully test their customizations with Sugar 7.7.

System Setting to collapse Subpanels by default

In the past, Sugar would always fetch subpanel data immediately upon navigating to a record view. Subpanels that were opened by users would be “sticky” and remain open when users visited other records within the same module.

For example, if you left the Contacts subpanel open on the Accounts module, then every time you returned to an Account the Contacts subpanel would be open and related record data would be fetched to populate that subpanel.

This behavior can now be controlled using a System Setting.

Screen Shot 2016-02-26 at 4.40.28 PM

New collapse_subpanels in Sugar 7.7

With the collapse_subpanels configuration setting enabled, all Sidecar subpanels will be collapsed by default for all users when they visit Record views.

Enabling the $sugar_config[‘collapse_subpanels’] setting is highly recommended for Enterprise customers or situations where “subpanel creep” has taken hold in your Sugar deployment.


Sugar Notifications in Action

$
0
0

Here is a guest post from Hatim Alam from BHEA, an Elite SugarCRM Partner, and is a certified Sugar Developer Specialist. Hatim shares some ideas for getting creative use out of Sugar Notifications.  Share your own ideas in comments below!

In this post, we are going to look into different scenarios where Sugar Notifications can be of great help. For example, It can be used to notify user when new post or comment has been created on the Activity Stream or on execution of custom job or on triggering of API endpoint or implementing approval/review workflow.

We will create Sugar Notification for each of these scenarios and learn how easy it is to use and implement.

new_comment_in_activity_stream

New comment in Activity Stream

What are Sugar Notifications?

The Notifications indicator is available to all Sugar users and is located on the upper right of the screen next to global search.

The number displayed in the notifications box indicates the number of messages with a status of “Unread”. A “0” will appear if there are no unread notifications.

Open the Notifications dropdown and click “View Notifications” in order to see all notifications in a list view.

sugar_notification_panel

Activity Stream notification in Notifications drop down

Create Sugar Notifications on new posts or comments in the Activity Stream

Editor’s Note:  Pedro Bazan had published popular a logic hook for adding notifications whenever a user is mentioned in an Activity Stream.

The following steps will create new before_save logic hook on Activities bean within Activity Stream module. Through this logic hook, we will create a new notification whenever a user posts a new comment.

Step 1: Create before_save Logic Hook extension definition

custom/Extension/modules/ActivityStream/Activities/Ext/LogicHooks/create_notification_save.php

Step 2: Create the Logic Hook action method

As defined in our logic hook extension above, now we need to create a file where we can define our logic hook function.  In this action, we will check if any new post or comment has been posted to Activity Stream.

Usually, there are multiple types of activities in Activity Stream – link, unlink, create, update and post. We will be checking if the activity type is a post.  The post activity type is associated with new posts or comments within an Activity Stream.

custom/modules/ActivityStream/Activities/customLogicHook.php

Create Sugar Notifications to update status of data synchronization

We have many situations where we integrate Sugar with external applications and expose our custom APIs to update data in Sugar as external changes happen. We can use notifications to increase user awareness of these changes. For eg; we can update contact information and notify the assigned user using Sugar Notifications.

Step 1: Create custom endpoint in Sugar

custom/modules/Contacts/clients/base/api/TestContactApi.php

Create Sugar Notifications to implement approval or review workflows

Sugar Notifications can be very handy to implement approval/review workflow and notify a user or a user’s manager if any specific condition satisfies. For eg: the assigned user’s Manager gets a notification when an opportunity is created with a discount > 25%.

Step 1: Create before_save logic hook extension definition

custom/Extension/modules/Opportunities/Ext/LogicHooks/check_opp_discount.php

Step 2: Create the logic hook action method

Here, we will check if opportunity discount percentage is >25%, we will notify assigned user’s Manager using Sugar Notifications

custom/modules/Opportunities/customLogicHooks.php

Se how easy it was to create Sugar Notifications? Sugar Notifications are a great tool for various other actions as well.  You can use them with custom APIs, logic hooks, Sugar Jobs, etc, in order to notify users of record assignment, new record creation, record update, job status, etc.

Try out some ideas on your own and let us know what you come up with in the comments below!

notification_detail_view

Record view for new Activity Stream notification

Quick Tip: Check out this SugarCRM Knowledge Base article for adjusting Sugar Notification Delay – Setting Sugar’s Notification Delay


Using Composer with Sugar PHP development

$
0
0

Here is a guest post from Emmanuel Dyan from iNET Process, an Elite SugarCRM Partner, and an active Sugar Developer community member as well as an open source advocate.

Are you interested in posting on the Sugar Developer Blog? Contact developers@sugarcrm.com with your idea.

Managing libraries and dependencies within Sugar

Sugar Partners sometimes need to share libraries between various Sugar development projects. It is also required that we use the custom directory structure for Sugar customization. Sometimes developers will just copy and paste libraries or other dependencies into the custom directory that they need to use for each of their Sugar projects.  But there are better ways to manage your code’s dependencies.

Composer is the best way to manage your software dependencies for PHP, so much so that it is de facto standard that PHP developers are adopting (including the team at SugarCRM). In this blog post, we will explore how you can use Composer to easily manage libraries used with Sugar development.

If you haven’t used Composer before, then check out Composer’s Getting Started guide for installation instructions.

Installing libraries using Composer

Let us suppose we have a project where we need to read YAML files. The best component to do with PHP is symfony/yaml. So, instead of downloading it and unzipping it into any directory, we can use Composer by running :

$ cd custom/
$ composer require symfony/yaml

This will generate a composer.json file that contains our new dependency and download the symfony/yaml library into the vendor directory.  However, we also need to make some additional edits to this file.

Here is an example of a complete config file that we can use with Sugar.

custom/composer.json

{ 
   "require":{ 
      "symfony/yaml":"^2.8" 
   }, 
   "require-dev":{ 
      "inetprocess/libsugarcrm":"^1-beta" 
   }, 
   "autoload":{ 
      "psr-0":{ 
         "":"include/lib/" 
      } 
   }, 
   "autoload-dev":{ 
      "psr-4":{ 
         "Inet\\SugarCRM\\Tests\\":"vendor/inetprocess/libsugarcrm/tests/" 
      } 
   }, 
   "config":{ 
      "platform":{ 
         "php":"5.4" 
      } 
   } 
}

Importantly, using the config.platform.php setting above allows us to ensure everything downloaded is compatible with PHP 5.4 as required by the Sugar version we are using.

Since we want to follow PHP best practices, we can also add a folder to the autoloader to load our own PSR compliant classes and methods.

For example, we may create code with the Inet\MyLib namespace that we store at custom/include/lib/Inet/MyLib.

Also in the above example, we have included a dev dependency for inetprocess/libsugarcrm. This is an open source library that is helpful for writing Sugar unit tests for our customizations.

Adding Composer’s Autoloader using Utils Extension

Finally, we’ll ask Sugar to use Composer’s autoloader by using Sugar’s Utils Extension to include an additional autoloader.

custom/Extension/application/Ext/Utils/composer.php

<?php
require_once(__DIR__ . '/../../../vendor/autoload.php');

With this in place we can share everything between modules!

Using sugarcli to quickly set up Composer

If you want to automatically setup Composer for your Sugar instance, just use … sugarcli (https://github.com/inetprocess/sugarcli) !

Follow instructions on Github to download it, install it, and launch:

./sugarcli.phar code:setupcomposer --path <sugarcrm_path> --do
# Or, if it's in the path: sugarcli code:setupcomposer --path <sugarcrm_path> --do

That will check if the file exist, complete the installation or create both the files. It can even reinstall Composer if you want to start from scratch.


Adding a viewed status to Notes Module

$
0
0

Here is another guest post from Shijin Krishna from BHEA, an Elite SugarCRM Partner!

Notes is a common module used to track ad hoc information within Sugar. Sugar Enterprise customers that use the Customer Self-Service Portal will notice that comments logged in that system appear as Notes within Sugar.  So making sure there are not any unread Notes can be important daily task for these users. But how do you know if you have viewed each Note already?

In this post we are going to explore how we can add Read and Unread statuses to the Notes module.

This idea is taken from the Sugar Notifications Module which also comes out of the box with Sugar. Basically we will have a new field type styled with Bootstrap labels. The Notes status field will be highlighted with a green label if it has been read and a red label if it is unread.

This new field will be available for Record, List and Subpanel List views. The status will automatically change to Read when any Sugar user opens and views a Note. Notes created through Customer Self-Service Portal will be marked Unread while those created in Sugar by regular Sugar users will be marked as Read.  However, Sugar users will also be provided the option to toggle this status by clicking the viewed status label.

We will also provide mass update functionality to update the status of many selected notes all at once!  Whew!

Step 1: Adding a new field for Notes Module

Our first step is to create a new status field for Notes module.

Navigate to Admin > Studio > Notes > Fields

Create a new drop down field with name ‘is_read_c’. Select the list name as ‘notifications_status_dom’. I have set the display label as ‘Status’. But you can change the label as per your wish. Also keep the Mass Update check box checked.

Step 2: Create new Read field type

Our next step is to add a new field type called Read for the Notes module. Our new field is_read_c will use this new field type.

Read Field Controller

custom/modules/Notes/clients/base/fields/read/read.js

Read Field Templates

Below we define detail and list view templates for the new field type.

custom/modules/Notes/clients/base/fields/read/detail.hbs

custom/modules/Notes/clients/base/fields/read/list.hbs

Step 3: Add Status field to Notes View metadata

Now we will add the status field to Notes module views through extensions. Below steps will explain you how to add the fields to record and list view. You can add the extension file to add the field to subpanels as well.

custom/Extension/modules/Notes/Ext/clients/base/views/record/record.php

recordview

Notes Read status on Record View

 

custom/Extension/modules/Ext/Notes/clients/base/views/list/list.php

notes_listview

Notes Read status on List view

Step 4: Add display labels for the new field type

Our final step is to define the display label for our new field using Language extension.

custom/Extension/modules/Notes/Ext/Language/sugarfield_is_read.lang.en_us.php

Step 5: Run Quick Repair and Rebuild

Finally, you will need to run Quick Repair and Rebuild in order to build your new extensions. You will also need to do a hard refresh of the browser page in order to load the updated JavaScript and CSS files.



Handling of JavaScript files in Sugar 7.7

$
0
0

This post is a follow up on a question we posed on the Sugar Developer Community.

The “Rebuild Minified JS Files” action is used to rebuild the contents of the jssource directory.

pastedimage_0

We are considering removing this particular action from the UI because, generally, rebuilding the minfied JS files is not something we would expect most users to need to do.  While customizing jssource files is not upgrade safe, we recognize some folks in Sugar Developer community may be using this action for one reason or another.

Where is JavaScript stored in Sugar?

As of Sugar 7.7, the application stores JavaScript in multiple locations on the filesystem.

Core JavaScript files are stored in many places: under the include directory, the vendor directory, under many modules subdirectories, etc.  We also separately store Sidecar framework JavaScript files under the sidecar directory.

Copies of unminified core JavaScript source files have traditionally been placed under the jssource directory.

At runtime, core JavaScript files are minified and concatenated into groupings stored under the cache directory.  The contents of the JavaScript cache are regenerated as needed at runtime.

The Sugar application generally only uses the JavaScript stored in the cache directory at runtime. For example, a browser page running Sugar does not refer to any files under the jssource path.

In reality, there is no compelling need to store JavaScript files in three different locations. We need only one copy of unminified sources and one copy of minified sources located under the cache directory.

Keeping copies of unminified source files in a separate location under jssource is superfluous and increases confusion about how JavaScript files are handled.

Changes for Sugar 7.7 release

The following actions have been removed from the Sugar Administration user interface in Sugar 7.7.  They are available under the Repair panel.

  • Rebuild JS Compressed Files
  • Rebuild Minified JS Files
  • Repair JS Files

These three actions all rebuild core JavaScript files based upon contents of jssource directory.  This is not necessary when the JavaScript in the cache directory gets rebuilt during a Quick Repair or at runtime as needed.

While they have been removed from the UI, these actions still exist and have just been deprecated. You can still manually run these JavaScript actions if needed.

Manually running these actions

As an example, you can navigate to the following URL to run the Repair JS Files action from your browser.

http(s)://path_to_sugar/index.php?module=Administration&action=RepairJSFile&type=replace&run_deprecated_feature=1

You may need to update your config_override.php file to include additional http_referer configuration if you encounter a Cross Site Request Forgery (XSRF) warning.  Directions are included on that warning page if you encounter it.

For example, here is a config that will allow localhost to run the Repair JS Files action.

config_override.php

<?php
$sugar_config['http_referer']['list'][] = 'localhost';
$sugar_config['http_referer']['actions'] =array( 'index', 'ListView', 'DetailView', 'EditView', 'oauth', 'authorize', 'Authenticate', 'Login', 'SupportPortal', 'LogView', 'SugarpdfSettings', 'saveftsmodules', 'SaveSequence', 'PasswordManager', 'LicenseSettings', 'Updater', 'Backups', 'Languages', 'Locale', 'Upgrade', 'repair', 'GlobalSearchSettings', 'Diagnostic', 'EnableWirelessModules', 'ConfigureTabs', 'UpgradeWizard', 'ConfigureShortcutBar', 'wizard', 'historyContactsEmails', 'GoogleOauth2Redirect', 'RepairJSFile' ); 

If the action was run successfully, you should see the expected message.

Screen Shot 2016-03-30 at 5.17.23 PM

Repair JS Files message

 

Changes in upcoming Sugar releases

The jssource directory will be remove completely.  Unminified sources will still be available outside of the cache directory.  We also will then remove the code related to the deprecated JavaScript repair actions because at that time they would have use.


Help plan UnCon @ SugarCon 2016!

$
0
0

Planning for this year’s UnCon is just beginning and we need your help!

What is UnCon?

Hosted by SugarCRM Engineering, UnCon is the developer conference within SugarCon. UnCon is your opportunity to learn, rub shoulders, and hack with the top developers and architects at SugarCRM. Whether you are a Sugar Developer ace trying to get answers to your deepest technical questions or a Sugar newbie trying to learn what the Sugar platform is all about, this where you can get the answers straight from the source.

This year it is again being held on June 14th and June 15th at the Hilton Union Square in San Francisco.

UnCon is your conference!

The Sugar Developer community (You!) helps plan this event each year. That is why we are using a new space in the Sugar Community as the place for us to engage with each other.

Participation in the UnCon community is free and open to anyone who has a SugarCRM.com account.  All you need to do is Log In or Register first if you do not have an account.

Let’s make this the best UnCon ever!

Calls to Action

Create new Ideas

Create new UnCon Ideas on how we can make this year’s UnCon awesome. You can vote on existing ideas too such as video recordings.

CreateIdeaUnCon

Vote in the Topic Survey

Vote on the topics you want to see presented or discussed at UnCon in the Topic Survey! Leave comments or create ideas if you do not see something you want to learn about listed.

UnConSurveyScreenshot

Ask Questions

Is there something you still want to know? Get answers to those burning UnCon Questions too.

UnConQuestions

RSVP for UnCon

Finally, if you are coming then please RSVP for the UnCon Events to let others know too! This way, your colleagues in the Sugar Developer community will see who else is going.

UnConEvents

We hope to see all of you there!


New SugarCRM sponsored open source projects!

$
0
0

At SugarCRM Engineering, open source is part of our DNA.

We build Sugar on open source technology and open standards. We host and run our software on open source platforms in Sugar On-Demand. And all of our developers use open source tools for developing Sugar and implementing CRM projects for our customers.

As much as we benefit from open source software, we are obliged to give back. We host a number of open source projects in our SugarCRM Github organization that are actively maintained by SugarCRM employees. We encourage everyone in the Sugar Developer community to collaborate with us on these projects!

Read more to find out about some brand spanking new SugarCRM open source projects.

Sucrose Charts

SugarCRM Engineering has built a custom D3.js based chart library that we use to build charts used in Sugar 7.  We are refactoring this code into a dedicated library used by Sugar product. This allows us to launch a new open source project for the benefit of anyone needing a localized, responsive, and easy to use HTML5 chart library.

Head over to Sucrose.io to see some live and interactive examples of Sucrose Charts in action!

Sucrose Chart

Sucrose Chart

We will explore how to leverage Sucrose Charts within Sugar code and in web application or framework in an upcoming post!  Stay tuned!

The Sugar REST Harness

SugarCRM Professional Services has created a REST API test automation framework that they use to test their Enterprise CRM projects.  We are now providing this code as a framework for any Sugar Developers out there looking for an easy and repeatable way to automate functional tests for Sugar REST APIs including custom or extended APIs.

This is going to be a great tool for any Sugar Developers looking to build a better automated test practice.  It also supports a variety of output formats which makes it an ideal Sugar REST API test tool to integrate with your DevOps or continuous integration process.

Check out the project README for usage instructions.

Updated Tidbit documentation

Tidbit is a great open source tool used widely by our Sugar Developer community to generate pseudo-random data in the Sugar database for testing purposes. Our Performance team has been enhancing this tool and put together some new and improved usage documentation.

This new Tidbit documentation is posted on the project’s Github wiki page.

 


Announcing the 2016 App Throwdown!

$
0
0

Welcome to the 2016 App Throwdown!

sugarcon-2016-icon-app-throwdown-1Submissions are now open for the 2016 App Throwdown! Our annual showcase of technology for the Sugar platform is always a crowd favorite. The App Throwdown is where customers, partners, and prospects get to see some of the coolest, most useful, and innovative extensions that drive business transformation, save costs, and close deals faster. Check out this overview document, then head on over to the How to Submit Your App to the App Throwdown! document to learn how to get started in the 2016 App Throwdown!

Don’t forget, you must be registered in the community to participate and submit an entry. No worries though! Registration is super easy–just fill out this form and validate your email. Also, there’s no cost to be a member of the community or participate in the App Throwdown.

Best in Class & Best in Show

This year’s categories will help align with the overall themes of SugarCon. From the submissions in each category your SugarCon team will select three finalists. These finalists will be reviewed by SugarCRM’s executive team, who will choose one entry from each category as “Best in Class.”  Each category winner will be invited to present on the main stage in front of the entire SugarCon audience to compete for the “Best in Show” award!

Power to the People!

uploadFor the first time ever the community also gets a voice for who will compete for the  “Best in Show” award!    Each submission will use a blog post in Welcome to the App Throwdown! space . This will give you, all of your colleagues, facebook friends, and twitter followers, the opportunity to “Like” your entry. When submissions close, the entry with the most “Likes,” will be designated “Community Favorite” and will be invited to show their stuff under the bright lights on SugarCon’s main stage! So go vote today!

Don’t wait to submit your application! This year’s deadline for all submissions is May 13!  Remember, the earlier you submit, the more time you have to get support and “Likes” on your entry.

The 2016 App Throwdown Categories

Category Description
Mobile CRM and the Internet of Things Are you helping design “wearable” CRM? Building a mobile cool app or a connector to help track and manage smart device data in Sugar? Then we want your submission! This category is all about innovative applications that take a unique approach to mobility and the Internet of Things.
Customer Insight We are looking for the latest and greatest in Sugar extensions and integrations that focus on everything from understanding the customer journey, to the 360 degree view of the customer, and predictive analytics. If you’re merging next-generation Business Intelligence with Sugar, this is your category!
Customer Engagement The way we connect, engage and solve customer issues is changing in an increasingly customer-controlled world. Are you extending Sugar’s engagement, service and support capabilities? Then submit your cool extensions here!
User Productivity The impact of digital, mobile, and cloud technologies is driving new interpretations of the modern workforce. If you have a connector or extension app that helps make CRM users more productive than or simply changes the way we can do business individual-to-individual in the modern age, then this is your category!

Submissions are open to… EVERYONE!

Like last year, submissions are open to EVERYONE! That’s right – anyone who wants to submit an extension, connector, custom app integration, or any other cool use of the Sugar platform, is eligible for consideration.

So what are you waiting for?

Want to throw it down with a submission?

Get started now!

Want to vote on submissions?

Learn more about the voting process and then go vote for your favorite app!

 


How to customize the Sugar PDF Manager

$
0
0

Here is another guest post from Cédric Mourizard from the Elite SugarCRM Partner Synolia.  Cedric is a well recognized expert on the Sugar PDF Manager.

In regard to some recent questions from Sugar Community stalwart, Francesca Shiekh, we will address some questions about how to deal with the PDF Manager that was originally introduced in Sugar 6.

A Common Use Case

In this article we want to resolve this common use case for customizing the PDF manager. When following up on a meeting, you want to be able to generate an attractive summary document that lists all the meeting details included lists of those who were invited or attended.

We will customize the PDF manager so that we can print a meeting summary for any Meeting record that will have all contacts and invited users listed.

Understanding PDF Manager and extending it

Sugar uses two important 3rd party libraries as part of the PDF Manager implementation. Note that Sugar 7.6.2.1 uses TinyMCE 3.5.8 and TCPdf 4.6.013.  These are not the latest available versions of these libraries.

The architecture of the SugarPDF API is described in the Developer Guide.  It can be customized in the usual way by creating your custom code at a special location under Sugar’s custom directory. We need to create a file at custom/modules/Meetings/sugarpdf/sugarpdf.pdfmanager.php where we can implement our logic to add related record information for the meeting:

<?php

require_once 'include/Sugarpdf/sugarpdf/sugarpdf.pdfmanager.php';

class MeetingsSugarpdfPdfmanager extends SugarpdfPdfmanager
{
    public function preDisplay()
    {
        parent::preDisplay();

        $previewMode = false;
        if (!empty($_REQUEST['pdf_preview']) && $_REQUEST['pdf_preview'] == 1) {
            $previewMode = true;
        }

        if ($previewMode === false) {

            // Select links to add
            $linksToLoad = array('contacts', 'users');

            foreach ($linksToLoad as $linkName) {
                /** @var Meeting $this->bean */
                $this->bean->load_relationship($linkName);
                $linkedBeans = $this->bean->$linkName->getBeans();

                // Prepare data
                $linkedData = array();
                foreach ($linkedBeans as $linkedBean) {
                    $linkedData[] = PdfManagerHelper::parseBeanFields($linkedBean, true);
                }

                // Assign data to template
                $this->ss->assign($linkName, $linkedData);
            }
        }
    }
}

Now we can create our PDF template based on the Meeting module with the PDF Manager which can be found in the Administration panel:

<h1>Meeting Summary</h1>
Topic:&nbsp;{$fields.name}<br />
Description:&nbsp;{$fields.description}<br />
{if isset($contacts) and $contacts|@count gt 0}
<br />
<h2>Contact Guests</h2>
<table style="width: 100%;" border="0">
    <tbody>
        <tr>
            <td><strong>Name</strong></td>
            <td>Email</td>
            <td>Phone</td>
        </tr>
        <!-- {foreach from=$contacts item="contact"} -->
        <tr>
            <td>{$contact.full_name}</td>
            <td>Email {$contact.email1}</td>
            <td>{$contact.phone_work}</td>
        </tr>
        <!--  {/foreach} -->
    </tbody>
</table>
{/if} {if isset($users) and $users|@count gt 0}
<br />
<h2>User Guests</h2>
<table style="width: 100%;" border="0">
    <tbody>
        <tr>
            <td><strong>Name</strong></td>
            <td>Email</td>
            <td>Title</td>
        </tr>
        <!-- {foreach from=$users item="user"} -->
        <tr>
            <td>{$user.full_name}</td>
            <td>{$user.email1}</td>
            <td>{$user.title}</td>
        </tr>
        <!-- {/foreach} -->
    </tbody>
</table>
{/if}

Hey! When I copy and paste this code into the WYSIWYG editor it doesn’t appear the same! What is going on here?

You are right! By default TinyMCE will add an HTML p tag on every line. To avoid that you can adapt the configuration by creating a file at custom/include/tinyMCEDefaultConfig.php

<?php

$defaultConfig = array(
    'forced_root_block' => '',
);

Want to learn more about TinyMCE configuration in Sugar? Do not hesitate to read the world famous Sugar Developer Guide section on Modifying TinyMCE Editor!

Tips for your own Templates

You can follow some of these tips when you are thinking about creating a new template:

  • Use HTML comment tag to add Smarty operators where you want
  • Use inline styles instead of a CSS declaration
  • Remember that PDF generation is performed using the language selected by the current user

Do not forget to perform a Quick Repair and Rebuild to make your customizations available for the application.

Enjoy your new PDF summary for your meetings!


Viewing all 93 articles
Browse latest View live