Working With SugarCRM Logic Hooks

There are two ways of installing logic hooks: one works fine, the other seems to cause problems.

The way not to use is a log_hooks array within the manifest file as follows.

'logic_hooks' => array(
array(
'module' => 'Emails',
'hook' => 'after_save',
'order' => 200,
'description' => 'This logic hook looks at a saved email and adds a       history record.',
'file' => 'custom/include/classes/History.class.php',
'class' => 'History',
'function' => 'addHistory',
),

You are much better to user the copy process as follows. Follow exactly the directory names.
Also, make the actual file name something unique, so that it doesn’t match an existing file for other logic hooks.

'copy' => array (
0 => array (
'from' => '/Files/custom/Extension/modules/Emails/Ext/LogicHooks/history_logic_hooks.php',
'to' => 'custom/Extension/modules/Emails/Ext/LogicHooks/history_logic_hooks.php',
),

Where the file referred to (eg.history_logic_hooks.php) holds the definition like this.

// logic hook to handle history // 3-oct-2017
$hook_array['after_save'][]
= Array( 200, 'Save History', 'custom/include/classes/history.class.php', 'History', 'addHistory' );

Of course you also have to copy the class file you refer to.

SugarCRM Module Loader Issue

When trying to unload a new module I kept getting a bank screen, and errors in sugarcrm.log. The upload uses sys_get_temp_dir() to get the temp directory and this was set outside the document root, hence the error.

But how do yo set the system temp directly? Finally I tracked it down. You need to add the following to the php.ini file. You think it would be there, commented out, like lots of other parameters.

sys_temp_dir = "/Users/gregambrose/tmp"

Obviously, restart apache.

I hope that helps somebody

Greg

SugarCRM Relationships

There are plenty of examples on-line of working with relationships between modules in Sugar using load_relationship, but one problem I’ve recently solved is, how do you know the name of the relationship you want to load. Contacts, Cases etc are easy but there are lots of others you may be interested in.

Well the answer is simple, so long as you can debug your code with something like X-debug. If you can’t you should be as it makes life for a developer very easy.

load_relationship is within the SugarBean class (data/SugarBean.php). Step into it and break just after this line.

$fieldDefs = $this->getFieldDefinitions();

Now look through all the $fieldDefs until you find the relationship you are interested in. I’m interested in membership, so this is the one I want. The {name} is what you use {relationship} is the name you will see when you look at relationships in Studio.

I hope this helps someone.

SugarCRM Inbound Emails

I’ve just recently been asked to add a logic hook to inbound emails, so that the emails could be used to be updated the associated contacts. I’m not going to provide the full details here but just a few hints.

Firstly when you set up Inbound Emails, you must make the mailbox a group mailbox, if you want to use logic hooks. Non group emails go to the table email_cache not emails.

Note also that it is the scheduled task that polls the email account for new emails, so you need to wait for it run, normally once a minute.

Also, inbound emails only get imported if they remain unread. Read emails are ignored. Once Sugar has imported them, they are set as read on the server.

To setup a logic hook, you need to do it on after_save on the Emails module.

Thats all, but I can provide source if you need it.

Greg

 

 

SugarCRM 7 Logic Hooks

I haven’t worked with SugarCRM for a couple of years so thought I would build a logic hook to refresh my memory. This one really should really be built into Sugar as an option. I think it would be the preferred behaviour for most people.

When you reassign an Account, this logic also reassigns all the Accounts contacts as well. Makes total sense that this is what you would normally do.

Anyway, these are the steps. Note the file names are mentioned in the source

1. Create a file like this

2. And a class like this

3. Check that all directories and files are readable by Sugar

4. Quick Repair

5. Give it a try

I hope that helps someone.

 

Debugging SugarCRM Scheduled Tasks

Debugging PHP is best done using an IDE (in my case Eclipse) where you can set break points and step through code and look at variables. Normal web applications are straight forward normally but scheduled task debugging is a bit of a challenge. Below are my suggestions as to how best this can be done.

Before starting I must say, don’t try this on a production server. You will be affecting the running of normal scheduled processes if you do!

You will need to make sure that the scheduled task you are debugging is the only task that will run. To achieve this, set all other job as deleted as follows (keep a note of what is active and what has previously been deleted before you start).

UPDATE job_queue SET deleted = 1
UPDATE job_queue SET deleted = 0, execute_time = '2017-01-01 00:00:00', status = 'queued' WHERE id = ''

As the execution time set is earlier than now, the job will be run.

Now to start debugging. You need to debug cron.php in the root directory, as a command line process. If you try defining it as a web application in your IDE (ie. in a browser) it will die before doing anything.

Break at this line in cron.php

$jobq->runCycle();

Then step in

In runCycle() you will see a loop through the scheduled tasks, like this.


for($count=0;$count<$this->max_jobs;$count++) {
$this->job = $this->queue->nextJob($myid);
if(empty($this->job)) {
return;
}
$this->executeJob($this->job);
if(time() >= $cutoff) {
break;
}
}

All you need do is break on executeJob() and have a look at $this->job to see if it is the one you are interested in. It should be as you have stopped all others.

Step into it and see what its doing.

Within executeJob() you find the following

$res = $this->job->runJob();

You should step into this.

The line that does all the work is this line.

$res = call_user_func_array($func, $data);

Step into that and you are in the code you want to debug!

When you have finished debugging, remember to reinstate the deleted status of all the other jobs.

If you think this can be improved, please let me know

Moving to Amazon AWS EC2 and RDS, and PHP 7

Moving a large web application from a dedicated host running PHP 5.5 to Amazon AWS EC2 with RHEL and PHP 7.1.2 presented much less in the way of challenges than I had expected. Maybe I’m a pessimist but I expected it to be a long drawn out affair.

As with any software change, we created a branch from our master source in Git, and worked on this. We would merge that back into master once the AWS EC2 instance was finally in production.

PHP had to be configured, which is expected as we had installed  PHP 7.1.2 and not yet touched its configuration. Having the old server as an example of what we needed made it very easy.

The application itself needed reconfiguration, as is normal when you move to new host. The database credentials needed to point to our database instance at AWS RDS, and other server specific changes like file locations needed to be made.

One issue I had was testing the application. We had to leave the current domain pointing to the old hosting as it was still in active use. How then to test the new server, while making sure that requests from it went back to the old server, without being noticed. If this happened, it wouldn’t be a complete test.

I  added an entry to the hosts file (normally /etc/hosts) on both the EC2 hosting and my test client (my MAC). If ever there was a stray link to the old domain, it would always be directed to the the EC2 host.

Obviously these host file changes were removed when the new host was in production.

There were a number of coding issued to be resolved, mostly to do with functions that had long been deprecated, but now finally removed (like split()). Beyond that a few file permission issues, but they are normal.

Before going live I had to transfer newly created files from the old web server. I used rsync as this is the most reliable way to ensure all new and amended files have been transferred. And it is very quick and easy to use.

Form a user’s point of view the new configuration seems about 20% faster, but we feel comfortable that we can increase the EC2 instance to a more powerful option should this ever be needed.

 

Setting Up An Amazon Web Service

Most of the software I write at work can’t be included in my blogs for obvious reasons, but when it comes to research over the holidays, that is a different matter. In this case I’m planning to move our applications across to AWS so I thought I would play round with it to see what was involved. I sure there are opportunities and pitfalls so the best way to find these is to have a go.

What I’m aiming at is cloud hosting for PHP applications, their databases and lots of file storage (photos and video). We will start with PHP 7 and resolve any compatibility problems as we migrate.

1.  Set up a free AWS account

https://portal.aws.amazon.com/gp/aws/developer/registration/index.html

Although its a free account, you have to enter credit card details. I’m a bit worried that I might start getting changed for things when not expecting it. I must keep track of options I select, to make sure they are free (for now anyway).

2. Build Your Virtual Machine

As a part of signing up you get the following options. I chose Launch a virtual machine. You also need to give it a name (GregsTest).

Then choose an operating system. I started with Amazon Linux, but got stuck trying to get PHP7 working. I changes to Red Hat Linux.

You then need to choose an instance type. Might as well go for something small and free for now.

Finally we need to set up private key. You keep this on your machine, and it gets used whenever you connect into your instance. AWS keep your public key.

Be sure to keep a safe copy of this private key as without it you are lost. AWS don’t keep it so you are on your own.

In this case the download will be a file GregsTest.pem

I know we have chosen everthing, but somehow we need to go through it again. We are asked to choose a machine instance as below. As mentioned, I went for Red Hat

Then an instance type

It will build now and then show you a list of your instances as follows.

You can connect to your instance with ssh as follows.

Not this refers to your private key. In this example the pem file is in the current directory but this may not always be the case. You will go straight into the shell on the new instance. There is no user name and password as the public/private keys have been used for authentication.

3.  Install Apache and PHP 7

All you need is this

And this

Well that’s it. You should be able to open that in a browser,using the AWS URL

SugarCRM 7 Record View

I’ve spent some time working on the newish Sugar 7, and don’t intend to review it any detail. There is one very small change that I don’t like, and that is to do with module views in Studio.

In earlier versions you could have a Detail View to display a record, and a separate Edit View to all creation and editing of records. These have been replaced by a single Record View.

This seems a backwards step. In many cases there are details that you want to show users, but not allow them to edit. An example might be sales figures that are updated by an integration process. Users should never be able to amend these, so in the past they would be just left off the Edit View. They would be included in the Detail View as they are potentially useful.

I can’t find anywhere a discuss on why this change was needed, and to me it seems a backwards step. I’m aware of the fact that people inherently don’t want change, so is this me just rebelling to something that has changed?

I would appreciate all any feedback.

Greg

Assigning Child Records In SugarCRM

If an account is assigned to another user, surely all the account’s contacts should also be reassigned. The same goes for other child records, such as documents, opportunities etc.

This requirement came up recently in the LinkedIn SugarCRM Network, so I thought I would put together a logic hook to see how it might be done.

The following logic hook was designed for Accounts, but could be applied to any module. Also I’ve specified in the code which child modules are to be updated. You may not need all related modules to be reassigned.

There are three issues that should be considered before implementing this type of logic, as follows.

(a) You will be saving related records, and if these have associated workflow or logic hooks, then these will get fired from this logic hook. You need to look carefully at each child module you use, just to be sure your are not going to initiate unwanted alters and actions.

(b) In some cases an account will have a huge number of records associated with it, and re-assigning them all via this logic hook could take some time. If this is the case it would be better to adopt a different solution (see below).

(c)  When a user creates a new contact, this logic hook will not ensure that the assigned user matches the account. This is because in this case the  accounts logic hook is never fired. To ensure all assignments are correct, you could also add logic hooks on each child module, or use a separate over-night process to ensure all records are assigned correctly (see below).

An alternative would be to run an overnight process to do the reassignments. This would involve similar logic, but run at a time of day that wouldn’t affect users. It would only look at recently updated records. This would handle (b) and (c) above, but not (a).

You will need to add the following to custom/modules/Accounts/logic_hooks.php

And add the following as a file custom/modules/Accounts/Reassign.php

 

I hope this is helpful. If you can suggest any improvements or have any comments, they would be very much appreciated.

Regards,

Greg