Skip navigation
All Places > Developer > Blog
1 2 3 Previous Next

Developer

158 posts

For years SugarCRM has published database schema information for each new Sugar release at apidocs.sugarcrm.com. Generated documentation, like our database schema reference, has largely taken a back seat to more formal documentation like the Sugar Developer Guide and Sugar Developer training curriculum over at Sugar University.

 

Over the past couple of releases, we have improved the Sidecar framework code to have better structure and code documentation while preserving compatibility. One of the benefits has been a significant improvement in the quality of our generated Sidecar JavaScript documentation when using tools like JSDoc.

 

Anyone can now view the documentation at anytime for each new Sugar release without having to manually generate the documentation!

 

If you visit SugarCRM Generated Documentation, you will find the Sugar 8.0.0 Sidecar framework documentation available today. We will be publishing the generated Sidecar framework documentation for each new release in the future.

 

We plan to continue to invest in the quality and quantity of generated API references that we publish for each release.

Yes, you read that right!  We have not one but TWO ways for Sugar developers to earn a FREE pass to SugarCon 2018 in Las Vegas, Nevada.  

Speak at SugarCon!

SugarCon is evolving, and we want you to be part of it!  

 

We know that you, our Sugar Developers, are in the trenches everyday--solving customer problems, designing ways to make your jobs easier, and innovating.  You have expertise to share, and we want to hear it! We’ve created a list of suggested topics, but we encourage you to submit any talk that you would want to see at SugarCon.  Suggested topics include:

  • What you wish you knew about Sugar before you started
  • Best practices and war stories around Sugar customization or integrations
  • Tools you use to work with Sugar
  • Building a highly functional Sugar development team
  • Tips for working in Sugar Cloud

 

In addition to all of the amazing keynotes, networking opportunities, and lunchtime table topics at SugarCon, we are planning to have sessions specifically for developers.  This is where we want your expertise! You can expect that the audience at these developer focused sessions will be technical and have a copy of Sugar installed on their laptops with the Professor M’s School for Gifted Coders module loadable package and sample data installed.  Our goal is for these sessions to be hands-on or interactive. Bonus points if you leverage Professor M’s School for Gifted Coders as your example! Sessions will be 45 minutes long if we pair you with a SugarCRM co-speaker or 20 minutes long if you speak solo.

 

Our call for speakers is officially open at sugarcon.com.  Click the Tell Your Story button and tell us what you want to speak about.  In your submission’s description, be sure to indicate that this is a developer focused session.

 

We will be accepting submissions through July 13, 2018.  Availability is limited, so please make your submissions as compelling as possible.  

 

We’re excited to see your proposals!

 

Become a Sugar Scholar!

We’re excited to be introducing the Sugar Scholars program.  Sugar Scholars are people who are advocates for Sugar all year round and want to help make SugarCon as amazing as possible.

 

You might be a Sugar Scholar if…

  • You are an active member of our Developer Community.
  • You rack up tons of points in Sugar Insiders.
  • You frequently blog about Sugar.
  • You create engaging videos about Sugar.
  • You can’t stop Tweeting about Sugar.
  • You lead Sugar meetups.

 

Sugar Scholars will be involved in assisting with SugarCon on both days of the conference.  They may be asked to do things like the following:

  • Facilitate lunchtime table topics for developers
  • Greet developers at the developer-focused lunches, sessions, and happy hours
  • Give a 5-minute lightning talk

 

If you think you have what it takes to be a Sugar Scholar, fill out this form by July 13, 2018.

We've already begun preparations for SugarCon in fabulous Las Vegas, Nevada, and we REALLY want to see YOU there.  That's why we have a promotion just for you, our favorite developers! 

 

From now until June 30, developers can register for SugarCon for only $400 when someone else from their company registers at the published rate for the Full Conference or VIP Full Conference (limit one discounted developer registration per Full Conference or VIP Full Conference registration).  To take advantage of the discount for developers, your colleague should register for SugarCon at the published rate.  Then email us at sugarcon@sugarcrm.com with your colleague's name and indicate you'd like the promo code for developers.  We'll reply with the promo code you need in order to register.

 

To make this deal even sweeter, Sugar Insiders can currently get our early-early bird rates for the Full Conference through June 30.  Not yet a Sugar Insider?  No problem!  Sign up here!  Once you're a Sugar Insider, email sugarcon@sugarcrm.com to extend our early-early bird rate of $600 per registrant until June 30, 2018.

 

Need help convincing your boss to bring you?  We've written this handy letter you can customize and send to your boss:

 

Hello, [your boss’s name] - 
I’d like to attend SugarCon 2018 on October 10-11, 2018 in Las Vegas, NV. SugarCon is the annual conference for Sugar users, experts, SugarCRM staff, thought leaders, and developers. 
I’d like to attend SugarCon for several reasons. There are multiple ways that my attendance can benefit [your organization’s name].
These include:
I’ll be a producer for the team - In addition to hands-on training, there will opportunities to engage with new tools and techniques in order to improve our current implementation.
I’ll learn more about CRM - SugarCon has sessions on challenges+solutions, sessions on practical pieces of the system as well as sessions on possible future projects. There will be panel sessions as well on how other brands are using the system to create real business outcomes.
I’ll connect with and learn from my networks - SugarCon will have people across various industries, roles, company sizes, and ages of deployment. I’ll be able to exchange ideas within these various groups in order to solve our unique business challenges. Plus, there will be networking events and sessions just for developers, so I can connect with other people tackling the same challenges I am.
The investment is approximately $XXXX.XX, which includes the discounted registration fee, air travel, hotel nights at the Cosmopolitan under the group block, and transportation between the airport and hotel.
As a developer, if I attend with someone else from our company, I can take advantage of a discounted registration fee just for developers and the investment for me goes down to $XXXX.XX.
I look forward to growing professionally and strengthening my network at SugarCon!  Thank you for your consideration!

 

We can't wait to see you in Las Vegas in October!

