OroCRM Partner Technical Training
September 2015
Schedule:
Day 1 - Monday 9/14
Define your Entities
--Environment and Project Setup
--Packages Management
--Entities and DB Schema Management
--Entity CRUD Implementation
Day 2 - Tuesday 9/15
Security and Productivity
--ACL
--Entity Activities
--System Configuration
Day 3 - Wednesday 9/16
User Interface
--Layouts and Templates
--CSS and JavaScript
--Widgets
--Navigation
--Localizations
Day 4 - Thursday 9/17
Integrate your Solution
--Job Queue
--Import and Export
--Integrations
--Automated Processes
--WEB API
Day 5 - Friday 9/18
Work with Data
--Workflow
--Reports
--Analytics and Marketing
--Tests
13. Developer Training
What is Doctrine entity?
Entities are PHP Objects that can be identified over many requests by a unique
identifier or primary key. These classes don’t need to extend any abstract base
class or interface. An entity class must not be final or contain final methods.
Additionally it must not implement clone nor wakeup or do so safely.
An entity contains persistable properties. A persistable property is an instance
variable of the entity that is saved into and retrieved from the database by
Doctrine’s data mapping capabilities.
Doctrine 2 ORM Documentation
http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html
Entities
14. Developer Training
Example of Doctrine's entity
● class: OroCRMBundlePartnerBundleEntityPartner
● DB table: orocrm_partner
Entities
15. Developer Training
Configurable Entity
• configuration is stored in the database
• two levels of configuration fields: entity and entity field
• different scopes
• configuration file: Resources/config/entity_config.yml
• access configuration fields via services
• change entity configuration in the UI
Entities
16. Developer Training
Example of using Entity Configuration
OroDataAuditBundle is responsible for audition of entity’s
changes. It introduces configuration scope and field with
name “auditable”.
When data of entity is modified this bundle checks the
value of configuration field and if it's “true”, then it adds
respective record to audition log.
Thus any bundle could use Entity Configuration to build it's
own business logic.
Configurable Entity
17. Developer Training
Define configuration schema
• Each bundle can contain file with configuration schema:
Resoures/config/entity_config.yml
• contains definitions of config fields on level of entity and
field, options used in UI to display these config fields
• Example of configuration schema:
Oro/Bundle/DataAuditBundle/Resources/config/entity_config.yml
Configurable Entity
18. Developer Training
Add entity annotations
• annotation classes:
OroBundleEntityConfigBundleMetadataAnnotationConfig
OroBundleEntityConfigBundleMetadataAnnotationConfigField
• example of @Config and @ConfigField annotations in
OroCRMPartnerBundle:Partner entity
Configurable Entity
19. Developer Training
UI management
• System → Entities → Entity Management
• configurable fields are displayed on different pages,
depending on configuration schema: grid, view, form
Configurable Entity
20. Developer Training
Main Commands
• oro:entity-config:cache:clear
This command removes all data related to configurable entities
from the application cache.
• oro:entity-config:update
This command can be used to update configurable entities. Usually
you need to execute this command only in “dev” mode when new
configuration attribute or whole configuration scope is added.
• oro:entity-config:debug
Debugging entity configuration.
Configurable Entity
21. Developer Training
Extended Entity
• useful for customization of entity if you not own it’s code
• add mapped Doctrine fields to entity without updating
code of entity
• add/remove fields dynamically using UI
• show added fields on view, form, grid
• support scalar fields and relations to other entities
Entities
22. Developer Training
Creating Extended Entity
• Extend entity from class with special name
• Run command oro:migration:load
This command will do all necessary updates of schema and generate
Extend entity caches.
• (Optional) Add new fields using migrations
Important
• this class should be empty, it will be replaced dynamically with class
generated in cache: app/cache/%env%/oro_entities/Extend/Entity
• don’t forget to call parent::__construct
Extended Entity
23. Developer Training
Adding Fields to Extended Entity
• using migrations
preferable in case of customization development
• using UI
preferable as a quick way if client code won’t rely on presence of this field
Extended Entity
24. Developer Training
UI management
• System → Entities → Entity Management
• Configurable fields are displayed on different pages, depending on
configuration schema: grid, view, form
Important
• It's not recommended to build business logic that relies on fields that were
added to entities from the UI, because there are no guarantees that they
won't be removed.
Extended Entity
25. Developer Training
Custom Entity
• create entity using UI or migrations
• manage fields of custom entities
• manage entity configuration
• auto-generated CRUD for custom entity records
Entities
28. Developer Training
Overview
Database Schema Migrations functionality is intended to
help manage changes of database schema.
Goals
• control state of application's database schema
• allow database schema upgrades via schema
migrations
Database Schema Migrations
29. Developer Training
Migration Class
• Each migration represents incremental change of database scheme
• Must implement OroBundleMigrationBundleMigrationMigration
• Must be located in %BundleDirectory%/Migrations/Schema/version_number
• Version number must be an PHP-standardized version number string
without "." and "+" characters as a version parts separator
• Method up method receives:
• schema – current database structure. With schema parameter, you
can create or update database structure without fear of compatibility
between database engines.
• queries bag – use it if you want to execute additional SQL queries
before or after applying a schema modification. A query can be a
string or an instance of a class implements MigrationQuery interface.
Database Schema Migrations
30. Developer Training
Migrations Persistence
• Executed migration saved in database table
oro_migrations
• This record is represented by entity
OroBundleMigrationBundleEntityDataMigration
Database Schema Migrations
31. Developer Training
Installation Class
• Must implement OroBundleMigrationBundleMigrationInstallation
• getMigrationVersion method must return max migration version number that
this installation file replaces
• Replaces running multiple migration files
Database Schema Migrations
32. Developer Training
Load Migrations Command
oro:migration:load
This command collects migration files from bundles, sorts them by version
number and applies changes.
Parameters
• force – causes the generated by migrations SQL statements to be
physically executed against your database;
• dry-run – outputs list of migrations without apply them;
• show-queries – outputs list of database queries for each migration file;
• bundles – a list of bundles to load data from. If option is not set, migrations
will be taken from all bundles;
• exclude – a list of bundle names which migrations should be skipped.
Database Schema Migrations
33. Developer Training
Dump Migrations Command
oro:migration:dump
• outputs current database structure in format of plain SQL queries
• outputs generated PHP class of migration
Generated PHP code could be used to write migration classes during
development:
1. Create your bundle and all entities with proper Doctrine's mapping
2. Run command doctrine:schema:update --force to apply schema changes
3. Run command oro:migration:dump > dump.php to generate PHP code of
migrations
4. Browse generated file and copy all migrations code related to your entities
into proper migration class.
Database Schema Migrations
34. Developer Training
Extensions for Migrations
Extension encapsulates some part of migration logic that can be reused in
migrations of other bundles.
Examples:
OroBundleMigrationBundleMigrationExtensionRenameExtension
helps to rename existing tables without loss of data
OroBundleEntityExtendBundleMigrationExtensionExtendExtension
adds extended relation field, custom entities, enums
OroBundleActivityBundleMigrationExtensionActivityExtension
adds association of entity with one of activity's entity
Database Schema Migrations
35. Developer Training
Create Migration Extension
• Create extension class in YourBundle/Migration/Extension directory
• Create interface %YourExtensionName%ExtensionAwareInterface
• Register an extension in container with tag oro_migration.extension
• Now you can add set%YourExtensionName%Extension method to
migration class and instance of extension will be injected
Database Schema Migrations
37. Developer Training
Overview
Data Fixtures is a way to programmatically create entities and other data
during installation and upgrade process. This functionality is based on
Doctrine's fixtures and guarantees that each data fixture will be loaded only
once.
Data Fixtures
38. Developer Training
Fixtures Types
Main
Delivered with bundle by default. For example, entities of predefined roles of
Administrator, Manager and User.
Demo
Can be loaded optionally to create bundle's entities intended to demonstrate its
features.
Data Fixtures
39. Developer Training
Fixture Class
• Must implement DoctrineCommonDataFixturesFixtureInterface
• Optionally can implement
DoctrineCommonDataFixturesDependentFixtureInterface to load dependent
fixtures first
• Main fixtures must be placed in directory Migrations/Data/ORM
• Demo fixtures must be placed in directory Migrations/Data/Demo/ORM
Data Fixtures
40. Developer Training
Load Fixtures Command
oro:migration:data:load
This command guarantees that each data fixture will be loaded only once.
Parameters
• fixtures-type – select fixtures type to be loaded (main or demo). By default
- main
• dry-run – outputs list of fixtures without apply them
• bundles – a list of bundle names to load data from (multiple values
allowed)
• exclude – a list of bundle names which fixtures should be skipped
(multiple values allowed)
Data Fixtures
41. Developer Training
Data Fixture State Persistence
• Executed migration saved in database record in table oro_migrations_data
• This record is represented by entity
OroBundleMigrationBundleEntityDataFixture
Data Fixtures
42. Developer Training
Fixture With Version
• Implement OroBundleMigrationBundleFixtureVersionedFixtureInterface
• getVersion method must returns a version of fixture data
• To load this fixture again, return a greater version
• Optionally implement
OroBundleMigrationBundleFixtureLoadedFixtureVersionAwareInterface to
know the last loaded version
• Example of fixture with version
OroCRMBundleMagentoBundleMigrationsDataORMLoadShoppingCartStatusData
Data Fixtures
44. Developer Training 44
Search
- MySQL Fulltext as default engine
- Mapping configuration: Resources/config/search.yml
- Commands
- oro:search:index
- oro:search:reindex
- API
http://www.orocrm.com/documentation/index/current/book/search
https://github.com/orocrm/platform/tree/master/src/Oro/Bundle/SearchBundle
45. Developer Training 45
Data Audit
DataAuditBundle
- Based on Loggable Doctrine extension
- Annotation and Entity Config support
@Config(
defaultValues={
"dataaudit"={
"auditable"=true
}
}
)
- Access to data changes log
47. Developer Training
Overview
Datagrid is table oriented representation of some data from some
datasource. It's configuration is declarative YAML based file, that
should be placed in Resources/config folder of your bundle and named
datagrid.yml.
Datagrids
48. Developer Training
Datasource
• Type
• Query
• Parameters binding
http://www.orocrm.com/documentation/index/current/cookbook/how-to-
pass-request-parameter-to-grid
Datagrids
50. Developer Training
Extensions
• Formatter - responsible for backend field formatting (e.g
generating url using router, translate using symfony translator,
etc..)
• Pager - responsible for pagination
• Sorter - responsible for sorting
• Action - provides actions configurations for grid
• Mass Action - provides mass actions configurations for grid
• Toolbar - provides toolbar configuration for view
• Grid Views - provides configuration for grid views toolbar
• Export - responsible for export grid data
Datagrids
51. Developer Training
Extending Grids
Grids could be extended in few ways:
• create custom datasource if needed (e.g. already implemented
SearchDatasource for working with search engine)
• create custom extension
• create some addons to already registered extensions (e.g. some
specific backend formatter)
• change base datagrid or base acceptor class (they are passed to
builder as DI parameters)
• add listener for datagrid events
Datagrids
52. Developer Training
Datagrid Events
• oro_datagrid.datagrid.build.pre
• oro_datagrid.datagrid.build.before(.my-grid)
- validage datagrid config and apply necessary config changes
• oro_datagrid.datagrid.build.after(.my-grid)
- add filters or query parameters to the grid datasource
• oro_datagrid.orm_datasource.result.before(.my-grid)
- make changes to the data source right before the data is retrieved, e.
g. add ACL restrictions to the query
• oro_datagrid.orm_datasource.result.after(.my-grid)
- make changes to already fetched result data
Datagrids
57. Developer Training
Controller
• Controller: DemoBundle/Controller/MyNewController.php
• Routing configuration in oro/routing.yml
• Action methods
• @Route and @Template annotations
CRUD
58. Developer Training
Form and Form Handler
Form
- Holds controls for every Entity field
- Form Types for complex fields
- Sets default values
Form Handler
- Validates Form
- Submits Form
- Saves Form Data
CRUD
59. Developer Training
Templates
By default templates are looked up in Resources/views/DemoEntity/
Automatically mapped to controller actions:
• view.html - View action
• update.html - Create and Update actions
You can specify custom templates in Controller @Template annotation
CRUD
64. Developer Training 64
Web API
- Integration with application data
- Frontend flexibility
- Multiple versions support
- Security
- API Token
- oro:wsse:generate-header
https://github.
com/orocrm/platform/tree/master/src/Oro/Bundle/SoapBundle
Web API
65. Developer Training 65
REST
- FosRestBundle
- Routing
- Versioning
- Documentation and Sandbox
- NelmioApiDoc Bundle
- @ApiDoc annotation
Web API
66. Developer Training 66
Sample CRUD
Controller
• @RouteResource annotation
• @NamePrefix annotation
Actions:
● Get List: cgetAction
● Get Entity: getAction
● Create: postAction
● Update: putAction
● Delete: deleteAction
Routes:
● oro/routing.yml and oro/routing_api.yml
● automatic route generation for entities
Web API
67. Developer Training 67
REST: Additional Info
Headers
- Request:
X-Include: totalCount, lastModifiedDate
- Response:
X-Include-Total-Count: 200
X-Include-Unknown: lastModifiedDate
Handler
- extend
OroBundleSoapBundleRequestHandlerIncludeHandlerInterface
- oro_soap.include_handler tag
https://github.
com/orocrm/platform/tree/master/src/Oro/Bundle/SoapBundle
Web API
68. Developer Training 68
SOAP
- BeSimple SoapBundle
- WSDL generation
- Types
- Controllers and Actions
http://besim.pl/SoapBundle
Web API
70. Developer Training 70
- ACL stands for Access Control List
- responsible bundle is OroSecurityBundle
- provides user access only to appropriate levels of
information that is required
- categorizes users by their roles and restricts access
based on those roles
- prevents user access to records the user does not
allowed to access
- based on Symfony standard security model
- all benefits of Symfony ACL security are supported
ACL Overview
Security & ACL
71. Developer Training 71
Example of restricting access to domain objects
- consider some domain object, e.g. a comment of blog
- user able to edit their own comments
- administrators able to edit all comments
Possible Approaches
- enforce security in your business methods: keeping a reference inside
each comment to all users who have access, compare these users to
provided token
- enforce security with roles: you would add a role for each Comment
object, i.e. ROLE_COMMENT_1, ROLE_COMMENT_2, etc.
Problems
- couple authorization logic to business code which makes it less
reusable
- increase the difficulty of unit testing
- performance issue if many users will have access to a single domain
object
Introduction to ACL
Security & ACL
72. Developer Training 72
Solution
- enforce security with ACL approach
Example of using Symfony ACL, reference to documentation
- http://symfony.com/doc/current/components/security/introduction.html
- http://symfony.com/doc/current/cookbook/security/acl.html
- http://symfony.com/doc/current/cookbook/security/acl_advanced.html
Introduction to ACL
Security & ACL
73. Developer Training 73
The security bundle comes with the following five access levels:
- User
own records
- Business Unit
records in records in all business units user is assigned to.
- Division
same as the Business Unit level plus subordinate Business Unit
- Organization
all records within the organization
- System
The user can access all objects within the system
Access Levels
Security & ACL
74. Developer Training 74
Permissions
- VIEW
Controls whether a user is allowed to view a record.
- CREATE
Controls whether a user is allowed to create a record.
- EDIT
Controls whether a user is allowed to modify a record.
- DELETE
Controls whether a user is allowed to delete a record.
- ASSIGN
Controls whether a user is allowed to change an owner of a record.
For example assign a record to another user.
Security & ACL
75. Developer Training 75
Configuring entity ACL
- use entity configuration with “security” scope
- set the list of supported permissions using
“permissions” parameter:
- "All" to consider all available security permissions
- “VIEW;EDIT” to consider only specified permissions
Security & ACL
79. Developer Training 79
Permissions Management UI
System → User Management → Roles
- manage roles
- manage entity privileges of role
System → User Management → Users
- assign roles to users
- assign users to business units and organizations
Security & ACL
82. Developer Training
Overview
• Special entities representing customer-related activities
such as phone calls, emails, tasks, etc.)
• Can be associated to other entities from the UI
• Associations can be enabled in the Entity Management
section
• Add activity button
• Activity Lists
Activities
86. Developer Training
Notes and Comments
• Enabling Notes for an Entity
- From the UI
- By Migrations
• Enable Comments for an Activity
- From the UI
- By Migrations
Activities
88. Developer Training
New Activity
Enable Activity Associations
• Migration:
use OroBundleActivityBundleMigrationExtensionActivityExtension
• Change associations in the UI
Activities
89. Developer Training
New Activity
Configure UI
• Activity List
- Controller action
- TWIG Template
- Datagrid definition
- Entity configuration
- Activity List provider
• Activity Button
- Button and Link templates
- Placeholders
- Entity configuration
Activities
92. Developer Training 92
System Configuration
● Multiple Scopes
- Global
- User
● Flexible configuration form:
Resources/config/system_configuration.yml
97. Developer Training
Introduction
• Twig overview
• OroUIBundle overview
• basic templates
• create and use templates
• override existing templates
Layout
UI customizations / Layout
98. Developer Training
Features
• available in Symfony 2 out of the box
• easy to learn: optimized for web designers
• has template oriented syntax: shortcuts for common patterns
• fast: compiles templates to plain optimized PHP code
• supports: multiple inheritance, blocks, automatic output-escaping, and much
more
• extensible: add custom tags, filters, functions, operators, nodes and tags
References
• http://twig.sensiolabs.org/documentation
• http://symfony.com/doc/current/book/templating.html
Twig Template Engine
UI customizations / Layout
104. Developer Training 104
Create And Use Templates
- create controller and pass data to view
- create template with name by pattern
bundle:controller:action
- extend one of basic templates of Oro
- override content block and/or other blocks
- (optional) pass data to parent template
- (optional) use widgets to separate content by
different blocks
- (optional) support extend fields in view and form
templates
UI customizations / Layout
105. Developer Training 105
Override Existing Template
Steps
- extend bundle or use app/Resources/views
- add template with same name
- extend template from parent
- override block and add customization
- (optional) override controller to pass extra data to
template
Alternative
- use placeholders
UI customizations / Layout
107. Developer Training 107
- a reusable UI element that is placed inside the widget
container
- widget content may be loaded immediately or via AJAX
request
- most of widgets reference to controller actions
- content can be refreshed
- examples of widgets: contact information, opportunity
information, address book, add address form, import
form, etc.
https://github.
com/orocrm/platform/blob/master/src/Oro/Bundle/UIBundle/Resources/
doc/reference/widgets.md
UI customizations
Widgets
108. Developer Training 108
● dialog – show widget content in dialog window
● button – show only included content without title and
actions
● block – display embedded widget content on page
On frontend Widget containers are Backbone views.
UI customizations / Widgets
Widget Container Types
109. Developer Training 109
● widget can be created from backend (in Twig templates)
or front-end (JS modules)
● Twig function oro_widget_render
● widgetType – widget type name
● url – URL used to load remote content
● elementFirst – flag to render widget without AJAX request using initial
content
● title – widget title
● alias – widget alias
● wid – unique widget identifier (generated)
UI customizations / Widgets
Rendering Widget
110. Developer Training 110
● extend @Template annotation behavior, try to match Twig templates
in next sequence:
- {bundleName}:{controllerName}:{widgetType}/{actionName}.html.twig
- {bundleName}:{controllerName}:widget/{actionName}.html.twig
- {bundleName}:{controllerName}:{actionName}.html.twig
● inside Twig template of widget content should be placed inside
element with class “widget-content”, actions could be placed inside
“widget-actions” element
UI customizations / Widgets
Widget Template
111. Developer Training
• JS modules
• oroui/js/widget/abstract
• oro/block-widget
• oro/buttons-widget
• oro/dialog-widget
• oroui/js/widget-manager
• widget manager adds ability of widget-to-widget, widget-
to-page and page-to-widget interaction based on
Backbone events and direct usage of widgets API
• each widget on page has its own unique widget
identifier, also a widget can be retrieved by its alias
UI customizations / Widgets
Widget Client Side
113. Developer Training 113
● dashboard is an entity with user owner
● permissions are managed using ACL
● user can have one active dashboard
● dashboard view page contains a set of blocks (widgets)
● dashboard widgets are also entities
● developer can add new widgets and dashboards
UI customizations
Dashboards
114. Developer Training 114
Dashboards Configuration
● Resources/config/dashboard.yml
● entities hold states of the specific dashboard and
dashboard widgets
● configuration holds static information used to render
dashboards and dashboard widgets
UI
119. Developer Training
Asset Management
- http://symfony.
com/doc/current/cookbook/assetic/asset_manageme
nt.html
- collecting CSS & LESS using config
- using Resources/config/assets.yml
Commands
- assets:install
- assetic:dump
Debug
Minification
UI customizations
CSS & LESS
120. Developer Training
• change fonts, colors, favicon and application logo
• CSS/LESS files that will be included at the end
• active theme app/config/config.yml
oro_theme:
active_theme: oro
• theme config Resources/public/themes/{theme_name}
/settings.yml
• oro:theme:list
• debugging theme CSS & LESS
UI customizations
Themes
122. Developer Training
• a point in UI template that can be extended dynamically
by any bundle
• a mechanism to customize UI without modifying Twig
templates
• comparable with “hooks” or “events” but in context of
layout rendering
UI customizations
Placeholders
123. Developer Training
• configuration in Resources/config/placeholders.yml
• items are subscribed to placeholders in configuration
• item options:
• template
• action
• data
• applicable
• acl
• order
• item configuration can contain expressions, they will be
resolved in a runtime
UI customizations / Placeholders
Placeholders Configuration
124. Developer Training
• Twig token or Twig function
{% placeholder <placeholder_name> %}
• parameters can be passed
{% placeholder <placeholder_name> with {'form' : form} %}
• items will be ordered and rendered and this content will be
outputted in place where placeholder that was specified in
Twig template
• parameters will be available in items as Twig template
variables
UI customizations / Placeholders
Placeholder in Twig Template
132. Developer Training
AMD and RequireJS
• Asynchronous module definition (AMD):
• define, require
• RequireJS config generation:
• shim, map, paths
• RequireJS build configuration
• Customization of RequireJS config in runtime
JavaScript
133. Developer Training
Client Side Architecture
• built over Chaplin (architecture based on the Backbone.
js)
• models, views, routes, controllers, modules
• application initialization
• application config
JavaScript
134. Developer Training
MVC and Backbone
backbone models, views and controllers
- srcOroBundleSidebarBundleResourcespublicjsmodel.js
- srcOroBundleSidebarBundleResourcespublicjsview.js
JavaScript
136. Developer Training 136
Overview
- OroNavigationBundle
- based on KnpMenuBundle
- provides navigation menus data
- can be configured in navigation.yml
http://www.orocrm.
com/documentation/index/current/cookbook/how-to-create-and-
customize-application-menu
https://github.
com/orocrm/platform/blob/master/src/Oro/Bundle/NavigationBund
le/README.md
Navigation
138. Developer Training 138
Customizing Menus
● configured in Resources/config/navigation.yml
● configuration will be collected from all bundles
● override menu items
● change menu structure using merge strategy:
append (default)
Node will be appended. If same node already present in tree it will be
not changed.
replace
All nodes with same name will be removed and replaced in tree with
current node definition
move
All nodes with same name will be removed and replaced in tree. Node
children will be merged with found node children.
Navigation
139. Developer Training 139
Navigation Titles
- manage page titles
- support of annotations in controller actions
- support of configuration files using route names
- configuration can be used to override title
annotations
- to apply titles changes execute command oro:
navigation:init
Navigation
141. Developer Training 141
Localization
- Numbers, dates and time formating (intl and
icu libs)
- Name and postal address formating
- Dictionaries for currencies, phone prefixes and
default locales
- Locale settings: locale, language, location,
timezone, currency
- PHP and JS tools
Localization
142. Developer Training 142
Localization
● System Configuration → Localization
● PHP: OroBundleLocaleBundleModelLocaleSettings (oro_locale.settings)
● locale
● language
● location
● calendar
● time zone
● list of person names formats
● list of addresses formats
● currency specific data
● currency symbols based on currency codes
● currency code, phone prefix, default locale based on country
● JS: module orolocale/js/locale-settings
Localization
146. Developer Training 146
Date and DateTime: Formatting
● based on PHP intl extension on backend and Moment.js on frontend
● PHP: OroBundleLocaleBundleFormatterDateTimeFormatter (oro_locale.
formatter.date_time)
● Uses IntlDateFormatter
● Twig filter: oro_format_date, oro_format_time, oro_format_datetime
● Twig functions: oro_locale_number_attribute,
oro_locale_number_text_attribute, oro_locale_number_symbol
● JS: module orolocale/js/formatter/datetime
● functions in JS module
Localization
147. Developer Training 147
Dumping Localization
oro:localization:dump
● executed during install/update
● localization information from *.yml files dumped to web/js/oro.locale_data.
js (module name oro_locale)
● these data can be used in JS to implement localization on frontend
Localization
160. Developer Training
Serializer
Serializer is responsible for converting entities to plain/array representation
(serialization) and vice-versa (deserialization)
• export
OroBundleImportExportBundleSerializerNormalizerNormalizerInte
rface
• import
OroBundleImportExportBundleSerializerNormalizerDenormalizerIn
terface
• registered by oro_importexport.normalizer tag
• extends OroBundleImportExportBundleSerializerNormalizer
ConfigurableEntityNormalizer
Import & Export
161. Developer Training
Data Converter
Data converter is responsible for converting header of import/export file
• basically a map of entity fields: file → entity
• extend
OroBundleImportExportBundleConverterAbstractTableDataConverter
Import & Export
162. Developer Training
Export Processor
Knows how to process exported entity using defined data converter and
serializer
• extends OroBundleImportExportBundleProcessorExportProcessor
• should be defined in DI container for every exported entity
• data converter and serializer can be injected into processor by
respective setter methods
• Controller action OroImportExportBundle:ImportExport:instantExport
(route oro_importexport_export_instant).
Import & Export
163. Developer Training
Import Strategy
Strategy defines the main logic how the entities are being processed. For
example import could add new records or it can update only existed ones.
• extends
OroBundleImportExportBundleStrategyImportAbstractImportStrategy
• for configurable entities: ConfigurableAddOrReplaceStrategy
Import & Export
164. Developer Training
Fixture Services
Fixtures implementation based on default import/export process
• extends
OroBundleImportExportBundleTemplateFixtureTemplateFixtureInterface
• registered by the oro_importexport.template_fixture tag
• define data converter
• define export processor
Import & Export
165. Developer Training
Import Processor
Knows how to process imported entity using defined data converter, serializer
and strategy
• extends OroBundleImportExportBundleProcessorImportProcessor
• should be defined in DI container for every imported entity
• strategy, data converter and serializer can be injected into
processor by respective setter methods
• import validation processor tag
Import & Export
166. Developer Training
Adding Import/Export to Grid
• Add buttons to the index.html.twig
• Add @ConfigField annotations
• importexport.yml
• Create a Fixture for import template
Import & Export
170. Developer Training
Overview
OroIntegrationBundle:
- responsible for interaction between third party services and the platform
- provides necessary abstractions for integrations allowing developers to
create integration bundles
- provides basic UI for integration configuration
- extends OroImportExportBundle to process data in the background using
cron and process queue.
Integrations
171. Developer Training
Integration Foundation
• Integration Channel Type
Grouping of source specific logic that focuses on a specific application or
service. For example: Magento channel type, eBay channel type etc.
• Integration Channel
A configured instance of a specific channel type that allows connection to a
specific end point, for example specific Magento store or eBay account.
• Transport
An implementation of connection to a third party application that allows
work with channel data. For example: SOAP transport, REST transport,
direct database connection and much more.
• Connector
Connector knows how to retrieve data of a specific type from remote
instance, using any type of compatible transport for the determined
channel. For example: Customer connector, Cart connector.
Integrations
172. Developer Training 172
New Integration Channel Type
- implement OroBundleIntegrationBundleProviderChannelInterface
- register in the DI with oro_integration.channel tag using
unique type
- optionally implement
OroBundleIntegrationBundleProviderIconAwareIntegrationInterface
Channels
173. Developer Training
Integration Entities
• Use IntegrationEntityTrait
• Configurable entity (@Config annotation)
• RemoteId - configurable field (@ConfigField annotation)
Integrations
174. Developer Training
Transport
Responsibility of transport is communication between connector and channel
• Create entity that will store transport settings
- extend OroBundleIntegrationBundleEntityTransport
• Create form to display on channel configuration page
• Implement transport type
- implement OroBundleIntegrationBundleProviderTransportInterface
- register in DI container by oro_integration.transport tag:
acme.demo_integration.provider.db_transport:
class: %acme.demo_integration.provider.db_transport.class%
tags:
- { name: oro_integration.transport, type: db, channel_type: some_channel}
Integrations
175. Developer Training
Connectors
Responsibility of connector is retrieving data of specific type from a remote
instance
• Create connector class
- implement OroBundleIntegrationBundleProviderConnectorInterface
- register in DI container by oro_integration.connector tag:
orocrm_partner.provider.github_issue_connector:
class: %orocrm_partner.provider.issue_connector.class%
tags:
- { name: oro_integration.connector, type: github_issue, channel_type: github }
• Selecting connectors on the UI
Integrations
176. Developer Training
Utilizing Import/Export Features
For processing imported records the core components of
OroImportExportBundle are utilized:
• Data Converter
• Serializer
- need to check for the channel type or entity class in
supportsNormalization() and supportsDenormalization() methods
• Strategy
- inject logger to show integration process
- populate default owner via
OroBundleIntegrationBundleImportExportHelperDefaultOwnerHelper
• Import Processor
Integrations
178. Developer Training
Reverse Sync
For integration that requires synchronization in both sides there is possibility to
declare export process on connector level:
• Converter should implement
OroBundleIntegrationBundleProviderTwoWaySyncConnectorInterface
• Export job defined in batch_jobs.yml
• Reader: add condition for records required for sync
• Writer: push changes to third party system
• Run: oro:integration:reverse:sync OR use automated processes
https://github.
com/laboro/platform/blob/master/src/Oro/Bundle/IntegrationBundle/Resource
s/doc/reference/reverse-sync.md
Integrations
179. Developer Training
Common challenges
• Pass data between jobs/connectors
• Connectors depend on each other
• Performance
- increase read batch size
- make sure only new records are being pulled
- use processes to create related entities
Integrations
181. Developer Training
Overview
• provide possibility to automate tasks related to entity
management
• use doctrine entity life-cycle events
• process can be performed immediately or after some
timeout
• use JMS Job bundle to provide possibility of delayed
execution
Processes
182. Developer Training
How it works
• each of process related to the some entity type
• each definition can have several triggers.
• user do some action with entity and all appropriate
triggers will run process
• if process is delayed a job will be scheduled to run
process
• after the specific entity item is deleted all job processes
related to this entity also will be deleted
Processes
184. Developer Training
Definition
• persisted via Doctrine OroWorkflowBundle:Process entity in
oro_process table
• can be specified in in Resources/config/process.yml
• contains:
• related entity type, e.g. user
• actions to perform, e.g. change value of some field
• execution order, used for immediate (not delayed) processes
subscribed on the same event
• enable flag
• label
• creation date
• updated date
Processes
185. Developer Training
Trigger
• persisted via Doctrine OroWorkflowBundle:ProcessTrigger
entity in oro_process_trigger table
• used to trigger process when specified event is fired
• supported events: create, update, delete
• entity field name can be specified for update event
• execution can be delayed or immediate
• if execution is delayed priority can be specified for
process jobs
Processes
186. Developer Training
Job
• persisted via Doctrine OroWorkflowBundle:ProcessJob entity in
oro_process_job table
• use for delayed processing
• contain data required to run process
• according to event job can contain following data:
• create event – entity identity;
• update event – entity identity and change set (old and new values);
• delete event – entity plain fields (without references).
• contains relation to the trigger used to create this job and entity hash (full
class name of the related entity plus identity of the specific entity). This
entity hash is required to find all registered jobs
• for the same specific entity (e.g. to remove all related jobs).
Processes
187. Developer Training
Commands
oro:process:configuration:load
• loads processes configuration from *.yml configuration
files to the database
• used during application installation and update
oro:process:execute:job
• executes process job with specified identifier
• used in the JMS jobs to execute delayed processes
Processes
193. Developer Training
Overview
• solution that allows user to perform set of actions with predefined
conditions for specific entity
• a kind of wizard that helps user to implement some business logic
• set of ordered actions that can be performed with the specific entity
• helps to manage entities, update existing ones and create new
• from user POV – set of buttons which may open forms that allow to
manipulate entity data
Workflow
194. Developer Training
Relation With Entity
• workflow has one related entity class
• entity class may have unlimited number of workflows
related to it
• entity class may have only one active workflow
• entity record at any given moment in time can be
subject to only one workflow. It is possible however to
have several workflows for one entity and switch
between them
• when a workflow is deleted, all its existing relations to
entities and entity records are lost
Workflow
195. Developer Training
B2B Sales Flow Visualization
Workflow
Qualify Develop Close
Develop
Close As Won
Close As Lost
Requalify Lost
Requalify Won
196. Developer Training
Configuration File
• Resources/config/workflow.yml
• configuration file may be split by parts
• all included parts must be placed under imports section.
• imports may be used in any part of workflow
configuration
• configuration cannot be merged
Workflow
198. Developer Training
Workflow Definition
• can be specified in Resources/config/workflow.yml
• persisted via Doctrine’s entity OroWorkflowBundle:
Workflow in table oro_workflow
• to push changes of definitions in configuration run
command oro:workflow:load
Workflow
199. Developer Training
Workflow Item
• it's a record of specific workflow
• represented by OroWorkflowBundle:WorkflowItem entity
• linked with workflow definition
• linked with specific record of related entity
• contains reference to current step
• contains values of workflow attributes if such exist
Workflow
200. Developer Training
Attributes
• workflow can manipulate it's own data (Workflow Data)
that is mapped by Attributes
• each attribute must have a type and may have options
• when Workflow Item is saved its data is serialized
according to configuration of attributes
• saving data that is not mapped by any attribute or
mismatched with attribute type is restricted
• attribute configuration does not contain any information
about how to render attribute on step forms
Workflow
201. Developer Training
Attributes Configuration
• unique name – Workflow attributes should have unique name in scope of Workflow
that they belong to. Step configuration references attributes by this value.
• type – Type of attribute
• label – Label can be shown in the UI
• entity_acl – Defines an ACL for the specific entity stored in this attribute.
• update – Can entity be updated. Default value is true.
• delete – Can entity be deleted. Default value is true.
• property_path – Used to work with attribute value by reference and specifies path
to data storage. If property path is specified then all other attribute properties except
name are optional - they can be automatically guessed based on last element (field)
of property path.
• options – Options of an attribute. Currently next options are supported
• class string Fully qualified class name. Allowed only when type either entity or
object.
Workflow
202. Developer Training
Step
• workflow must contain at least one step
• at any given moment in time workflow entity must be in
some step
• workflow step can be used as default step
• steps are shown in the small widget on the workflow
entity view page
• must have at least one transition, either incoming, or
outgoing
Workflow
203. Developer Training
Step Configuration
• name – Step must have unique name in scope of Workflow
• label – Label of step, can be shown in UI if Workflow has type wizard
• order – This value is used in wizard page to sort steps in UI.
• is_final boolean If true than step will be counted as workflow final step.
• entity_acl – Defines an ACL for the workflow related entity when workflow
is in this step.
• update – Can entity be updated. Default value is true.
• delete – Can entity be deleted. Default value is true.
• allowed_transitions – Optional list of allowed transitions. If no transitions
are allowed it's same as is_final option set to true
Workflow
204. Developer Training
Transition
• connects workflow's steps
• steps and transitions form a directed graph, where steps
are nodes and transitions are edges
• may point to the same step (self-transition)
• may have ACL resource
• may perform post actions
• may have conditions and pre-conditions to restrict or
allow performing transition
• transitions appear as buttons on the view of workfow
entity
Workflow
205. Developer Training
Starting Transition
• special case of transition
• don't have starting step
• workflow must have either a default step, or a starting
transition
Workflow
206. Developer Training
Transition Form
• based on registered Symfony's form types
• shown to the user after he clicks the transition button
• form displays workflow attributes
• attributes could be mapped to entity properties or they could be not
mapped
• forms are optional, and transition may have no form attached
• form appears in the popup windows
• form may appear in a separate page
Workflow
207. Developer Training
Transition Configuration
Workflow
• unique name – A transition must have unique name in scope of Workflow
• step_to – Next step name
• transition_definition – A references to Transition Definition configuration
• is_start – If true than this transition can be used to start new workflow
• is_hidden – Indicates that this transition must be hidden at frontend
• is_unavailable_hidden – transition must be hidden when not allowed
• acl_resource – ACL resource to protect transition execution
• acl_message – permission error message
• message – Notification message will be shown before transition execution.
• display_type – Possible options are: dialog, page. "page" require
"form_options"
• form_type – (oro_workflow_attributes - default) A form type of transition
• frontend_options – Can have such frontend options as class, icon
• form_options – options for form types of attributes
• transition_definition – Name of associated transition definition
208. Developer Training
Transition Definition
Workflow
• used by Transition to check Conditions and to perform Init Action
and Post Actions
• Transition definition configuration:
• conditions & pre_conditions – Configuration of Conditions
and Pre Condition that must satisfy to allow transition
• post_actions – Configuration of Post Actions that must be
performed after transit to next step will be performed
• init_actions – Configuration of Init Actions that may be
performed on workflow item before conditions and post actions
209. Developer Training
Conditions & Pre Conditions
• Conditions checked when the transition form is committed, if they are not
met the transition won’t be conducted
• Pre Conditions are checked first, and affect availability of Transition
button UI
• Pre Conditions are required becuase some transtion may use forms, and
entered forms data could be used in Conditions
• not yet available on the UI and can be accessed only via configuration files
• conditions tree
• to add custom condition implement
OroBundleWorkflowBundleModelConditionConditionInterface and
register service with tag oro_workflow.condition and attribute alias
• conditions configuration
Workflow
210. Developer Training
Post Actions & Init Actions
• executed after the transaction is conducted (i.e. the transition form is
submitted, preconditions and conditions are met, the workflow is moved to
the destination step)
• may include creation of another entity, manipulation of the existing entity
data and available workflow attributes, email notifications, etc.
• if a post action creates a new record of an entity that has an active
workflow with default step, it will be started automatically
• Init Actions performed before transition. Possible use case is to set
default values, which will be used by Transition form.
• not yet available on the UI and can be accessed only via configuration files
• to add custom post action implement
OroBundleWorkflowBundleModelActionActionInterface and register
service with tag “oro_workflow.action” and attribute “alias”
• actions configuration
Workflow
216. Developer Training
Enable RFM for an Entity
Configure entity in the channel:
• implement RFMAwareInterface interface
• implement RFMAwareTrait trait
Metric providers:
• define providers for each metric of the entity to be
collected and implement RFMProviderInterface for each
provider
• add the providers to the DI container with
orocrm_analytics.builder.rfm tag
Run the calculation command for the channel
Analytics
218. Developer Training 218
Test Suites
- Unit tests
- Functional (Integration) tests
- Selenium Tests
- JavaScript Tests
- Code Standards Tests (Sanity Tests)
219. Developer Training 219
Unit Tests
Installation
To run unit tests you should have PHPUnit 3.7+ installed.
Running
$ phpunit -c app src/Acme/DemoBundle/Tests/Utility/
$ phpunit -c app --testsuite="Unit Tests"
220. Developer Training 220
Functional Tests
OroCRM takes advantage of Symfony2 functional test framework.
Each test is a PHP class that should be placed in the Tests/Functional
subdirectory of your bundle.
Functional tests workflow:
• Make a request
• Test the response
• Click on a link or submit a form
• Test the response
221. Developer Training 221
Working with Functional Tests
Installation
To run functional tests you should have PHPUnit 3.7+ installed.
Configuration
- appconfigparameters_test.yml
- appconfigconfig_test.yml
Preparing
app/console oro:test:schema:update --env test
app/console doctrine:fixture:load --no-debug --append --no-interaction --
env=test --fixtures src/Oro/src/Oro/Bundle/TestFrameworkBundle/Fixtures
Running
$ phpunit -c app --testsuite "Project OroCRM Functional
Tests" --verbose --stderr
222. Developer Training 222
Selenium Tests
Installation
Selenium tests requires:
• PHPUnit 3.7+
• PHPUnit Selenium 1.3.2+
• PhantomJS 1.9+ or Selenium Server 2.37+
Configuration
Main config options you can find in appphpunit.xml.dist
223. Developer Training 223
Working with Selenium Tests
Running
$ phpunit -c app --testsuite "Project Selenium Tests" --
verbose
Writing
- Test example
- Page class example
- Base page classes:
- AbstractPageGrid
- AbstractPageFilteredGrid
- AbstractPageEntity
224. Developer Training 224
JavaScript Tests
Installation
To run JS tests the following software is required:
• Node.js (JavaScript Engine)
• Karma (Test Runner for JavaScript)
• Jasmine (Behavior-Driven Development Testing Framework)
225. Developer Training 225
Working with JavaScript Tests
Configuration
Configuration for tests-run is placed in app/karma.config.js.dist
Running
karma start app/karma.conf.js.dist --single-run
Writing
- regular test example
- karma-requirejs-exposure plugin in action
226. Developer Training 226
Code Standards (Sanity) Tests
Installation
To check code standards in Oro you’ll need:
• PHP Code Sniffer
• PHP Mess Detector
For ease, we recommend to use xml reports.
227. Developer Training 227
Running Sanity Tests
Configuration
PHP Code Sniffer and PHP Mess Detector configuration can be provided in
ruleset.xml files.
Running
$ phpcs --encoding=utf-8 --extensions=php --
report=checkstyle --standard=rulesetCS.xml --report-
file=app/logs/checkstyle.xml ./src
$ phpmd ./src xml rulesetMD.xml --reportfile app/logs/pmd.
xml --exclude ../src/Acme
230. Developer Training
Segments
Representation of some dataset based on entity and set of filters
Types of segments:
• Static ("On demand")
• Dynamic
Implementation:
• Extends OroBundleQueryDesignerBundleModelAbstractQueryDesigner
• Segment snapshot
• Query builder
• Datagrid
https://github.
com/laboro/platform/tree/master/src/Oro/Bundle/SegmentBundle
Marketing
231. Developer Training
Marketing Lists
• Uses wizard similar to Custom Reports
• Requires at least on contact information field
• Can be used to:
• run Email Campaigns in OroCRM
• synchronize with Subscribers Lists in MailChimp
• synchronize with Address Books in DotMailer
• Abandoned Cart Campaign
• conversion tool
Marketing