Professional Documents
Culture Documents
Oro Fundamentals
Oro Fundamentals
environment
1
www.oroinc.com
Goal
www.oroinc.com
PhpStorm IDE
www.oroinc.com
PhpStorm Symfony Plugin
● Services autocomplete
○ Type hinting
●
○ Entities autocomplete
○ EntityRepository
(find/findOneBy/findAll/findBy)
● Templates autocomplete
● Routes autocomplete
● Translations autocomplete
www.oroinc.com
PhpStorm ORO Plugin
●
○ Layout updates, api.yml, datagrids.yml,
etc..
●
○ Actions, Conditions,
mass_action_provider, etc.
●
○ Eg. label in mass_actions
●
www.oroinc.com
PHP Code Sniffer in PhpStorm
●
○ PSR-2
●
Demonstration >>>
www.oroinc.com
Xdebug
● Debugger
● Profiler (not recommended)
● Configurable
● Supports remote debugging
○ https://xdebug.org/docs/remote
Demonstration >>>
www.oroinc.com
Xdebug in PhpStorm
Demonstration >>>
www.oroinc.com
PHPUnit in PhpStorm
● Configuration
● Easy run using right click
● Debug
Demonstration >>>
www.oroinc.com
PHP Mess Detector in PhpStorm
●
● Configuration
● Rule sets
○ https://phpmd.org/rules/index.html
● Automatic check and highlight
● Suppression
○ @SuppressWarnings(PHPMD)
Demonstration >>>
www.oroinc.com
Excluded directories in PhpStorm
●
●
●
○ var/cache
■ var/cache/dev/oro_entities/Extend/Entity
○ var/logs
○ public/bundles
Demonstration >>>
www.oroinc.com
Assets via symlinks
Demonstration >>>
www.oroinc.com
Emails
●
○ https://mailcatcher.me/
●
●
○ mailer_transport: smtp
○ mailer_host: 127.0.0.1
○ mailer_port: 1025
○ mailer_encryption: null
○ mailer_user: null
○ mailer_password: null
Demonstration >>>
www.oroinc.com
Extras
● Terminator
○ Arrange terminals in a grid
○ Tabs, Drag and drop reordering of terminals
○ Super + g
● Grep for ERROR|CRITICAL
● Scripts for tedious tasks
Demonstration >>>
www.oroinc.com
Best Practices
www.oroinc.com
General
concepts
16
www.oroinc.com
Goal
www.oroinc.com
Foundation
● Symfony Framework
○ No significant issues with adding
symfony-specific components to ORO
applications
● Doctrine ORM
○ Pay attention on the performance
● Some best practices aren’t used
○ Eg. bundles.yml / routing.yml
https://symfony.com/projects/orocrm
https://symfony.com/projects/orocommerce
www.oroinc.com
Oro applications
www.oroinc.com
Application environments
● dev
○ Symfony toolbar + ORO extensions
○ The slowest one
○ Good for debugging, mail catching etc.
○ System configuration
● prod
○ Performance optimized
○ Recommended for demo
● test
○ No demo data!
Demonstration >>>
www.oroinc.com
Application environments
www.oroinc.com
Structure
22
www.oroinc.com
Application directory structure
Demonstration >>>
www.oroinc.com
Applications and packages
www.oroinc.com
Main package dependencies
platform
platform-enterprise
crm commerce
crm-enterprise commerce-enterprise
commerce-crm
www.oroinc.com
Additional packages
● Plugins
● Integrations
● Additional functionality
● Marketplace
○ https://marketplace.orocommerce.com/
○ How to Manage Extensions
www.oroinc.com
Packages in OroCRM application
crm-application
crm
platform
crm-task-bundle
crm-call-bundle
calendar-bundle
marketing
platform-serialised-fields
crm-hangouts-call-bundle
crm-magento-embedded-contact-us
crm-dotmailer
crm-zendesk
www.oroinc.com
Dependencies of OroCRM
application
● https://github.com/oroinc/crm-application/blob/4.1/compo
ser.json#L18-L24
● https://github.com/oroinc/crm/blob/4.1/composer.json#L1
7-L21
● https://github.com/oroinc/platform/blob/4.1/composer.json
#L13-L78
www.oroinc.com
Packages and bundles
Demonstration >>>
www.oroinc.com
Bundle directory structure
● Resources/config/oro
● Migrations
● .md files
● and more
Demonstration code>>>
www.oroinc.com
Components and bridges
● Component
○ Abstract functionality (library)
○ No bundle dependencies
● Bridge
○ Connects several bundles
Demonstration >>>
www.oroinc.com
Relational DBMSes
● MySQL
○ Not strict SQL
○ Suitable for small applications - up to
1M of entities
● PostgreSQL
○ Strict SQL
○ Suitable for big applications - more
than 1M of entities
○ Supported only in Enterprise Edition
www.oroinc.com
Search engines
● ORM
○ Suitable for small applications
○ Stores data in the application DB
○ Implements EAV
● Elasticsearch
○ Suitable for big applications
○ Allows to configure search behaviour
○ Document based engine (NoSQL)
○ Efficient aggregation, geo queries, REST, and
more
○ Supported only in Enterprise Edition
[Admin guide]
www.oroinc.com
Message queue engines
● DBAL
○ Suitable for small applications
○ Stores data in the application DB
○ Emulates queue
○ Better for debugging
● AMQP (RabbitMQ)
○ Suitable for big applications
○ RabbitMQ allows better scaling
○ Supported only in Enterprise Edition
[Docs] & [Admin guide]
www.oroinc.com
Application configuration: Files
● Symfony
● config/config.yml ; parameters.yml
● config/security.yml
● config/routing.yml
● ORO
● <bundle>/Resources/config/oro/app.yml
● <bundle>/Resources/config/oro/routing.yml
● and others...
https://github.com/oroinc/platform/tree/4.1/src/Oro/Bundle/PlatformBundle
https://github.com/oroinc/platform/tree/4.1/src/Oro/Bundle/DistributionBundle
www.oroinc.com
Application configuration: UI
Demonstration >>>
www.oroinc.com
Best Practices & Principles
● SOLID
www.oroinc.com
Application installation: CLI
● bin/console oro:install
● Additional parameters
● Might take up to 5 minutes
● Supports different environments
● Can be used in Continuous Integration
[Docs]
Demonstration >>>
www.oroinc.com
Application upgrade
● Maintenance mode
● Turn off application processes (cron, MQ)
● Create backups of your db and source code
● Get new code
● Composer install
● Remove var/cache/<environment>
● bin/console oro:platform:update
● Return everything back
[Docs]
www.oroinc.com
Cron
● bin/console oro:cron
● Triggers other commands
● Has to be executed every minute
● */1 * * * *
● It has to be prefixed with oro:cron
[Docs]
● bin/console oro:message-queue:consume
● -vvv for more verbosity
● Supervisor
● Message limit
● Time limit
● Memory limit
www.oroinc.com
Logger
● Use everywhere
● Use in critical places
● Use in the integrations
● Correct logging level
● Context
[Example]
www.oroinc.com
How to find required code
● Search by labels
● Search by HTML (tags, classes)
● Use Symfony Profiler
● Set breakpoints
● Regex in Phpstorm
Demonstration >>>
www.oroinc.com
Best Practices
● Make sure your application can be installed from scratch
unless there is no other way but use DB dumps (make sense
only for development to have an easy way to reinstall an app)
www.oroinc.com
Best Practices
● If you are planning to use the same code in multiple projects
then it is recommended to put it to the separate bundle /
component and add it using composer.json, use company name
as first part of the namespace - e.g. Oro/Bundle/UserBundle
www.oroinc.com
Best Practices
● Write documentation based on the experience of the
developers who will work with the code; if they are
seniors - mention only very unusual solutions (maybe
only as a comments in code), if they are juniors -
document bundle / component responsibility, relations
to other bundles, structure, algorithms, entities, API
calls, layout structure and providers etc.
www.oroinc.com
Documentation
● Documentation in bundles
● https://doc.oroinc.com
● https://www.slideshare.net/OroCRM/present
ations
● https://www.youtube.com/channel/UC9ougJg
KzJd-ZxrLuvBqZLg
● Use Google
www.oroinc.com
Testing
48
www.oroinc.com
Goal
www.oroinc.com
Why do we need tests?
● Reliability
● Better code quality
● Coverage of business use cases
● Continuous integration
www.oroinc.com
Types of tests in Oro application
● Unit tests
● Functional tests
● Behat tests
www.oroinc.com
Unit tests
● Tests for separate PHP classes
● No interaction with storages
● Mocks
● Minimum environment setup
● Do not require installed application
● Validate behaviour on class level
● Very fast (milliseconds)
● <bundle>/Tests/Unit
www.oroinc.com
Functional tests
● Tests for backend functionality
● Interactions with storages (DB, search index)
● Minimum number of mocks
● Require application installed in test mode
● Validate behaviour on bundle and
component levels
● Average speed (seconds)
● <bundle>/Tests/Functional
www.oroinc.com
Behat tests
Demonstration >>>
www.oroinc.com
How to run tests
● PHPUnit
● Run from CLI
● Run from PhpStorm
● Integration with PhpStorm
Demonstration >>>
www.oroinc.com
Good tests
[Example]
www.oroinc.com
Bad tests
● Not isolated
● Don’t validate state or result
● Lots operations in one test
● Hard to read
● Hard to change
● Coupled
www.oroinc.com
Code review
[Best practices]
[Tips and FAQ]
www.oroinc.com
Code review workflow
www.oroinc.com
Code review checklist
● Functional review
● Architectural review
● Implementation review
● Automated tests
● Documentation
[Full checklist]
www.oroinc.com
Best Practices
www.oroinc.com
Extend functionality
with bundles
www.oroinc.com
Service/parameter overriding
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/EntityB
undle/Resources/config/services.yml#L2-L7
www.oroinc.com
Service decoration
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bundle/
WebsiteSearchBundle/Resources/config/services.yml#L90-L96
www.oroinc.com
Compiler passes
● Dynamic manipulations with services and
parameters
● Allows to add custom logic during the
compilation of DIC
● Examples
○ Add method call
○ Change class
www.oroinc.com
Overriding at the application level
www.oroinc.com
Routes overriding
● Define routes with the same name
● The latest route wins
● Might be used to override controllers
www.oroinc.com
Template inheritance
{% extends '!OroUI/actions/update.html.twig' %}
www.oroinc.com
Template placeholders
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UIBun
dle/Resources/views/actions/view.html.twig#L51-L58
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/DataA
uditBundle/Resources/config/oro/placeholders.yml
www.oroinc.com
Twig extensions
● Filters
○ ‘label’|trans
● Functions
○ oro_currency_name(currency)
● Tests
○ value is defined
● Operators
○ value == value
● Globals
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/Entit
yBundle/Twig/EntityExtension.php
www.oroinc.com
Form extensions
[Symfony documentation]
www.oroinc.com
Configuration files
● config/config.yml
● <bundle>/Resources/config/oro/app.yml
● bin/console debug:config --help
https://github.com/oroinc/orocommerce-application/blob/4.1/co
nfig/config.yml#L37-L43
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bundl
e/CMSBundle/Resources/config/oro/app.yml
www.oroinc.com
Events
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/D
ataGridBundle/Datagrid/Builder.php#L89-L90
www.oroinc.com
Best Practices
● It’s faster to override service instead of fixing the
arguments with Compiler Pass
● You may enable autowiring and autoconfiguration for
endpoint application
● Do not use bundle inheritance
● If you need to override only one route - create new
controller and define route with the same name
www.oroinc.com
Best Practices
www.oroinc.com
Extend functionality
with bundles:
Practice session
76
www.oroinc.com
● add bundle Training/UserNamingBundle
● decorate Oro\Bundle\LocaleBundle\
Provider\EntityNameProvider service
www.oroinc.com
Entities
and their data
www.oroinc.com
Entities
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Entity/Group.php
www.oroinc.com
Entity repositories
[Example]
www.oroinc.com
Quiz
$this
->getDoctrine()
->getManager()
->getRepository(Config::class)
->findAll();
Demonstration >>>
www.oroinc.com
Entity managers
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/Platfor
mBundle/Resources/config/oro/app.yml
www.oroinc.com
Avoid using default manager
$this
->getDoctrine()
->getManager()
->getRepository(Config::class)
->findAll();
● The class
'Oro\Bundle\ConfigBundle\Entity\Config' was
not found in the chain configured namespaces
Demonstration >>>
www.oroinc.com
Get entity using
ManagerRegistry
www.oroinc.com
Get entity using
DoctrineHelper
www.oroinc.com
Entity configuration
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBundle/
Entity/Contact.php
www.oroinc.com
Entity configuration: CLI commands
● bin/console oro:entity-config:update
○ Updates configuration data for entities.
● bin/console oro:entity-config:cache:clear
○ Clears the entity config cache.
● bin/consol oro:entity-config:cache:warmup
○ Warms up the entity config cache.
www.oroinc.com
Entity configuration: UI
● Attachments
○ Contact entity - view page
○ Enable attachments
○ Update schema + (optional) show DB
○ Add attachment to Contact
● Auditable
○ Edit firstName
○ Show change history
○ Disable auditable
○ Show change history
www.oroinc.com
Extended entities
[Video presentation]
www.oroinc.com
Extended entities: Code
● Examples
○ Add field to an extended entity
○ Add relation to an extended entity
● Extend extension
www.oroinc.com
Extended entities: UI
● Contact - UI
○ Create field products (one-to-many to Product)
○ Edit any Contact -> add products
● Contact - code
○ cache
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBundle/
Entity/Contact.php
www.oroinc.com
Custom entities
www.oroinc.com
Custom entities: UI
www.oroinc.com
Migrations
www.oroinc.com
Bundle installation
Demonstration >>>
www.oroinc.com
Bundle version
Installer v1_1
v1_1 Migration v1_1
Installer v1_2
v1_2 Migration v1_1 Migration v1_2
www.oroinc.com
Installer
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bundle/Pro
ductBundle/Migrations/Schema/OroProductBundleInstaller.php
www.oroinc.com
Migrations
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bundle/P
roductBundle/Migrations/Schema/v1_9/MakeVisibleDefaultProductA
ttributes.php
www.oroinc.com
Data fixtures
● Doctrine DataFixtures
● No version (usually)
● Interaction with ORM
● Types
○ Dependent, ordered, versioned
● Migrations/Data/ORM/<file>.php
● bin/console oro:migration:data:load
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bundle
/ProductBundle/Migrations/Data/ORM/LoadProductUnitData.php
www.oroinc.com
Demo data fixtures
https://github.com/oroinc/orocommerce/blob/4.1/src/Oro/Bund
le/ProductBundle/Migrations/Data/Demo/ORM/LoadProductDe
moData.php
www.oroinc.com
MigrationBundle
● https://doc.oroinc.com/backend/bundles/platf
orm/MigrationBundle/
● https://doc.oroinc.com/backend/entities-data-
management/data-fixtures/
www.oroinc.com
Datagrid
www.oroinc.com
Datagrid
Demonstration UI >>>
www.oroinc.com
Configuration of datagrid
● ORM query - select, from, where, groupBy
● Columns - label, frontend type
● Filters - type, data name
● Sorters - data name, default
● Properties
● Single actions and mass actions
● Resources/config/oro/datagrids.yml
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Resources/config/oro/datagrids.yml
www.oroinc.com
Customization of datagrid
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/EntityP
aginationBundle/Datagrid/EntityPaginationExtension.php
www.oroinc.com
Datagrid - exercise
www.oroinc.com
Entity index page
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Controller/GroupController.php#L70-L75
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Resources/views/Group/index.html.twig
www.oroinc.com
Entity CRUD
● Create
● Read
● Update
● Delete
www.oroinc.com
Read: Code
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/DemoData
Bundle/Migrations/Data/Demo/ORM/LoadGroupData.php#L77
www.oroinc.com
Read: Controller
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBu
ndle/Controller/UserController.php#L40-L46
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBu
ndle/Resources/views/User/view.html.twig
www.oroinc.com
Create: Code
● Create entity object
● EntityManager::persist
● EntityManager::flush
● Created entities are stored in UnitOfWork
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBu
ndle/Migrations/Data/ORM/LoadSourceData.php
www.oroinc.com
Create: Controller
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Controller/UserController.php#L121-L126
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Resources/views/User/update.html.twig
www.oroinc.com
Update: Code
● Get entity
● Change entity
● EntityManager::persist
● EntityManager::flush
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Migrations/Data/ORM/UpdateUserEntitiesWithOrganization.p
hp#L39-L56
www.oroinc.com
Update: Controller
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBu
ndle/Controller/UserController.php#L143-L146
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBu
ndle/Resources/views/User/update.html.twig
www.oroinc.com
Delete: Code
● Get entity
● EntityManager::remove
● EntityManager::flush
● Deleted entities are removed from UnitOfWork
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBu
ndle/Entity/BaseUserManager.php#L119-L121
www.oroinc.com
Delete: Controller
● No need to have it
● Actions added automatically
○ or via API, e.g. oro_api_delete_contact
○ [More info]
www.oroinc.com
Menu
● Uses KnpMenuBundle
● ORO: NavigationBundle
● Represented by a tree structure
● Label
● Route
● Position
● Resources/config/oro/navigation.yml
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserB
undle/Resources/config/oro/navigation.yml
www.oroinc.com
Customization of menu
● UI
● Config - Resources/config/oro/navigation.yml
● ConfigureMenuEvent
○ oro_menu.configure.<menu_name>
● Menu extension
○ oro_navigation.menu_extension
● Menu builder
○ oro_menu.builder
● + page titles
[example]
www.oroinc.com
Menu - exercise
www.oroinc.com
Validation
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBu
ndle/Resources/config/validation.yml
www.oroinc.com
Search
www.oroinc.com
Search demo
● UI - quick search
● API - simple + advanced
○ search=Debra from=oro_contact
○ select firstName from oro_contact where
firstName ~ 'Debra'
● DB - structure
● bin/console oro:search:reindex
○ --scheduled !!!
● QueryBuilder
○ Oro\Bundle\SecurityBundle\Search\AclHel
per::apply
www.oroinc.com
Search docs
● https://doc.oroinc.com/backend/bundles/platform/S
earchBundle/
● Search Component Architecture
● Configuration file structure
www.oroinc.com
Autocomplete
Demonstration >>>
www.oroinc.com
Name provider
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBun
dle/Provider/ContactEntityNameProvider.php
www.oroinc.com
Name provider demo
● UI - contact
● ContactEntityNameProvider
● Twig: entity|oro_format_name
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/Locale
Bundle/Resources/doc/reference/name-formatting.md
https://doc.oroinc.com/user/back-office/system/localization/
www.oroinc.com
Entity aliases
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/EntityBundle
/Resources/doc/entity_aliases.md
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/UserBundle/
Resources/config/oro/entity.yml
www.oroinc.com
Virtual fields and relations
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBu
ndle/Resources/config/oro/entity.yml#L2-L38
www.oroinc.com
Best Practices
● Use standard Doctrine fields, relations and entities
instead of the extended ones if possible
● If you need bidirectional relations to Oro core entity - use
extended relations
● If you need to work with entities really fast (e.g. import
them very fast) - use plain SQL through Doctrine DBAL
(e.g. Doctrine\DBAL\Query\QueryBuilder) instead of
Doctrine ORM, but remember that in this case all
functionality that works on Doctrine events (data audit,
search reindexation) will not work and you have to handle
it manually
www.oroinc.com
Best Practices
● Avoid Doctrine object hydration if you work with lots of
entities (performance issue), use array hydration instead
● You may add or modify Doctrine annotations of an
existing entity class or an existing field with
LoadClassMetadata event
● You may disable some event listeners completely (by
removing the specific services) or temporary (see
OptionalListenerInterface and --disabled-listeners CLI
command option)
● Do not define repository as a service
www.oroinc.com
Best Practices
● New section to datagrid configuration (column,
filter, sorter, action etc) can be added using
datagrids.yml file only - configuration sections
are simply merged there
● Make sure that all visible static values are
translated - e.g. field labels
● Make sure that all visible dynamic values are
localized - e.g. date/times, decimal / money
values, localizable values
www.oroinc.com
Security and
Access Control
Lists
www.oroinc.com
General information
https://doc.oroinc.com/backend/security/example/
www.oroinc.com
Ownership
● Entity may have an owner
● Owner is represented by one of the entities:
○ User
○ Business Unit
○ Organization (EE only)
● Owner is used to check permissions
● Specified at the entity configuration
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBun
dle/Entity/Contact.php#L51-L57
www.oroinc.com
Security
Demonstration >>>
www.oroinc.com
Entity permissions
● Permissions
○ VIEW, CREATE, EDIT, DELETE, ASSIGN, …
○ permissions.yml
● Access levels without ownership
○ None, Global
● Access levels with ownership
○ None, User, Business Unit, Division,
Organization, Global
[Documentation]
www.oroinc.com
Entity permissions
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBu
ndle/Entity/Contact.php#L58-L62
www.oroinc.com
Ownership Access Levels
Global
Organization
Division
Business Unit
User
None
www.oroinc.com
How to define entity permissions
● Controller annotations
○ [example]
● Resources/config/oro/acls.yml
○ [example]
www.oroinc.com
How to check entity permissions
// PHP code
$checker = $this->container->get('security.authorization_checker');
$checker = $this->container->get(AuthorizationCheckerInterface::class);
if ($checker->isGranted('VIEW', $entity)) {
.yml
acl_resource: acl_name
{# Twig template #}
{% if is_granted('VIEW', entity) %}
{% endif %}
www.oroinc.com
Example: Call center
Administrator
Manager of organization
www.oroinc.com
Example: Operator
www.oroinc.com
Example: Operator
www.oroinc.com
Example: Manager of department
www.oroinc.com
Example: Manager of department
www.oroinc.com
Example: Manager of call center
www.oroinc.com
Example: Manager of call center
www.oroinc.com
Example: Manager of organization
www.oroinc.com
Example: Manager of organization
www.oroinc.com
Example: Administrator
www.oroinc.com
Example: Administrator
www.oroinc.com
Example: Call center with hierarchy
Administrator
www.oroinc.com
Action permissions (capabilities)
Demonstration UI >>>
www.oroinc.com
How to define action permissions
www.oroinc.com
How to check action permissions
// PHP code
$checker = $this->container->get('security.authorization_checker');
$checker = $this->container->get(AuthorizationCheckerInterface::class);
if ($checker->isGranted('capability_name')) {
.yml
acl_resource: capability_name
{# Twig template #}
{% if is_granted('capability_name') %}
{% endif %}
www.oroinc.com
More
● Workflow permissions
● Field based ACL
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bridge/TaskCRM/
Migrations/Data/ORM/CrmRoles/workflows.yml
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/Secur
ityBundle/Resources/doc/field-acl.md
www.oroinc.com
Docs
https://doc.oroinc.com/user/back-office/system/user-management/roles/
https://doc.oroinc.com/backend/security/
www.oroinc.com
Best Practices
www.oroinc.com
Security and
Access Control Lists:
Practice session
159
www.oroinc.com
● add security section to UserNamingType entity
○ no ownership
www.oroinc.com
Import and Export
of Entities
www.oroinc.com
General information
● Uses AkeneoBatchBundle
● Works asynchronously (via consumer)
● Executed in parallel
● Used by integrations with data sync
https://docs.spring.io/spring-batch/trunk/reference/html/do
main.html
www.oroinc.com
Jobs
https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/Import
ExportBundle/Resources/config/batch_jobs.yml
www.oroinc.com
Reader > Processor > Writer
Reader
● reads data rows from data source
● returns one data row at a time
Processor
● processes one data row
● returns one processed data row at a time
Writer
● receives batch of data rows
● saves data rows to data source
www.oroinc.com
Processors
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBu
ndle/Resources/config/importexport.yml
www.oroinc.com
Data Converters
www.oroinc.com
Normalizers
[Symfony serializer]
www.oroinc.com
Import Strategy
[Custom Strategy]
[Custom Strategy - definition]
www.oroinc.com
Processor types
● import_validation
● import
● export_template
● export
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/ContactBun
dle/Resources/config/importexport.yml
www.oroinc.com
Import Validation
CSV File Reader
Import Processor
● Data converter
● Serializer
● Strategy
Null Writer
www.oroinc.com
Import
CSV File Reader
Import Processor
● Data converter
● Serializer
● Strategy
Entity Writer
www.oroinc.com
Export template
Template Fixture Reader
Export Processor
● Data converter
● Serializer
www.oroinc.com
Export
Entity Reader
Export Processor
● Data converter
● Serializer
www.oroinc.com
Entity field configuration
● @ConfigField annotation
● Section/scope: importexport
● Fields:
○ header
○ order
○ identity
○ excluded
○ short
● UI
www.oroinc.com
Entity field configuration: Example
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundle/Entit
y/Lead.php
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundle/Res
ources/config/importexport.yml
www.oroinc.com
Import and Export buttons
● OroImportExportBundle:ImportExport:
○ buttons.html.twig
○ buttons_from_configuration.html.twig
● Pass entity class and processor aliases
● Usually placed at index page
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundl
e/Resources/views/Lead/index.html.twig#L9-L11
https://doc.oroinc.com/backend/integrations/import-export/
www.oroinc.com
Potential issues
● Configuration:
○ Problem: Need to use custom data format
○ Solution: Implement custom data converter,
serializer, strategy or whole processor
● Performance:
○ Problem: Too slow (because of ORM)
○ Solution: Work directly with DBAL
www.oroinc.com
Best Practices
www.oroinc.com
Best Practices
www.oroinc.com
Import and Export
of Entities:
Practice session
180
www.oroinc.com
● Add simple import and export for UserNamingType
entity
○ available from index page
○ use default data converter, serializer and strategy
○ use buttons_from_configuration.html.twig macro
to display buttons
www.oroinc.com
API
www.oroinc.com
General information
www.oroinc.com
General information
● Based on the ChainProcessor
○ Organizes data processing flow
● Commands
○ oro:wsse:generate-header
○ oro:api:cache:clear
○ oro:api:doc:cache:clear
○ oro:api:debug
○ more
● Sandbox (/admin/api/doc & /api/doc)
● Plain API is outdated!!
Demonstration UI - sandbox >>>
www.oroinc.com
Authentication - oAuth2
● Generate private/public keys - configuration
○ var/oauth_private.key & var/oauth_public.key
● Add application
www.oroinc.com
Authentication - oAuth2
● Copy Client ID and Client secret
www.oroinc.com
Authentication - oAuth2
● Generate token
(e.g. using
Postman)
○ Endpoint:
/oauth2-token
www.oroinc.com
Authentication - oAuth2
● Add generated token to request header
www.oroinc.com
Actions
www.oroinc.com
General configuration
● Entity based
● Generated automatically for specified entities
● Custom entity aliases
● Excluded entities and fields
● Filters
● Sorters
● Validation
● X-Include header
www.oroinc.com
Entity configuration
● May be excluded
● Documentation (!)
● Max results
● Default order
● Form to process create and edit
● Delete handler
[Documentation]
www.oroinc.com
Field configuration
● May be excluded
● Data type
● May refer to other property (property path)
● Symfony Form Data transformers are used
● Form to process create and edit
● Meta property
[Documentation]
www.oroinc.com
Filters configuration
● May be excluded
● Data type
● Multiple values
○ allow_array: true + comma separated (see: notes)
● May refer to other property (property path)
● Operators
● Custom filters + custom options: config
● Added for fields with indexes by default
[Documentation]
www.oroinc.com
Sorters configuration
● May be excluded
● May refer to other property (property path)
● Added for fields with indexes by default
[Documentation]
www.oroinc.com
Actions configuration
[Documentation]
www.oroinc.com
Processors
www.oroinc.com
Context
● Stores configuration, metadata, request and result
● Action specific
● Passed to all processors
● Data can be changed
○ Example
[Documentation]
www.oroinc.com
Processor Groups
● Action specific
● Executed one by one
● Processors inside the same group are
executed according to their priority
● bin/console oro:api:debug
[Documentation]
www.oroinc.com
X-Include header
[Documentation]
www.oroinc.com
Example
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundle/Res
ources/config/oro/api.yml
www.oroinc.com
Documentation
● How to
○ Add a custom controller
○ Expose an API for non-entity resource
○ Enable custom API
www.oroinc.com
API:
Practice
session
202
www.oroinc.com
● add default API for UserNamingType entity
https://doc.oroinc.com/backend/api/configuration/#fields-config
www.oroinc.com
Integrations
www.oroinc.com
What is integration?
www.oroinc.com
Ways to integrate
www.oroinc.com
Simple controller or CLI command with
hardcoded configuration
+ Easy to build
+ Quick implementation
- Not configurable
- Not flexible
- Hard to support
- Only one instance
www.oroinc.com
Simple controller or CLI command with
configuration at the system configuration
+ Easy to build
+ Quick implementation
+ Configurable
- Not flexible
- Hard to support
- Only one instance
www.oroinc.com
Proper implementation with configuration at the
system configuration
+ Configurable
+ Flexible
+ Easy to support
- Hard to build
- Slow implementation
- Only one instance
www.oroinc.com
Proper implementation with
configuration at the integration channel
+ Configurable
+ Flexible
+ Easy to support
+ Multiple instances
- Hard to build
- Slow implementation
www.oroinc.com
Configuration sources
● System configuration
○ One on the global level
○ One per each scoped entity
■ (ex. Organization -> MS Exchange) todo:
remove
● Integration channels
○ Any amount of integrations
○ Ability to trigger data synchronization
○ Log
Demonstration UI >>>
www.oroinc.com
Integration (sync)
www.oroinc.com
Integration consists of...
● Channel type
● Transport
○ Settings entity
○ Settings form type
● Connectors
www.oroinc.com
Channel Type
www.oroinc.com
Transport
www.oroinc.com
Transport Settings: Entity
● Extends OroIntegrationBundle:Transport
● Uses single table inheritance - Doctrine docs
○ Remember about a migration
● Contains settings
● Returns list of settings using ParameterBag
● [Zendesk example]
www.oroinc.com
Transport Settings: Form type
www.oroinc.com
Connector
www.oroinc.com
Overall schema
Channel type
Transport Connector 1
Settings form
Connector 3
type
www.oroinc.com
Integration types
● Data based
○ Import and export of entities
○ Connectors
○ Synchronization (sync)
● Operation based
○ Operation calls (local or RPC)
○ No connectors
○ No synchronizations
● Combined
www.oroinc.com
Possible issues
www.oroinc.com
Best Practices
www.oroinc.com
Docs
● https://doc.oroinc.com/user/back-office/system/integrations/
● https://doc.oroinc.com/backend/integrations/
● https://github.com/oroinc/platform/tree/4.1/src/Oro/Bundle/In
tegrationBundle
www.oroinc.com
Workflows
www.oroinc.com
Overview
● Representation of a business process
○ checkout with approval, closing opportunity, status
www.oroinc.com
General information
● State machine
● Assigned to entity
● States = steps
● Internal data = attributes
● Changes of states = transitions
● Actions and conditions = transition definitions
● Data restrictions = entity restrictions
www.oroinc.com
Workflow Definition
● Resources/config/oro/workflows.yml
○ Includes are allowed (imports)
● oro:workflow:definitions:load
● oro:debug:workflow:definitions
● WorkflowDefinition entity
● Translations for labels are in a separate file
○ oro:workflow:translations:dump
● User may add simple definitions from UI
● Developer may add custom definitions from YML
www.oroinc.com
Workflow Item
Demonstration >>>
UI -> manually start workflow
DB -> new record
www.oroinc.com
Steps
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundl
e/Resources/config/oro/workflows/opportunity_flow/steps.yml
www.oroinc.com
Attributes
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundl
e/Resources/config/oro/workflows/opportunity_flow/attributes.yml
www.oroinc.com
Attributes
● $.data.status
○ attribute “status”
● $status
○ attribute “status” (same as above)
● $.result.status
○ temporary data (not persistent), useful for
dependent actions but in case when there is no need
to store this information in an attribute
● $.status
○ PropertyAccessor->getValue(WorkflowItem, status)
○ Will throw exception
www.oroinc.com
Variables
● Changeable configuration ● Accessed like
values on a workflow level attributes
○ Data is serialized ● [example]
● [docs]
www.oroinc.com
Entity Restrictions
● Restrict modification of attribute fields
● Might be assigned to step
○ restriction will be applied only in this step
● Mode: full, disallow, allow
○ Default: full
● Example
● Docs
www.oroinc.com
Transitions
● Represent change of state
● Lead to one workflow step
● Workflow has one or more start transitions
● Might have a form with attribute fields
● Might have ACL restriction
● Might have assigned conditions
● Might have related actions
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundle/Res
ources/config/oro/workflows/opportunity_flow/transitions.yml
www.oroinc.com
Transition Definitions
https://github.com/oroinc/crm/blob/4.1/src/Oro/Bundle/SalesBundl
e/Resources/config/oro/workflows/opportunity_flow/transition_defi
nitions.yml
www.oroinc.com
Actions
www.oroinc.com
Conditions
www.oroinc.com
Translations
www.oroinc.com
Operations
www.oroinc.com
Processes
● Executed on:
○ Create, update, delete of entity or specific field
○ Cron
● Can be delayed with `time_shift`
● Use actions and conditions
[Documentation]
www.oroinc.com
Additional features
● Scopes
○ Documentation
www.oroinc.com
Best Practices
www.oroinc.com