Hey there, developers!  We've officially released Sugar 8.0.0 (Spring '18)!  This is our third quarterly release for Sugar Cloud (formerly known as Sugar On-Demand).  We're on a roll!  This release is also our yearly release for our on-prem customers.

 

This release has a ton of great features, but we're most excited about all of the work we put in to data privacy around the General Data Protection Regulation (GDPR).  If GDPR is just a random smattering of letters to you, check out Matt's blog posts on the subject.

 

Our Co-Founder & CMO, Clint Oram, discusses the highlights of this release from an end-user's perspective in the video below:

 

 

Matt Marum and I recently hosted a webinar where we gave an overview of the big things developers need to know about this release:

 

 

The slides from the webinar are available here.

 

If you're looking for the high-level overview, I've got your covered!

  1. In order to support the GDPR and other data privacy regulations, we added a Data Privacy module and a Data Privacy Manager role.  We added additional features like the ability to opt-out new email addresses by default, mark fields as containing personally identifiable information (PII), disable activity streams, track additional context in audit logs, and view and permanently erase PII.  For more information, see Data Privacy and GDPR in Sugar.
  2. We made updates to the audit data model to better support tracking information about changes.
  3. We implemented semantic versioning for our REST API and introduced v11.1.
  4. We added a new option to configure API platforms in the Admin interface.  Integrations that use custom platforms no longer need to create a custom module loadable package in order to register their custom platforms; the platforms can be registered in the Admin interface instead.
  5. To improve performance, ./cache/file_map.php has been removed and many SugarAutoloader functions have been deprecated and now do nothing. We also recommend disabling the 'block_nested_loop' optimization in MySQL.
  6. Be sure to check the updated list of supported platforms.  Note that we have dropped support for PHP 5.6 and Elasticsearch 1.7.5.
  7. We will not be posting this release in the Developer Builds community since it will be available in the Sugar Store.

 

This blog post promised to have just about everything you need to know about the Sugar 8.0.0 (Spring '18) release.  Below are some resources that have the rest of the details.

 

We hope you’re as excited about this release as we are!

As discussed in Why SugarCRM developers should care about Data Privacy and GDPR, data privacy is an important topic that we are going to keep discussing here on the developer blog. Today is another installment specifically focused on best practices for getting consent to collect and process personal information.

 

General Data Protection Regulation (GDPR) has strict requirements for consent. However, consent to personal data processing is a big topic for regulation in many countries and especially applies to email marketing. Under GDPR, unless you have an existing lawful basis for using personal information, you need to collect explicit consent from the data subject when storing and processing their information in Sugar. By explicit consent, we mean it was freely given, informed, affirmative, and unambiguous. For example, a web to lead form with a pre-selected opt-in checkbox is not going to cut it in the EU, Australia, or Canada.

 

Let's look at a couple different ways of collecting explicit consent.

 

Collecting explicit consent

 

Collecting explicit consent is particularly important for marketing campaigns and business development. For other CRM use cases (like customer support), you may already have another lawful basis that gives you the right to process customer information.

 

Consent really just boils down to allowing someone to knowingly and freely give their permission for you to use their personal information. You could collect consent over the phone, written in an email, or over a handshake in person.

 

It is possible to collect explicit consent with a properly designed web form as well. There are lots of resources out on the web with advice for building compliant Single Opt-In (SOI) web forms.

 

However, a common practice for collecting consent is to use Double Opt-In (DOI) which is also known as Confirmed Opt-In (COI).

 

Double Opt-In (aka Confirmed Opt-In)

 

We all know web forms aren’t perfect. Sometimes users aren’t sure what they are signing up for themselves. Maybe they mistyped their email address and now somebody else is signed up for that mailing list. Or worse, somebody is a troll and intentionally signing them up for email or services that they don’t want. There is a better way and it is called double opt-in.

 

Double opt-in (or Confirmed Opt-In) essentially means that someone who puts their personal information into a web form must confirm twice. A user enters their information on a form and affirms that they want to subscribe to a service. They then get a confirmation email, text message, or some other communication where they can re-confirm their intention. This is typically done by providing a link in an email that users must then click to confirm.

 

Double opt-in is an easy way to ensure you have a clean mailing list or lead list full of people who went through the trouble to confirm twice.

 

Many of our customers use marketing tools such Act-On, Marketo, and others to manage their mailing lists and the necessary opt-in processes. As an added feature to Sugar’s Marketing capabilities, we are planning to include DOI/COI in a subsequent release. Meanwhile, here is how you can achieve DOI/COI with Sugar 8 or Spring ‘18.

 

Adding Double Opt-In to Sugar 8.0.0

 

If you have access to the Sugar 8 Preview then this is something you can try today. Otherwise you will need to wait until the official release in a couple short weeks.

 

This customization implements double opt-in behavior for specific email addresses stored within Sugar. The steps below involve Sugar Studio configuration changes as well as code level customizations. This example allows for any email address to be subject of a confirmed opt-in flow without any specific dependencies on Campaigns, web to lead forms, Leads, Contacts, etc. Note that since this customization is focused on the confirmation step of double opt-in so for this reason we prefer the term “Confirmed Opt-In”.

 

Once you have followed the steps below, you will be able to generate confirmation messages for new email addresses. For each email address that needs to be confirmed, there will be an associated URL that, when clicked, will confirm and opt-in the associated email address.

 

Step 1) Configure your lead forms or integrations to opt-out by default

 

You need to take some steps to make sure that email addresses are not prematurely opted-in within Sugar.

 

In Sugar administration, visit the “System Email Settings” panel and make sure “Opt-out new email addresses by default” is checked. You may need to enter SMTP Mail Server settings in order to save this change on this page. This is a new setting in Sugar 8.0.0.

 

 

If you are using Sugar web-to-lead forms, they should be updated to remove the email opt-in checkbox that Sugar includes by default if it still exists. I’d recommend updating the form to let the user know that a confirmation email will be sent separately.

 

 

