I will be posting here some tips for re-factoring existing custom code or custom setups to work properly with Espo 6.0 + , as we work on updating our own application, it would be very helpful if others can also share here their tips to make the transition a little less painful, since this was a major upgrade and seems to trigger a lot of errors and warnings.
Hooks:
The previous "Espo\Core\Hooks\Base" class is deprecated now, so while it might still work for the time being, it is best to consider it obsolete and refactor all hooks that were extended from it, use the table below as an informal guide to replace former "base" hook class methods:
BEFORE:
NOW:
BEFORE:
NOW:
BEFORE:
NOW:
BEFORE:
NOW:
BEFORE:
NOW:
BEFORE:
NOW:
BEFORE:
NOW:
Entry Points:
Entry points can only be invoked now using GET requests, if your code has entry point calls using POST requests (like we had because in some cases I didn't want to display the payload parameters in the browser's url) you could replace the entry point call with a standard Ajax - Controller - Service -Controller - Ajax implementation as follows:
BEFORE: (view code)
BEFORE: (entry point class code)
NOW: (view class code)
NOW: (back-end controller class code)
NOW: (back-end service class code)
Service Classes:
The base class Espo\Services\Services.php was refactored, custom service class that extend from it will need the following modifications:
Hooks:
The previous "Espo\Core\Hooks\Base" class is deprecated now, so while it might still work for the time being, it is best to consider it obsolete and refactor all hooks that were extended from it, use the table below as an informal guide to replace former "base" hook class methods:
BEFORE:
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // some code $this -> getEntityManager() -> // more code }
Code:
use Espo\Core\ORM\EntityManager; class MyCustomHook { protected $entityManager; public function _construct(EntityManager $entityManager) { $this -> entityManager = $entityManager; } // some code $this -> entityManager -> // more code }
BEFORE:
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // some code $this -> getConfig() -> // more code }
Code:
use Espo\Core\Utils\Config; class MyCustomHook { protected $config; public function __construct(Config $config) { $this -> config = $config; // some code $this -> config -> // more code
BEFORE:
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // some code $this -> getMetadata() -> // more code }
Code:
use Espo\Core\Utils\Metadata; class MyCustomHook { protected $metadata; public function __construct(Metadata $metadata) { $this -> metadata = $metadata; } // some code $this -> metadata -> // more code }
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // custom hook functions ... $this -> getContainer() -> ... }
Code:
use Espo\Core\Container; class MyCustomHook { protected $container; public function __construct(Container $container) { $this -> container = $container; } // custom hook functions .... $this > container -> ....
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // custom hook functions ... [COLOR=#000000]$this -> getServiceFactory() ->[/COLOR] ... }
Code:
use Espo\Core\ServiceFactory; class MyCustomHook { protected $serviceFactory; public function __construct(ServiceFactory $serviceFactory) { $this -> serviceFactory = $serviceFactory; } // custom hook functions .... [COLOR=#000000]$this -> serviceFactory ->[/COLOR] ....
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // custom hook functions ... [COLOR=#000000]$this -> getUser() -> [/COLOR] }
Code:
use Espo\Entities\User; class MyCustomHook { protected $user; public function __construct(User $user) { $this -> user = $user; } // custom hook functions .... [COLOR=#000000]$this -> user -> [/COLOR] ....
Code:
class MyCustomHook extends \Espo\Core\Hooks\Base { // custom hook functions ... [COLOR=#000000]$this -> getContainer() -> get('mailSender');[/COLOR] ... }
Code:
use Espo\Core\Di; class MyCustomHook implements Di\EmailSenderAware { use Di\EmailSenderSetter; // custom hook functions .... [COLOR=#000000]$mailSender = $this -> emailSender -> create();[/COLOR] ....
Entry Points:
Entry points can only be invoked now using GET requests, if your code has entry point calls using POST requests (like we had because in some cases I didn't want to display the payload parameters in the browser's url) you could replace the entry point call with a standard Ajax - Controller - Service -Controller - Ajax implementation as follows:
BEFORE: (view code)
Code:
...... var url = '?entryPoint=chatNotification'; var options = { notificationType: 'eMail', authorId: authorId, subject: subject, body: body, portalBody: portalBody, distributionList: distributionList, portalDistributionList: portalDistributionList }; var payload = JSON.stringify(options); var xmlhttp = new XMLHttpRequest(); xmlhttp.open("POST", url); xmlhttp.setRequestHeader("Content-type", "application/json"); var self = this; xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState === XMLHttpRequest.DONE) { if (xmlhttp.status === 200) { console.log("Email Notifications sent to: ",xmlhttp.responseText); } else if (xmlhttp.status === 400) { alert('There was an error 400'); } else { alert('something else other than 200 was returned'); } } }; xmlhttp.send(payload);
PHP Code:
......
class ChatNotification extends \Espo\Core\EntryPoints\Base
{
public function run()
{
//convert the POST JSON input received into a PHP associative array
$requestPayload = file_get_contents("php://input");
$payload = json_decode($requestPayload, true);
$notificationType = $payload["notificationType"];
if($notificationType === "eMail") {
$this -> getServiceFactory() -> create('ChatNotification') -> emailNotification($payload);
} elseif($notificationType === "sms") {
$this -> getServiceFactory() -> create('ChatNotification') -> smsNotification($payload);
}
}
}
NOW: (view class code)
Code:
...... var payload = { notificationType: 'eMail', authorId: authorId, subject: subject, body: body, portalBody: portalBody, distributionList: distributionList, portalDistributionList: portalDistributionList }; // Make the request to the back-end: Ajax Call > PHP Controller > PHP Service > PHP Controller > Ajax Response this.ajaxPostRequest('ChatPostNotification/action/sendChatActivityNotification', payload).then( function (responseData) { var serverResponse = ''; if(typeof(responseData === "object")) { serverResponse = JSON.parse(responseData); } else { serverResponse = responseData; } console.log("Email Notifications sent to: ",serverResponse); }.bind(this)).fail( function (xhr) { xhr.errorIsHandled = true; } );
PHP Code:
public function postActionSendChatActivityNotification($params, $data) {
// build the payload to send to the Service class
$payload = (object)[];
$payload- > notificationType = $data -> notificationType;
$payload -> authorId = $data -> authorId;
$payload -> subject = $data -> subject;
$payload -> body = $data -> body;
$payload -> portalBody = $data ->portalBody;
$payload -> distributionList = $data -> distributionList;
$payload -> portalDistributionList = $data -> portalDistributionList;
// invoke the appropriate service function depending on the type of notification requested
if($payload > notificationType === "eMail") {
$response = $this -> getServiceFactory() -> create('ChatNotification') -> emailNotification($payload);
} elseif($payload -> notificationType === "sms") {
$response = $this -> getServiceFactory() -> ('ChatNotification') -> smsNotification($payload);
}
return $response;
}
PHP Code:
public function emailNotification($payload) {
// Code to prepare and send notifications via eMail and store the list of email addresses to which the notifications were sent
......
// return the list of email addresses to the controller
echo json_encode($sentList);
}
Service Classes:
The base class Espo\Services\Services.php was refactored, custom service class that extend from it will need the following modifications:
BEFORE | NOW |
$this -> getSelectAttributeList($params); | $this -> getSelectManager() -> getSelectAttributeList($params); |
Comment