oro/crm-call-bundle
Adds Call activity tracking to Oro applications: provides the Call entity plus UI to log, view, and manage call records for any entity with the activity enabled. Includes related docs on entities, form type, and validators.
Installation:
composer require oro/crm-call-bundle
Ensure the bundle is enabled in config/bundles.php:
Oro\Bundle\CallBundle\OroCallBundle::class => ['all' => true],
Enable Calls for Entities:
Use the oro_activity.entity configuration to enable calls for specific entities (e.g., Customer or Lead):
# config/packages/oro_activity.yaml
oro_activity:
entity:
Oro\Bundle\CustomerBundle\Entity\Customer:
activities:
- call
First Use Case:
Customer) in the UI, navigate to the "Activities" tab, and click "Add Call".
Fill in the call details (duration, notes, etc.) and save.Key Files to Review:
Resources/doc/reference/entities.md (Call entity structure).Resources/doc/reference/form_type.md (Form customization).oro_activity.yaml to include your entity:
oro_activity:
entity:
App\Entity\CustomEntity:
activities:
- call
// src/Form/Type/CallTypeExtension.php
namespace App\Form\Type;
use Oro\Bundle\CallBundle\Form\Type\CallType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
class CallTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('custom_field', TextType::class);
}
public static function getExtendedType()
{
return CallType::class;
}
}
Register the extension in services.yaml:
services:
App\Form\Type\CallTypeExtension:
tags:
- { name: form.type_extension, extended_type: Oro\Bundle\CallBundle\Form\Type\CallType }
Use the CallManager service to create calls programmatically:
use Oro\Bundle\CallBundle\Entity\Call;
use Oro\Bundle\CallBundle\Manager\CallManager;
class MyService
{
private $callManager;
public function __construct(CallManager $callManager)
{
$this->callManager = $callManager;
}
public function logCall($entity, $duration, $notes)
{
$call = new Call();
$call->setDuration($duration);
$call->setNotes($notes);
$call->setEntity($entity);
return $this->callManager->save($call);
}
}
Extend the call datagrid to add custom columns or filters:
# config/packages/oro_call.yaml
oro_datagrid:
grids:
oro_call-call:
columns:
custom_field:
label: Custom Field
type: twig
template: OroCallBundle:CallGrid:custom_field.html.twig
filters:
custom_field:
type: string
data_name: customField
Trigger actions on call creation/update:
use Oro\Bundle\CallBundle\Entity\Call;
use Oro\Bundle\CallBundle\Event\CallEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CallSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
CallEvents::POST_SAVE => 'onCallSave',
];
}
public function onCallSave(CallEvent $event)
{
$call = $event->getCall();
// Custom logic (e.g., send notification)
}
}
Enable the call API endpoint in config/packages/oro_api.yaml:
oro_api:
rest:
call:
enabled: true
action:
create: true
update: true
get: true
Dependency Injection:
Use CallManager, CallRepository, or CallQueryBuilder directly in services/controllers.
Example:
public function __construct(
private CallManager $callManager,
private CallRepository $callRepository
) {}
Twig Extensions:
Access call-related data in templates via oro_call.twig.call_extension (if not private in your version).
Example:
{{ oro_call.get_call_duration(call) }} minutes
Validation:
Customize call validation by extending the Call entity or using constraints:
use Symfony\Component\Validator\Constraints as Assert;
class CallExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('duration', IntegerType::class, [
'constraints' => [
new Assert\GreaterThanOrEqual(1),
],
]);
}
}
Localization:
Translate call-related labels/placeholders via translator service:
$this->translator->trans('oro.call.form.label.duration');
Entity Configuration:
oro_activity.yaml will hide the "Add Call" button.activities: [call] is set for your entity.Service Privacy:
oro_call.twig.call_extension is marked as private. Use alternative methods (e.g., custom Twig functions) if needed.DI Parameter Changes:
*.class parameters (e.g., oro_call.call.entity.class).Call::class).Form Overrides:
CallType may break if the parent class changes in minor updates.prepend or append methods instead of full overrides where possible.API Permissions:
oro_api.yaml is configured.oro_call to oro_api.rest as shown in the workflows.Database Migrations:
php bin/console doctrine:migrations:diff and doctrine:migrations:migrate.Event Dispatching:
CallEvents::POST_SAVE may not fire if the call is not persisted properly.CallManager::save() instead of direct entity persistence.Check Entity Activities: Run this SQL to verify enabled activities for an entity:
SELECT * FROM oro_activity_entity WHERE entity_class = 'App\Entity\Customer';
Datagrid Issues:
Clear cache and check for typos in oro_datagrid configuration:
php bin/console cache:clear
Form Validation Errors: Enable debug mode and check the browser console for validation messages. Common issues:
duration).Event Subscriber Not Triggering:
Verify the subscriber is registered in services.yaml and the event name matches (e.g., CallEvents::POST_SAVE).
API Endpoint Not Found:
Ensure the route is enabled in oro_api.yaml and the bundle is compiled:
php bin/console debug:router | grep call
Custom Call Fields:
Add fields to the Call entity via Doctrine extensions or custom tables:
// src/Entity/CallExtension.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class CallExtension
{
#[ORM\Column(type: 'string', nullable: true)]
private $customField;
}
Update the form and datagrid to include the new field.
How can I help you explore Laravel packages today?