If you are using some other system (like a lead portal or marketing automation tool) to capture contact information, they should be configured to not send back email opt-out information to Sugar. Or alternatively they could be configured to set email opt-out to true by default.

 

Step 2) Add Studio configuration changes to Data Privacy module

 

In this example, we will reuse the Data Privacy module (new in Sugar 8.0.0) to track email confirmation activities. If you haven’t already, you may need to add the Data Privacy module to the list of displayed modules in the Administration panel first.

 

Add a new “Confirmed Opt In” option to the dataprivacy_type_dom used by the Data Privacy module’s type field. This will be used to differentiate email confirmations from other Data Privacy activities.

 

 

Also add two new custom fields that are visible only for Confirmed Opt-In activities. To do this, I used the following visibility formula on these custom fields.

 

equal($type, "Confirmed Opt In")

 

The first is an email_address_to_confirm_c text field that stores the record ID for the email address that needs to be confirmed.

 

 

The second is a URL field called confirmation_url_c that will use a generated URL. The default value is designed to pass email_address_to_confirm_c field and the Data Privacy id field as parameters to a custom entry point that we will create later. The URL will vary based upon the site URL for your Sugar instance. For my development environment, I used:

http://localhost:8080/sugar/index.php?entryPoint=confirmEmail&email={email_address_to_confirm_c}&id={id}

 

 

Make sure to add these two new fields to your Data Privacy record layout as well which will help us with testing. Remember to Save and Deploy after adding them.

 

 

Step 3) Add the ConfirmedOptInManager class and related Entry Point

 

The following class includes two optional logic hooks as well as a required method that will be used by a new Entry Point. We are choosing to use a custom Entry Point here instead of a REST API endpoint because the Sugar REST API is designed to only return JSON responses. This makes for a poor usability experience for the person who is trying to confirm their email address and sees a page full of gobbledygook in their browser. Typically, people will expect to see a nicely formatted web page with a confirmation message. An entry point allows us to return an HTML response that matches user expectations.

 

The createConfirmedOptIn() method can be used as an after_save hook on the Leads module to automatically create a confirmed opt-in activity whenever new Lead records are created.

 

The sendConfirmOptInMessage() method is a stub that can be used as an after_save hook on the Data Privacy module to automatically send confirmation emails to end users. This could also be orchestrated using an Advanced Workflow.

 

The last confirm() method is the most important one. This method is called directly by a custom public entry point shown further below. This is what determines if the request is a valid one and then updates the email address record. It first loads the DataPrivacy bean, then compares the email address ID stored there with the one provided in the URL. It then updates the EmailAddress and DataPrivacy beans accordingly.

 

./custom/Extension/modules/Leads/Ext/LogicHooks/createConfirmOptInRecord.php

 

<?php
// Copyright 2018 SugarCRM Inc.  Licensed by SugarCRM under the Apache 2.0 license.
$hook_array['after_save'][] = array(
  1,
  'create_confirmation_record',
  null,
'Sugarcrm\\Sugarcrm\\custom\\ConfirmedOptIn\\ConfirmedOptInManager',
  'createConfirmOptInRecord',
);

 

./custom/Extension/modules/DataPrivacy/Ext/LogicHooks/sendConfirmOptInMessage.php

 

<?php
// Copyright 2018 SugarCRM Inc.  Licensed by SugarCRM under the Apache 2.0 license.
$hook_array['after_save'][] = array(
  1,
  'send_confirmation_message',
  null,
'Sugarcrm\\Sugarcrm\\custom\\ConfirmedOptIn\\ConfirmedOptInManager',
  'sendConfirmOptInMessage',
);

 

./custom/src/ConfirmedOptIn/ConfirmedOptInManager.php

<?php
// Copyright 2018 SugarCRM Inc.  Licensed by SugarCRM under the Apache 2.0 license.
namespace Sugarcrm\Sugarcrm\custom\ConfirmedOptIn;

/**
*
* Manages confirmed opt-in workflow for Email addresses
*
* Class ConfirmedOptInManager
*/

class ConfirmedOptInManager
{

    /**
     * After Save logic hook on Leads module (or any other Person module with an email address)
     *
     * Used to automatically create email confirmation records in DataPrivacy module.
     *
     * @param \SugarBean $bean SugarBean with an email address that needs to be confirmed.
     * @param string $event Logic hook event name. Expected to be 'after_save'.
     * @param array $arguments
     */

    public function createConfirmOptInRecord(\SugarBean $bean, string $event, array $arguments)
    {
        //If this is a newly created record
        if (!$arguments['isUpdate'] && $bean->load_relationship('emails')) {
            $address = $bean->emailAddress->getPrimaryAddress($bean);
            //And a primary email address is set
            if (!empty($address)) {
                //Create a new 'Confirmed Opt In' DataPrivacy activity
                $dpb = \BeanFactory::newBean('DataPrivacy');
                $dpb->name = "Confirm $address";
                //Note: This assigned user for Data Privacy activity MUST have the Data Privacy Manager role!
                $dpb->assigned_user_id = $bean->assigned_user_id;
                //We will store ID for primary address here.
                $dpb->email_address_to_confirm_c = (new \SugarEmailAddress())->getGuid($address);
                $dpb->type = 'Confirmed Opt In';
                $dpb->save();
            }
        }
    }


    /**
     *
     * After save logic hook on Data Privacy module
     *
     * Can be modified to send the confirmation message to the appropriate email address.
     * You should make sure not to send multiple messages for the same Data Privacy request.
     *
     * @param \DataPrivacy $bean DataPrivacy bean that has been saved
     * @param string $event Logic hook event name. Expected to be 'after_save'.
     * @param array $arguments
     */

