Update Oro Platform to Version 4.0

PHP error.log

[03-Dec-2019 16:08:08] WARNING: [pool www] child 15777 said into stderr: "NOTICE: PHP message: PHP Fatal error:  Uncaught RuntimeException: "
[03-Dec-2019 16:08:08] WARNING: [pool www] child 15777 said into stderr: "In ContainerBuilder.php line 1023:"
[03-Dec-2019 16:08:08] WARNING: [pool www] child 15777 said into stderr: "                                                     "
[03-Dec-2019 16:08:08] WARNING: [pool www] child 15777 said into stderr: "  You have requested a non-existent service "mail".  "
[03-Dec-2019 16...

Log output of executed cron job to table `oro_message_queue_job`

There is a data column in oro_message_queue_job which can be used to log the output of cron job.

References

vendor\oro\platform\src\Oro\Component\MessageQueue\Job\JobRunner.php

In private function callbackResult($runCallback, $job), it does the callback to execute the cron:

$jobRunner = $this->getJobRunnerForChildJob($job->getRootJob());
try {
    $result = call_user_func($runCallback, $jobRunner, $job);

So it passed 2 parameters to the anonymous function. The $job param is the entity for the table `oro_messag...

Add a Cron Job and Command

There is no config to register a cron job in OroPlatform. There are 2 steps to add a cron job:

  1. add a command class in the bundle
  2. run a CLI to add the job in table oro_cron_schedule

The added class can be run as a command in CLI when it is defined as a Service.

Add a Command Class

src\Stars\Bundle\LoggerEventBundle\Command\InsertActionDataCommand.php

<?php

namespace Stars\Bundle\LoggerEventBundle\Command;

use Oro\Bundle\CronBundle\Command\CronCommandInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\...

Service

What is a Service?

A service is a discrete unit of functionality:

  1. It logically represents a business activity with a specified outcome.
  2. It is self-contained.
  3. It is a black box for its consumers.
  4. It may consist of other underlying services.

Put simply, a service is any PHP object that performs some sort of global task.

You don't have to do anything special to make a service: simply write a PHP class with some code that accomplishes a specific task.

In Symfony...

Create a Doctrine DBAL Connection for Another Database

There are 3 ways to create a DBAL connection to access another database:

\Doctrine\Bundle\DoctrineBundle\ConnectionFactory

/** @var \Doctrine\Bundle\DoctrineBundle\ConnectionFactory $connectionFactory */
$connectionFactory = $this->getContainer()->get('doctrine.dbal.connection_factory');
$connection = $connectionFactory->createConnection([
	'pdo' => new \PDO(
		"mysql:host=$hostname;dbname=$dbname", 
		$username, 
		$password)
]);

$connection->executeQuery('SELECT * FROM your_table');

\Doctrine\DBAL\DriverManager

/**
...

Override an Override Service with Compiler Pass

I wanted to increase the length of name for MySQL table from 30 to 64 as I encountered this error:

[kiat@reporting misoro]$ sudo -u nginx php bin/console oro:migration:load --force
Process migrations...
Oro\Bundle\EntityExtendBundle\Migration\LoadEntityConfigStateMigration
Stars\Bundle\LoggerEventBundle\Migraions\Schema\v1_0\StarsLoggerEventBundle
    ERROR: Max table name length is 30. Please correct "sc_stars_logger_event_action_data" table 
in "Stars\Bundle\LoggerEventBundle\Migraions\Schema\v1_0\StarsLoggerEventBundle" migration
`...

Entity

What is an Entity?

Every PHP object that you want to save in the database using Doctrine is called an "Entity". Each entity must have a unique identifier.

Oro Platform Entity

The entity class resides in the Entity directory in the bundle's root. In VS Code, install PHP Setters & Getters to generate the setter and getter code.

src\Stars\Bundle\LoggerEventBundle\Entity\ActionData.php:

<?php

namespace Stars\Bundle\LoggerEventB...

Add a Basic Controller in Oro Platform Application

After we have our bundle, we can add a controller with just 2 files.

Add a Controller Class

Add file src\DbugBundle\Controller\DbugController.php

<?php
namespace DbugBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;


/**
 * @Route("/dbug")
 */
class DbugController
{
    /**
     * @Route("/phpinfo", name="dbug_phpinfo")
     */
    public function phpinfoAction(): Response
    {
        ob_start();
        phpinfo();
        $html = ob_get...

Setup Cron Job in Oro Platform Application

Step 1: Add a cron for user nginx

Note I'm on Centos with Nginx web server. Open the crontab file in vi editor on behalf of the nginx user:

[kiat@reporting misoro]$ sudo -u nginx crontab -e
no crontab for nginx - using an empty one
crontab: installing new crontab

That will launch the vi editor.

Step 2: Editing the cron file in vi

Press Insert key.

Paste:

*/1 * * * * php /usr/share/nginx/html/misoro/bin/console oro:cron --env=prod > /dev/null

Notes:

  1. that will schedule execution of the oro:cron comm...

Install Oro Platform 3.1.3 on Centos 7.4.1708 - Nginx 1.12 - PHP 7.1

Reference the official install guide.

We are using Symfony Framework v. 3.4 LTS in Oro Applications v.3.x.

Errors I Encountered and How I Fixed Them

Apache is Active

Check Port 80

[kiat@reporting /]$ sudo netstat -tulpn | grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      55851/httpd

Port 80 is used by Apache (as user httpd).

Disable Apache

[kiat@reporting /]$ sudo...

OroPlatform API - Deleting Entity - API Testing - WSSE Authentication

In the Creating a Simple CRUD cookbook, it uses REST API to delete entities. However, the description isn't enough to properly implement the delete operation.

However, there are examples on how to do it in the \vendor\oro\platform codebase. Reference vendor\oro\platform\src\Oro\Bundle\OrganizationBundle\ on coding for REST API. The files of inter...

Cookbook: Creating a Simple CRUD

Here's my attempt to follow the official OroPlatform guide on creating a simple CRUD.

Create the InventoryBundle

Starting from a fresh instance of Oro Platform ver 3.1.3, follow the manual steps in Create A Bundle.

Create the Vehicle Entity

Create the file src\InventoryBundle\Entity\Vehicle.php

<?php

namespace InventoryBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="vehicle")
 */...

Install Oro Platform on Wins 10 WAMP

2 Ways to Install

Actually, there are more than 2 ways to download the source codes. But the common ways are

  1. Git Clone
  2. Composer

Git Clone

  1. Fork the repository from oroinc.
    1. For running the applications, fork from one of the pinned repositories
    2. For contributing to the code, fork the repo without suffix -application
  2. Git clone the fork with TortoiseGit.
  3. Composer to get the dependencies.
kiat@win10 MINGW64 /d/Work/wamp64/www/oro/crm-application (master)
$ composer inst...

Errors when Creating a Simple CRUD

Errors encountered while following the developer guide to create a simple CRUD.

ClassNotFoundException

Attempted to load class "InventoryBundle" from namespace "InventoryBundle".
Did you forget a "use" statement for another namespace?

Add the bundle definition file: src\InventoryBundle\InventoryBundle.php

<?php

namespace InventoryBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class InventoryBundle extends Bundle
{
}

Anno...

Create a menu item in backend

Steps to create a menu item:

Image

src\MisBundle\Resources\config\oro\navigation.yml

navigation:
    menu_config:
        items:
            scicom_tab:
                label: Scicom
                uri:   '#'
                extras:
                    position: 300
            scicom_tab_link:
                label: Scicom Hello
                route: scicom_link
        tree:
            application_menu:
                children:
                    scicom_tab:
                        children...

Create A Bundle

Prerequisites

Official OroPlatform guide on installation and setup.

What is a Bundle?

All OroPlatform-based applications have unique features that facilitate smooth development routine, like autoregistration of bundles and configuration files, for example.

However, these features assume that all application code is organized in bundles. For this reason, you have to create your own bundle for your custom code in order to perform...