    public function sendConfirmOptInMessage(\DataPrivacy $bean, string $event, array $arguments)
    {
        //Should only continue if this is a newly created Confirmed Opt In request
        if ($bean->type === 'Confirmed Opt In' && !$arguments['isUpdate']) {
            $log = \LoggerManager::getLogger();
            $eab = \BeanFactory::retrieveBean('EmailAddresses', $bean->email_address_to_confirm_c);
            if (!empty($bean->email_address_to_confirm_c) && !empty($eab->email_address)) {
                $log->info(
                    "Send out confirmation to $eab->email_address with link to $bean->confirmation_url_c."
                );
                // You could update to send message using mailer, SMS gateway, whatever.
            }
        }
    }

    /**
     *
     * Opt-in the email address if the email associated with given requestID matches the given emailAddressID
     *
     * Used with `confirmEmail` public custom entry point
     *
     * @param string $requestId
     * @param string $emailAddressId
     * @return bool
     */

    public function confirm(string $requestId, string $emailAddressId): bool
    {
        global $current_user, $timedate;
        // Since this is a public endpoint, we need to select a current user to associate with this action.
        // For our purposes, we will use the User assigned to the Data Privacy request since the person confirming
        // their email address is likely not a current Sugar user.
        // Note: For this to work, assigned/current user must be admin or have Data Privacy Manager role!
        if ($current_user && empty($current_user->id)) {
            $q = new \SugarQuery();
            $q->from(\BeanFactory::newBean('DataPrivacy'), array('team_security' => false));
            $q->where()->equals('id', $requestId);
            $q->select(array('assigned_user_id'));
            $results = $q->execute();
            //If no assigned user, then default Admin user will be used.
            $assignedUserId = empty($results) ? 1 : $results[0]['assigned_user_id'];
            $current_user = \BeanFactory::retrieveBean('Users', $assignedUserId);
        }

        $confirmRequest = \BeanFactory::retrieveBean('DataPrivacy', $requestId);
        //Make sure email address matches the one associated with the request ID
        if ($confirmRequest && $confirmRequest->email_address_to_confirm_c === $emailAddressId) {
            //If already closed, then no need to re-confirm.
            if ($confirmRequest->status === 'Closed') {
                return true;
            }
            $addrBean = \BeanFactory::retrieveBean('EmailAddresses', $emailAddressId);
            $addrBean->opt_out = false; //opt in!
            $addrBean->save();
            $confirmRequest->status = 'Closed';
            $currentTime = $timedate->getNow();
            $confirmRequest->resolution = 'Confirmation received on ' . $currentTime->format(DATE_RFC850);
            $confirmRequest->date_closed = $currentTime->asDbDate();
            $confirmRequest->save();
            return true;
        }
        return false;
    }

}

 

The last file is our public custom entry point, which we install with the help of the EntryPointRegistry extension. This will allow us to create a publicly accessible URL on our Sugar instance that can be used to easily display HTML for a user readable response.

 

./custom/Extension/application/Ext/EntryPointRegistry/confirmEmail.php

 

<?php
// Copyright 2018 SugarCRM Inc.  Licensed by SugarCRM under the Apache 2.0 license.
$entry_point_registry['confirmEmail'] = array(
'file' => 'custom/src/ConfirmedOptIn/ConfirmEmailEntrypoint.php',
'auth' => false
);

 

Since this is a public entry point, we should take extra care to validate user input. We will use the InputValidation framework to assert that the URL parameters are both the GUIDs that we expect for record IDs.

 

./custom/src/ConfirmedOptIn/ConfirmEmailEntrypoint.php

 

<?php
// Copyright 2018 SugarCRM Inc.  Licensed by SugarCRM under the Apache 2.0 license.
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

use Sugarcrm\Sugarcrm\Security\InputValidation\InputValidation;
use Sugarcrm\Sugarcrm\custom\ConfirmedOptIn\ConfirmedOptInManager;

$manager = new ConfirmedOptInManager();
$validator = InputValidation::getService();

$recordId = $validator->getValidInputGet('id', 'Assert\Guid');
$emailId = $validator->getValidInputGet('email', 'Assert\Guid');

if ($manager->confirm($recordId, $emailId)) {
    echo "<h1>Confirmed!</h1>";
} else {
    echo "<h1>Unable to confirm.</h1>";
}

 

This page will just show “Confirmed!” if the email address was properly confirmed and “Unable to confirm.” if the confirmation failed which could be due to badly formed request or because the email address or data privacy record IDs didn’t already exist in the system. You could update this entrypoint to return whatever HTML you want or perhaps even to redirect the person’s browser to some other page.

 

For example,

 

header("Location: http://www.example.com/success");

 

If you happen to see a blank page, then input validation has probably failed. You can check for a fatal message in sugarcrm.log for more details on the failure.

 

Step 4) Try it out!

 

Create a new Lead record that includes a new email address.

 

New Lead record

 

Switch over to Data Privacy module and you will find a new Data Privacy record like the one below.

 

 

For convenience, we can just click the confirmation URL itself to trigger the confirmation check of using an email to do it. In a real implementation, it may make sense to hide this URL from Sugar end users so they do not accidentally click on it since we expect someone who does not use Sugar to click it themselves.

 

 

Nice, it was confirmed! If the request isn’t quite right or the email address is not in the system then you will get the “Unable to confirm” message instead.

 

If I return to my Data Privacy record, then I can see it has been completed and that the email address on my original Lead record has been opted in.

 

 

There is a lot that could or should be done to enhance this example for production use. But you can see that the pattern is straightforward to implement using existing Sugar platform extensions and APIs.

While we introduced PHP 7.1 support in the Sugar 7.9.0 release back in May 2017, we have up until now continued to support PHP 5.6. But PHP 5’s days are numbered. We will be dropping support for PHP 5.6 in the Sugar 8 and Spring ‘18 releases. Sugar 8.0.0 and Spring ‘18 will only support PHP 7.1. Long live PHP 7!

 

In the Sugar cloud, we have been migrating from PHP 5.6 to PHP 7.1. With this transition, we have discovered some additional PHP 7 pitfalls that we want to make sure everyone avoids in their Sugar customizations. These problems affect any version of Sugar that uses PHP 7. They are both centered around a new ArgumentCountError that was introduced in PHP 7.1.

 

If you haven’t already, you should check out the old blog post we did on preparing customizations for PHP 7. There are lots of benefits for using PHP 7 with Sugar. Not only are there performance improvements but Sugar code as well as customizations are now able to take advantage of more advanced PHP language features.

 

Let’s take a look at the two pitfalls we want to help you avoid.

 

Do not use deprecated PHP 4 style constructors in Logic Hooks classes

You should not be using PHP 4 style constructors in PHP 7 at all, but there is an additional complication that is introduced when you are using Logic Hooks with PHP 7.1.

 

Take the following example:

 

class Hook {
    public function hook($bean, $event, $arguments)
    {

    }
}

 

The issue here is rooted in the fact that functions and classes in PHP are case insensitive.  The hook() function contained within the Hook class is interpreted as a PHP 4 style constructor even though the names differ in case.

 

For logic hook code where the class name and function name differ only in case, it would cause Sugar to throw fatal PHP errors in PHP 7.1 and warnings in earlier PHP versions. Since the class name and function name does not match in the example, Sugar will not recognize hook() as a constructor. So Sugar will first instantiate the Hook object and then subsequently call the hook() function later. But PHP recognizes hook() as a constructor. So PHP would instantiate a Hook object without passing the needed arguments to hook(). Calling a function with an incorrect number of arguments in PHP 7.x throws a fatal ArgumentCountError.

 

When using PHP 5 with Sugar, this would generate a PHP warning and ultimately the hook() function would be called twice; once with no arguments for the constructor and then a second time with arguments to process the hook.

 

So there’s all kinds of things going wrong here in this very brief example.

 

For compatibility reasons, we have fixed this case sensitive behavior where we will only call this function once in Sugar 8.0.0 but even then you are still using a deprecated PHP 4 constructor in PHP 7. This is either unintentional or simply a bad idea.

 

You must use function names that are different than your class names in your Logic Hook classes.

 

We can easily fix the example above by changing the function name.

 

class Hook {
    public function afterSave($bean, $event, $arguments)
    {

    }
}

 

 

Do not define too many arguments for Logic Hooks functions

Now we should take a look at another issue that will throw an ArgumentCountError.

 

class Hook {
    public function afterSave($bean, $event, $arguments, $customArgs)
    {

    }
}

 

The developer who wrote the afterSave() function above may have been trying to save time by adding the $customArgs argument to a standard after_save module logic hook function to handle some alternative usages. The issue is that Sugar is going to call this logic hook function with three arguments instead of four, which will throw an ArgumentCountError in PHP 7.1. In PHP 5, a warning is simply logged and the function is still executed.

 

It should go without saying that functions should be called with the correct number of arguments.

 

¯\_(ツ)_/¯

 

We can fix the example above to ensure that functions can always be called with the correct number of arguments.

 

class Hook {

    public function afterSave($bean, $event, $arguments)
    {
        $this->otherSave($bean, $event, $arguments, array());
    }

    public function otherSave($bean, $event, $arguments, $customArgs)
    {

    }

}

 

You must ensure that your Logic Hook functions use the correct number of arguments.

 

For most logic hook events that is three arguments but sometimes it is two! Check the event definitions in the Logic Hooks section of the Developer Guide if you aren’t sure how many arguments are required!

 

Recap

Let’s recap what you should do to prepare your Logic Hooks for PHP 7.1:

  • Ensure that none of your Logic Hook classes contain functions have the same name as the class. Remember that PHP is case insensitive when it comes to class and function names.
  • Ensure that your Logic Hook functions use the correct number of arguments.

Hi there, Sugar Developers!

 

We want to make sure your customizations and integrations are ready for the Sugar 8 and Spring ‘18 releases, so we’re hosting two webinars just for you!

 

Webinar Topics

We’ll discuss the big changes that are likely to impact you including the following:

  • Review Data privacy features used for GDPR compliance (if you’re not thinking about this, you probably should be!)
  • New Sidecar components and features that support Data Privacy
  • New Admin panel to register custom API platforms
  • Changes to Audit APIs, data model, and behavior
  • Changes to supported platforms and libraries
  • Update on the Professor M School

 

Webinar Information:

We are holding 2 sessions to accommodate various geographical locations. Please choose ONE of the following times below.

Monday, April 23nd 6:00 PM - 7:00 PM PT

OR

Tuesday, April 24rd 8:00 AM - 9:00 AM PT

(Choose one)

 

Register Here


We will be posting the webinar recordings here in the Developer space for those who are unable to attend the live sessions.

Post originally written by avlasovsugar.

 

Alex Vlasov is an experienced Sugar Developer and contractor that works on the SugarCRM Engineering platform team. In this post, Alex shares advice to Sugar Developers for preparing their Sugar customizations for PHP 5.6 and PHP 7.

 

The Sugar team has been preparing core Sugar code for PHP 5.6 and PHP 7 support with an eye on deprecating support for older PHP versions. This means there are some actions that the Sugar Developer community needs to take in order to prepare their code for latest versions of PHP.

 

Summary of core Sugar app changes

 

In order to support newer versions of PHP, we made some changes to internal core classes that Sugar Developers need to know about. Many of these changes were made in Sugar 7.7.1 when we added PHP 5.6 support. Other changes outlined below are in upcoming Sugar releases.

 

PHP 7 deprecated features removed from core Sugar code

  1. Removed static calls to non-static methods
  2. Removed PHP4-style constructors

 

Read the full list of features deprecated in PHP7.

 

Additional changes to address core Sugar code hygiene and to adopt new PHP 7 features

  1. Fixed incompatible child class methods signatures
  2. Updated 3rd party libraries to support latest versions of PHP
  3. Changes to support PHP 7.0 new uniform variable syntax
  4. Adopted PHP 7's CSPRNG API but added random_compat library to support older PHP versions

 

Actions for Sugar Developers

 

In order to properly upgrade custom code, two main tasks need to be performed:

 

Make your code compatible with PHP 5.6 and PHP 7.0

 

To make your code compatible with PHP 5.6 and 7.0, use the following checklist.

  1. Remove static calls to non-static methods within your PHP code
  2. Remove any use of PHP4-style constructors within your PHP code
  3. Remove other deprecated PHP functionality in your PHP code (PHP 5.6 deprecated features, PHP 7 deprecated features)

 

For example,

 

class Foo {

public function __construct() { // Yes.
// ...
}

public function Foo() { // No.
// ...
}

    public static function aStaticMethod() {
        // ...
    }

    public function aNormalMethod() {
    // ...
    }

}

Foo::aStaticMethod(); // Yes.

Foo::aNormalMethod(); // No.

 

 

 

For additional detail, refer to PHP migration guides for PHP 5.6 and PHP 7.0.

 

Make your code compatible with changes to Sugar PHP APIs

 

To make custom code compatible with updated Sugar PHP APIs, use the following checklist.

  1. (7.7.1) Do not use old PHP4 constructors in Sugar PHP classes, they are removed as part of PHP 7.0 support.
  2. (7.7.1) If there is code that extends Sugar PHP classes, make sure child methods signatures are correct
  3. (7.7.1) 3rd party libraries were moved:
    1. parsecsv library was moved to the vendor directory
  4. (future) 3rd party libraries updates:
    1. Elastica library will be upgraded, so make sure you do not use deprecated Elastica APIs.
    2. Removal of mcrypt support and Crypt_Blowfish library, so make sure you are not calling these libraries directly.
  5. (future) Significant changes to be made to the following Sugar PHP APIs:
    1. ActivitiesApi::getQueryObject() will become protected and function arguments are changed
    2. RelationshipHandler class will stop extending Relationship class
    3. SearchForm class will not extend EditView class anymore
    4. Quarter*TimePeriod::buildLeaves() methods will have function arguments changed
    5. PMSEEngineFilterApi::addFieldFilter() method will be renamed

Sugar is a fantastic product that is built on a powerful platform! As Director of Solutions Consulting for the Americas and an architect by trade, I am often asked to describe Sugar's platform for a variety of audiences. I have a standardized presentation that I give that provides an overview of Sugar's platform from a beginner's point of view. It covers the topics that I get asked about the most.

 

Looking for a concise overview of the components in the Sugar platform and the key highlights that makes Sugar so popular? Then this is the video for you! 

 

The topics it covers are:

  • Platform layers (top to bottom look)
  • Overview of Sugar's framework
  • Mobility
  • Security (Authentication and Access Control)
  • Open Cloud Strategy (hosting)

 

I hope you all find this valuable. As the platform grows, this presentation will continue to evolve.

 

 

I want to know what you think! Please leave feedback in comments below.

Please don’t hate me. It’s not really my fault. I am sorry to say that every single Sugar developer needs to care about the General Data Protection Regulation (GDPR) and data privacy in general. It is a sign of the times and part of the interrelationship of technology and modern society that impacts the software we implement today and in the future.

 

I can explain but first let me provide some context.

 

What is the General Data Protection Regulation (GDPR)?

 

First off, I am not a lawyer or a GDPR specialist. If you really want to understand what GDPR is and what steps you need to take to be compliant, then I suggest reading the Regulation for yourself or hiring counsel. GDPR is a complex set of rules, and there’s still a lot of debate about what it all really means. Other interpretations, including yours, may be different from what I describe below.

 

Many of our colleagues in the European Union are well acquainted with the GDPR which requires full compliance by May 25th, 2018. But for those of you who do not live in the European Union (EU), I highly recommend reading Data Privacy and GDPR in Sugar by Deepak Deolalikar. It covers some GDPR basics as well as provides an overview of some of the features planned in Sugar to help our customers comply with GDPR.

 

In short, the spirit of GDPR is about allowing individuals (data subjects) to have control over their own personal information. GDPR ensures that personal information or Personally Identifiable Information (PII) of EU citizens are processed responsibly. EU citizens have a right to privacy that in many cases means you must comply with their requests to access, restrict the use of, or delete the personal information that is stored about them.

 

The scope is broad and the penalties are severe. Any organization that stores personal information about EU citizens, even if that organization is based outside the EU such as in the United States, is subject to this regulation.

Penalties for failure to comply with these regulations could result in fines that start at €20 Million or 4% of total revenue if that value is greater.

 

Are you paying attention now?

 

Data Privacy is yet another software globalization requirement

 

When we build software, we make sure that it meets all sorts of requirements. We design for performance, scalability, and security. We work hard to ensure a positive user experience and high quality software. At SugarCRM, we also focus on making sure that all our products are ready for the global marketplace. That means that over the years we have invested in translations into dozens of languages and support for multiple currencies, numerous date and time formats, right-to-left languages, Unicode character encodings (though we’re still working on emojis), and 508 compliance.

 

The fact is that GDPR is just one example of a data privacy regulation at a time when there are dozens more government bodies all over the world considering and implementing new data privacy regulations. UTF-8 character encoding and a translatable UI are no longer enough to make sure your software is ready for the global marketplace! The responsible collection and processing of personal information is now an additional obligation for all software developers.

 

With the upcoming Sugar Spring ‘18 (cloud) and 8.0.0 (on premise) release, we are now investing in data privacy features. These features will help provide our customers with the tools they need to comply with GDPR and many other data privacy rules or regulations.

 

These data privacy features and other data privacy concerns will impact Sugar customizations and integrations that collect or process personally identifiable information (PII).

 

Future installments on Data Privacy and GDPR

 

We will be exploring several data privacy topics in the coming weeks. Here is a quick summary.

 

Collecting explicit consent before storing data in Sugar

 

GDPR has strict requirements for consent. Unless you have an existing lawful basis for using personal information, you need to collect positive and unambiguous consent from the data subject even before data is stored in Sugar. For example, a web to lead form with a pre-selected opt-in checkbox is not going to cut it in the EU. We will be exploring ways to make sure you are collecting explicit consent using techniques like double opt-in (DOI) or confirmed opt-in (COI).

 

Managing PII data and the right to erasure in Sugar

 

There are new Sugar APIs being added for working with PII as well as features that allow Sugar customers to comply with data subject requests like the right to access their own data and the right to erasure. In particular, external systems that integrate with Sugar may need to identify and implement their own erasure measures in compliance with a data subject request.

 

Improved change log and attribution of changes using Data Sources

 

We are implementing some enhancements in Sugar’s change log functionality to allow for finer grain tracking and proper attribution for changes to PII. We will be exploring these platform level enhancements including the ability to define new data sources (for example, an integration) that are responsible for changes to data.

 

What do you think?

 

What are some of your biggest data privacy or GDPR concerns? Let us know and we’ll try to address them in future posts.

 

Also, please follow this space and this blog to be sure you are notified when the next installment is posted!

What is the Sugar Metadata API?

As you probably know, Sugar metadata encompasses the settings, data model (Vardefs), and visual layouts (Viewdefs) used by the Sugar application. The majority of changes made to Sugar using Sugar Studio, Module Builder, or even custom code are implemented by modifying metadata.

 

How can I know that the custom field or custom modules that you need for your integration to work exists in Sugar?

How can I know what are the allowed values are valid for a Sugar dropdown field?

How can I know if a field is required?

How can I know the display label for a given field?

How can I know what fields are available in Sugar that I can map back to an external data source?

 

The answers to all these questions and many more can be found in Sugar metadata.

 

On the server side, metadata is implemented as an extensible set of PHP associative arrays. But how does this information get sent out to Sugar clients like your web browser, mobile app, or even the Outlook plug-in? This is accomplished via the Sugar metadata endpoint of the Sugar REST API.

 

GET /rest/v11/metadata HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json

 

The full metadata response comes back as a very large JSON object. It's usually a few megabytes in size (about 3MB in a stock version of Sugar Winter '18) but can be much larger depending on customizations. Make sure compression is enabled on your web server if you are going to be using it over a slow connection!

 

 

The value to using the Metadata API is that you can discover changes in Sugar configuration and Sugar customizations. New custom fields, relationships, modules, changes to Sugar views and layouts, and much more are all represented in Sugar metadata responses.

 

From a REST API perspective, the only way to accurately know the current data model for any given Sugar instance is to use the Metadata API.

 

Since the Metadata API is so important, here are three important tips to keep in mind to make development easier.

 

Tip 1: Retrieve only what you need

Metadata API calls can generate a huge response depending on your Sugar instance configuration and the customizations that may exist. You should specify filters on your metadata request in order to narrow the response to the data that you actually need. Narrowing what is returned will improve performance on both server side in terms of generating the response but also on the client side where you need to parse the JSON response.

 

For example, if you are integrating with only the Accounts module then you may only need to concern yourself with that part of the metadata. Specify a type_filter and module_filter as URL parameters to only return module metadata for the Accounts module. Other supported type_filter options are server_info, config, relationships, labels, languages, currencies, views, layouts, full_module_list, and etc.

 

GET /rest/v11/metadata?type_filter=modules&module_filter=Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json

 

Tip 2: Cache metadata, update only when it changes

You can safely cache the metadata that you need if you keep track of the _hash value returned in the metadata response.

 

You should present that hash value in the X-Metadata-Hash header on subsequent Sugar REST API requests to ANY endpoint. If the metadata hash is out of date then Sugar will return a 412 PRECONDITION FAILED HTTP response. You should then retrieve updated metadata from the Metadata API and store the updated metadata hash value.

 

GET /sugar/rest/v11/Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json
X-Metadata-Hash: 705fb99230e2ec60b59f481c6831a7cf

 

Also worth mentioning, many of our API resources (such as records and our metadata) implement HTTP caching. If an API response contains an E-Tag HTTP header then you can safely cache the response body as well as the E-Tag value. If you present this value in the If-None-Match HTTP header properly on a subsequent HTTP GET request for that resource, you will get an empty 304 NOT MODIFIED response back if it is safe to continue using the cached version of the previous response. This is another approach to reduce needless processing.

 

GET /rest/v11/metadata?type_filter=modules&module_filter=Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json
If-None-Match: 705fb99230e2ec60b59f481c6831a7cf

 

This allows you to update your local copy of the metadata as soon as it changes and precisely no more often than that.

 

Tip 3: Different users and platforms will retrieve different responses

If a user is assigned a role that doesn't have access to a particular module then the metadata for that module will not be returned when that user accesses the metadata API. Makes sense, right? 

 

Sugar also support things like role based views which will provide alternative UI layout metadata based upon the current user's role.

 

Different platforms will have different metadata responses as well. The mobile platform retrieves module metadata that reflects the needs of our Sugar Mobile app. Mobile UI components look a lot different from what you see when you access Sugar from your browser. The metadata that is retrieved is significantly different to accommodate these changes.

 

For example, the mobile client uses separate edit and detail views for representing records instead of a single record view like you find in Sugar web client. This is represented in the mobile metadata response.

 

One of the first things people do when they start thinking about implementing DevOps best practices is setting up continuous integration and continuous deployment (CI/CD) tooling.  So that’s just what we did with the Professor M School.  (Not sure what I’m talking about when I say the “Professor M School?”  Check out my earlier blog post Introducing Professor M’s School for Gifted Coders.)

 

We’ve set up CI/CD with not one but two popular tools:  Travis CI and Jenkins.  As you decide which tool to use, consider the following tradeoffs.  Travis CI is hosted online so you don’t have to set it up yourself.  Open source projects can leverage Travis CI for free, but closed source projects will have to pay.  Jenkins requires you to set up and manage the app yourself but is free for all projects.  

 

Travis CI Build
Automated build inside of Travis CI.

 

Jenkins Build

Automated build inside of Jenkins

 

We’ve set up the same basic flow for both CI/CD tools:

  • Run the automated tests
  • Build the Professor M module loadable packages

 

In addition, the Travis CI build is configured to post the Professor M module loadable packages to the GitHub releases page whenever a commit is pushed to the master branch.

 

You can learn more about how we’ve implemented CI/CD in the Professor M School’s Readme:

 

You can also explore the results of our latest Travis CI builds at https://travis-ci.org/sugarcrm/school/.

 

We hope you’ll be able to leverage the work we’ve done to setup CI/CD with Travis CI and Jenkins in your own projects!   

One of the biggest pains in developing a module loadable package for Sugar is figuring out how to track the package in source control.  You don’t want to keep your entire Sugar directory under source control--you just want your custom code in source control.  However, from a development perspective, this can be a huge pain.  If you do your development separate from the Sugar directory, every time you make an incremental change, you have to manually build and install the module loadable package, which is a process that can quickly become very time consuming.

 

We’ve developed a tool you can use called the Sugar Synchronizer.  The Synchronizer allows you to develop your Sugar customizations in your Sugar directory while still tracking your changes for your module loadable package in a separate directory.  You can see a live demo of the Sugar Synchronizer in the Sugar Winter '18 Technical Training

webinar recording (you may want to jump ahead to the 38:42 mark).

 

The Sugar Synchronizer is open source, and you can get a copy of the code in our GitHub repo:  https://github.com/sugarcrm/project-sync.  The repo’s Readme has instructions on how to use the Synchronizer.

 

If you have suggestions for improvement or find a bug, please create an issue in the GitHub repo.  Or, better yet, write some code and submit a pull request!  

 

We hope the Sugar Synchronizer makes developing module loadable packages easier for you!

We’ve been working behind the scenes to create a customized version of Sugar that we’re calling the Professor M School.  The essential pieces are ready to go, and we’re thrilled to announce that the repo for the Professor M School is now public and open source.  

 

So what is this the Professor M School?  Let’s begin by talking about the goals for this app:

 

  1. The app should be an authoritative example on upgrade-safe customizations.  We want you, the Sugar developers, to be able to use this app as a reference for what good, upgrade-safe customizations look like.

  2. The app should provide examples of DevOps best practices when developing Sugar customizations and integrations.  For example, we want to have examples of automated test suites and how to leverage continuous integration tools.

  3. The app should include common customizations so that SugarCRM’s engineers can use it for testing and validation.  When our engineers want to know if their changes are going to break common customizations, we want them to be able to use this app to find out.  Ultimately, we want to integrate the app’s automated tests into our internal continuous integration process.


With those goals in mind, we developed the scenario and use cases for the Professor M School.  The app is built around a fictitious university called Professor M’s School for Gifted Coders.  If you attended UnCon 2017, you might remember hearing about Professor M.  We’ve built on what we created for UnCon in order to create the Professor M School.  


Let’s talk about the scenario behind the Professor M School.  Professor M aka Professor Marum has created an exclusive not-for-profit school for gifted coders.  The school currently uses Sugar for the following use cases:

  • Managing applicants, current students, former students, and professors
  • Tracking super groups affiliated with students
  • Soliciting donations from alumni and alumni affiliated super groups.

Professor M will be expanding his use of Sugar to cover other use cases in the future.

To learn more about the Professor M scenario and see a demo of the customizations, check out this video I previously recorded (you might want to jump ahead to the 1:07 mark).

As I mentioned earlier, the Professor M School is open source.  Here are some ways that you can get involved:

  • “Watch” the Professor M School’s GitHub repo: https://github.com/sugarcrm/school.
  • Explore the code and use it as a resource as you develop your integrations and customizations.
  • Submit GitHub issues if you have ideas for improvement, a feature request, or a bug report.
  • Update the code and create a pull request.

 

We hope you find the Professor M School to be a useful resource!  Check back soon for more updates on the app!

Attention developers!  We’ve released Winter '18!  This is our second quarterly On-Demand only release, and we’re pretty excited about it.  Our Co-Founder & CMO, Clint Oram, discusses the highlights of this release from an end-user's perspective in the video below:

 

Matt Marum and I recently hosted a webinar where we gave an overview of the big things developers need to know about this release:

 

The slides from the webinar are available here .

 

If you’re looking for the CliffsNotes version, I’ve got you covered:

  1. Sugar has a new skin, and it’s fabulous.  No JavaScript changes were made as part of this reskinning.  For more information, check out Matt’s blog post: A new Sugar UX coming in Winter '18 .

    Before:
    Old look
    After:
    New look

  2. The Input Validation Framework that has been implemented since Sugar 7.7.1 is now enforced by default.  Input validation violations will cause FATAL errors.  See Matt’s blog post for more details:  How to fix Sugar input validation failures .  

    As part of enforcing the Input Validation Framework, all custom platforms must be registered.  If you have a customization or integration that uses our REST API, this probably affects you.  Check out my blog post  that has links to get more information about the change and a tutorial to help you register your custom platform.
  3. You now have the option of turning on denormalized team security, which can greatly improve List View performance.  Check out the Developer Release Notes or the webinar recording above for more details.
  4. We’ve added PhaserIO as a new library.  As a result, we’re seeing outstanding performance in the new Product Catalog Dashlet and great potential for speeding up other parts of the app.  Check out the Developer Release Notes for a list of all library changes.
  5. We’ve been working on an Exemplar App (https://github.com/sugarcrm/school) and the Sugar Synchronizer (https://github.com/sugarcrm/project-sync), which we hope will become key resources for everyone.  Watch the blog for more details coming soon!

 

This blog post promised to have just about everything you need to know about the Sugar Winter ‘18 release.  Below are some resources that have the rest of the details.

 

We hope you’re as excited about this release as we are!