Another Mautic Guide
Another Mautic Guide
Another Mautic Guide
https://developer.mautic.org/#plugin-directory-structure 1/222
17/12/2017 Mautic Developer Documentation
Introduction
Welcome to the Mautic Developer Documentation. This documentation will go over how to build a Mautic Plugin that extends the features of
Mautic, how to build custom themes, and and how to integrate applications outside of Mautic using its REST API.
Symfony
Mautic is built on Symfony, the popular PHP framework (Mautic 1.0.x uses Symfony 2.5; Mautic 2.0.x uses Symfony 2.8). This document
will go over the basics but most of their documentation applies to Mautic as well which can be used to obtain more advanced Symfony
functionality.
There are some structural differences between Mautic and standard Symfony. Below is a list of where you will nd some of standard
Symfony locations in Mautic:
Symfony Mautic
web/ /
AcmeBundle/Resources/cong AcmeBundle/Cong
AcmeBundle/Resources/views AcmeBundle/Views
AcmeBundle/Resources/public AcmeBundle/Assets
AcmeBundle/Resources/translations/domain.en_US.ini AcmeBundle/Translations/en_US/domain.ini
Most of Symfonys standard locations, such as the Resources/views and Resources/translations directories, should still function with
Mautic. However, it may be required to handle service registration, etc with native Symfony processes if not using the Mautic methods
dened in this document.
Development Environment
SETUP
It is assumed that the system already has composer and git installed and congured.
https://developer.mautic.org/#plugin-directory-structure 2/222
17/12/2017 Mautic Developer Documentation
To setup the developer environment, simply fork and clone the source from GitHub. Then Run composer install on the source.
Open your browser and complete the installation through the Mautic installer.
ENVIRONMENTS
dev is used when accessing the site through index_dev.php. Using Mautic in the dev environment will activate Symfonys proler toolbar,
has more strict error handling, will display information about exceptions, and will not cache as much (see below). Note that steps should be
taken to ensure index_dev.php is not accessible to the public as it could potentially reveal sensitive information. It is restricted to localhost
by default. However, there are two ways to allow access to index_dev.php from a non-localhost. The rst option is to set a header from the
web-server with the IP addresses assigned to MAUTIC_DEV_HOSTS . The second and easier option is to add an array to your installations
app/config/local.php le as 'dev_hosts' = ['123.123.123.123', '124.124.124.124'], then clear the cache.
CACHE
Symfony makes heavy use of a lesystem cache. Frequently clearing this cache will be required when developing for Mautic. By default, the
cache is located in app/cache/ENV where ENV is the environment currently accessed (i.e. dev or prod). To rebuild the cache, the ENV can
just be deleted or run the Symfony command php app/console cache:clear --env=ENV If a specic environment is not passed to the
command via --env=ENV , the dev environment will be used by default.
In the dev environment, translations, views, and assets are not cached. However, changes to these les will require the cache to be cleared
for them to take effect in the prod environment. Changes to Mautic cong les, Symfony cong les, etc will require the cache to be cleared
regardless of environment.
The typical rule of thumb is, if Mautic is not acting as you expect after making changes, try clearing your cache.
If you get class could not be found or cannot redeclare class errors when using the cache:clear command, manually delete the
app/cache/ENV folder then run the command and/or browse to the site to rebuild.
Plugins
Plugins are bundles that can extend the functionality of Mautic. They can be very simple or very complex and have access to leverage
pretty much all that Symfony offers. Just as as reminder, the basics are covered in this document. If more advanced processes are
required, the Symfony book and cookbook will be valuable resources.
Mautic plugins are located in the plugins/ directory and must be namespaced with MauticPlugin.
Migrations/Deprecations
The following is a list of deprecations and migrations required to support latest versions of Mautic.____
https://developer.mautic.org/#plugin-directory-structure 3/222
17/12/2017 Mautic Developer Documentation
1.2.0
1.2.0 deprecated the Mautic Addon with its successor, the Plugin. Mautic addons will continue to work but should be migrated to a plugin
before Mautic 2.0 when support will be dropped.
2.0.0
The big ticket item with 2.0.0 is the deprecation of MauticFactory which will be phased out during the 2.x release cycles and to be removed
in 3.0. Where possible, please use direct dependency injection of services rather than relying on MauticFactory.
1. MauticFactory deprecated - use dependency injection of required services. Many MauticFactory helper functions have been
replaced with services.
2. Models need to be registered as services using a specic nomenclature. See Models for more information.
3. The static callback function for campaign actions and decisions has been deprecated. Please see Extending Campaigns for more
information on the new event based method. (Form submit actions, point triggers, and the like will follow suit with a similar migration
throughout the lifecycle of 2.0 but for now still uses the static callback method).
4. Minimum PHP version has been increased to 5.6.19 and thus newer PHP code goodies are available for developers (traits, etc)
5. Themes have been completely revamped although the old format is still supported for now. Please see Themes for the new format.
6. Some routes for /leads/* were removed in favor of /contacts/*. I.e. /api/leads is now /api/contacts, /s/leads is now /s/contacts, and so
forth. The route names were also updated. For example, mautic_lead_action is now mautic_contact_action and so forth.
<?php
// plugins/HelloWorldBundle/HelloWorldBundle.php
namespace MauticPlugin\HelloWorldBundle;
use Mautic\PluginBundle\Bundle\PluginBundleBase;
The directory structure of an plugin will vary based on the features implemented.
HelloWorldBundle/
- - - Cong/
- - - - - cong.php
- - - HelloWorldBundle.php
The HelloWorldBundle.php le registers the bundle with Symfony. See the code block for the minimum required code.
https://developer.mautic.org/#plugin-directory-structure 4/222
17/12/2017 Mautic Developer Documentation
A typical MVC plugin may look something like:
HelloWorldBundle/
- - - Assets/
- - - - - - images/
- - - - - - - - - earth.png
- - - - - - - - - mars.png
- - - - - - helloworld.js
- - - - - - helloworld.css
- - - Cong/
- - - - - - cong.php
- - - Controller/
- - - - - - DefaultController.php
- - - Model/
- - - - - - ContactModel.php
- - - - - - WorldModel.php
- - - Translations//
- - - - - - en_US/
- - - - - - - - - ashes.ini
- - - - - - - - - messages.ini
- - - Views/
- - - - - - Contact/
- - - - - - - - - form.html.php
- - - - - - World/
- - - - - - - - - index.html.php
- - - - - - - - - list.html.php
- - - HelloWorldBundle.php
- - - HelloWorldEvents.php
Each of the other directories and les are explained elsewhere in the document.
Install/Upgrade
<?php
// plugins/HelloWorldBundle/HelloWorldBundle.php
namespace MauticPlugin\HelloWorldBundle;
use Doctrine\DBAL\Schema\Schema;
use Mautic\PluginBundle\Bundle\PluginBundleBase;
use Mautic\PluginBundle\Entity\Plugin;
use Mautic\CoreBundle\Factory\MauticFactory;
/**
* Called by PluginController::reloadAction when adding a new plugin that's not already installed
*
* @param Plugin $plugin
* @param MauticFactory $factory
* @param null $metadata
*/
https://developer.mautic.org/#plugin-directory-structure 5/222
17/12/2017 Mautic Developer Documentation
if ($metadata !== null) {
self::installPluginSchema($metadata, $factory);
}
/**
* Called by PluginController::reloadAction when the plugin version does not match what's installed
*
* @param Plugin $plugin
* @param MauticFactory $factory
* @param null $metadata
* @param Schema $installedSchema
*
* @throws \Exception
*/
static public function onPluginUpdate(Plugin $plugin, MauticFactory $factory, $metadata = null, Schema $installedSchema = null)
{
$db = $factory->getDatabase();
$platform = $db->getDatabasePlatform()->getName();
$queries = array();
$fromVersion = $plugin->getVersion();
// Simple example
switch ($fromVersion) {
case '1.0':
switch ($platform) {
case 'mysql':
$queries[] = 'ALTER TABLE ' . MAUTIC_TABLE_PREFIX . 'worlds CHANGE CHANGE description description LONGTEXT DEFAULT NULL';
break;
case 'postgresql':
$queries[] = 'ALTER TABLE ' . MAUTIC_TABLE_PREFIX . 'worlds ALTER description ALTER TYPE TEXT';
break;
}
break;
}
if (!empty($queries)) {
$db->beginTransaction();
try {
foreach ($queries as $q) {
$db->query($q);
}
$db->commit();
} catch (\Exception $e) {
$db->rollback();
throw $e;
}
}
}
}
Currently, plugins are installed by uploading the plugin to the plugins folder and the cache manually deleted ( app/cache/prod ). Then, the
admin must click the Install/Upgrade Plugins button in the Plugin manager. When that happens, new plugins found will have the static
method onPluginInstall() called from the plugins bundle le. If the plugin has already been installed, and the version has changed, then
onPluginUpdate() is called.
By default, onPluginInstall() will execute installPluginSchema() . This function will generate and execute schema based on found Entity
classes.
https://developer.mautic.org/#plugin-directory-structure 6/222
17/12/2017 Mautic Developer Documentation
updatePluginSchema() is available for use with onPluginUpdate() , however it is not called by default. The reason is that it uses Doctrine to
generate schema differences and executes the queries. This is not recommended due to the risk of Doctrine making incorrect assumptions
that will lead to data loss. If updatePluginSchema() is relied upon, it is very important to test thoroughly to ensure the desired outcome. It is
recommended to write a migration path for both MySQL and PostgreSQL with native queries instead.
ONPLUGININSTALL()
Executed when a plugin is rst installed. By default, the plugins database schema will be generated and installed based on the Entity class
loadMetadata function.
$plugin Mautic\PluginBundle\Entity\Plugin The plugin entity with information gleaned from the plugins cong le.
INSTALLPLUGINSCHEMA()
ONPLUGINUPDATE()
$plugin Mautic\PluginBundle\Entity\Plugin The plugin entity with information gleaned from the plugins cong le.
UPDATEPLUGINSCHEMA()
GENERAL
<?php
// plugins/HelloWorldBundle/Config/config.php
return array(
https://developer.mautic.org/#plugin-directory-structure 7/222
17/12/2017 Mautic Developer Documentation
'name' => 'Hello World',
'description' => 'This is an example config file for a simple Hellow World plugin.',
'author' => 'Marty Mautibot',
'version' => '1.0.0',
The general cong options will dene what should be listed in the Plugin manager.
The version should be PHP-standardized as the Plugin manager will use version_compare() to determine if the onUpdate callback should
be executed.
ROUTES
If copying, do not copy <?php //continued as it is simply used to force sytax highlighting.
<?php // continued
Routes dene the URL paths that will be used to execute the plugins controller actions. See Routing for specics on how routes work.
FIREWALLS
Firewall Description
main Secure area of Mautic (/s/ will be auto prepended to the path). The user will be required to login to access this path.
https://developer.mautic.org/#plugin-directory-structure 8/222
17/12/2017 Mautic Developer Documentation
Firewall Description
public Public access without needing authentication. The URL will be appended directly to Mautics base URL.
api Secure API area of Mautic (/api/ will be auto prepended to the path). OAuth authorization will be required to access the path.
Each rewall accepts an array of dened routes. Each key, the routes name, must be unique across all bundles and rewalls. Paths must
be unique across the same rewall. Order does matter as the rst matching route will be used.
ROUTE DEFINITIONS
Denes the path for the URL. Placeholders can be dened using curly brackets. Parameters
path REQUIRED string
are passed into the controller function as arguments.
Denes the controller and function to call when the path is accessed. This should be in
controller REQUIRED string Symfonys controller notation of BundleName:ControllerClass:controllerMethod. See
Controllers for more information.
method OPTIONAL string Restricts the route to a specic method, i.e. GET, POST, etc
Denes default values for path placeholders. If a default is dened, it is not required in the
defaults OPTIONAL array URL. In the code example, /hello will be the same as /hello/earth and the controllers $world
argument will default to earth as well.
Denes regex matches placeholders must match in order for the route to be recognized. For
requirements OPTIONAL array example, for plugin_helloworld_world in the code example, world is restricted to earth or mars.
Anything else will not be recognized by the route.
Sets the request format for the Request response, i.e. Content-Type header. The api rewall
format OPTIONAL string
will automatically set this to json.
condition OPTIONAL string Very exible expression to set when the route should match. Refer to Symfony docs.
Note that there are some internally used placeholders that Mautic will set defaults and requirements for (if not overridden by the route)
Each routes name must be unique across all bundles and rewalls and paths must be unique with the same rewall.
Order does matter. The rst route the path matches will be used.
Debugging Routes There are a few CLI commands that make help with debugging routes.
https://developer.mautic.org/#plugin-directory-structure 9/222
17/12/2017 Mautic Developer Documentation
MENU
<?php // continued
MENU TYPES
admin Admin menu accessible through the cogwheel in upper right hand side of Mautic
prole Prole menu accessible through clicking the username in upper right hand side of Mautic
extra Displays to the right of the Mautic logo in the upper left hand. Only shows if there are menu items injected.
PRIORITY
To control the placement of the menu item set, set an array with 'priority and 'items keys. Priority can be negative to position the items
lower than others or positive to position them higher. If the menu items are returned without setting priority, like the admin menu in the code
example, priority is treated as 9999.
To control the priority of individual menu items, set priority its denition array.
PARENT
https://developer.mautic.org/#plugin-directory-structure 10/222
17/12/2017 Mautic Developer Documentation
To place a menu item in another bundles parent menu item, for example Channels or Components, dene the parent key with the key of
the menu item this item should display under. For example, to show an item under the Channels parent menu item, use 'parent' => 'mau
tic.core.channels', .
The menu items name should be the language string key that will be displayed as the items link.
Item denitions:
The route name as dened in routes. Do not set a route to treat the item as a parent to
route OPTIONAL string
activate a submenu.
routeParameters OPTIONAL array Route placeholder values to use when generating the URL
Sets the id of the <a /> attribute. This will default to what is set as route. This is used in
id OPTIONAL string conjuction with returnUrl returned in a controllers response so that the correct menu item
is highlighted when ajax is used to navigate the interface.
iconClass OPTIONAL string Font Awesome class to set the icon for the menu item.
Set the permission required for this item to display to the user currently logged in. Can also
access OPTIONAL string
set 'admin to restrict to Administrators only.
Restricts display of the link based on either congured parameters or the GET request. It
checks OPTIONAL array will accept a 'parameters and/or 'request array of key => value pairs that must be true to
display the menu item.
parent OPTIONAL string Display this item under another parent menu item.
priority OPTIONAL int Set the priority for ordering this menu item with its siblings.
SERVICES
<?php // continued
https://developer.mautic.org/#plugin-directory-structure 11/222
17/12/2017 Mautic Developer Documentation
)
),
Services are PHP objects stored in the service container and are used all throughout Mautic. They can be as simple or as complex as
required. Read more about Symfonys service container here.
SERVICE TYPES
Type Description
Denes event subscriber classes used to listen to events dispatched throughout Mautic and auto-tagged with
events 'kernel.event_subscriber. The dened class must extend \Mautic\CoreBundle\EventListener\CommonSubscriber. Read more
about subscribers here.
Denes custom template helpers available through the $view variable in views. These services are auto-tagged with
helpers
'templating.helper.
SERVICE DEFINITIONS
Each key within the service types array is the name of the service and must be unique. Use the following to dene the service:
class REQUIRED string Namespace to the service class (not that it does not start with a backslash)
Sets the alias used by the service. For example, the key for the template helpers, $view,
alias OPTIONAL string
array or the string to retrieve a specic form type.
Tags the service used by bundles to get a list of specic services (for example form types
tag OPTIONAL string
and event subscribers).
tagArguments OPTIONAL array Array of attributes for the tag. See Symfony docs for more information.
Preferred method for using a factory class. Factory class for managing creating the
factory OPTIONAL string
service.
factoryService OPTIONAL string Factory class for managing creating the service. Deprecated; use factory instead.
Method name in the factory service called to create the service. Deprecated; use factory
factoryMethod OPTIONAL string
instead.
Array of methods to be called after a service is created passing in the array of arguments
methodCalls OPTIONAL array provided. Should be in the format of 'methodName => array('service_name,
%parameter%)
https://developer.mautic.org/#plugin-directory-structure 12/222
17/12/2017 Mautic Developer Documentation
CATEGORIES
<?php // continued
Denes category types available or the Category manager. See Extending Categories.
PARAMETERS
<?php // continued
The parameters array dene and set default values for custom conguration parameters specic to the plugin.
Any parameter to be written to the systems local cong le should be dened here.
Translations
Mautic uses INI les for translations.
HelloWorldBundle/
- - - Translations/
- - - - - - en_US/
- - - - - - - - - messages.ini
All plugins should include strings for the United States English locale (en_US) as it is the default for the system.
https://developer.mautic.org/#plugin-directory-structure 13/222
17/12/2017 Mautic Developer Documentation
The directory structure for translations should be Translations/locale/domain.ini .
DOMAINS
Language strings can be organized into domains. Each domain should be its own le in the plugins language locale folder(s). The plugin
can use any domain it wants but Mautic makes consistent use of three domains:
Domain Description
messages Default domain for the translator service when no domain is specied
INI FILES
; plugins/HelloWorldBundle/Translations/en_US/messages.ini
plugin.helloworld.contact_us="Contact Us"
plugin.helloworld.goodbye="Goodbye and have a good day!"
plugin.helloworld.greeting="Hello %name%!"
plugin.helloworld.index="Hello World"
plugin.helloworld.manage_worlds="Manage Worlds"
plugin.helloworld.number_of_planets="{0}0 planets|{1}1 planet|]1,Inf[%planets% planets"
plugin.helloworld.world="World"
plugin.helloworld.worlds="%world% Description"
; plugins/HelloWorldBundle/Translations/en_US/flashes.ini
Refer to the translator service to learn how to use translations in the code.
If your bundle implements custom javascript where translations are required, you can get them by the Mautic.translate(key, params)
method.
Create a javascript.ini in the same directory as the messages.ini as described above. Any translation strings added to that le will be
available when translating in javascript.
https://developer.mautic.org/#plugin-directory-structure 14/222
17/12/2017 Mautic Developer Documentation
For example, if your javascript.ini le contained the following translation strings:
mautic.core.dynamicContent="Dynamic Content"
mautic.core.dynamicContent.new="Dynamic Content %number%"
You can request those translation strings in your javascript by passing the key to the Mautic.translate() function.
Mautic.translate("mautic.core.dynamicContent");
// outputs "Dynamic Content"
String interpolation for messages with variables works with js translations just as youd expect.
MVC
Mautic uses a Model-View-Controller structure to manage user interaction on the frontend (views) with the underlying code processes
(controllers and models). (Entity and Repository classes are also used to manage interaction with the database).
In Symfony, and thus Mautic, the controller is the center of the MVC structure. The route requested by the user determines the controller
method to call. The controller will then communicate with the model to get or manipulate data then display it to the user through the view.
CONTROLLERS
<?php
// plugins/HelloWorldBundle/Controller/DefaultController.php
namespace MauticPlugin\HelloWorldBundle\Controller;
use Mautic\CoreBundle\Controller\FormController;
return $this->delegateView(
array(
'viewParameters' => array(
'world' => $world,
'details' => $worldDetails
),
'contentTemplate' => 'HelloWorldBundle:World:details.html.php',
'passthroughVars' => array(
'activeLink' => 'plugin_helloworld_world',
https://developer.mautic.org/#plugin-directory-structure 15/222
17/12/2017 Mautic Developer Documentation
'route' => $this->generateUrl('plugin_helloworld_world', array('world' => $world)),
'mauticContent' => 'helloWorldDetails'
)
)
);
}
/**
* Contact form
*
* @return JsonResponse|\Symfony\Component\HttpFoundation\Response
*/
public function contactAction()
{
// Create the form object
$form = $this->get('form.factory')->create('helloworld_contact');
// isFormValid() will bind the request to the form object and validate the data
if ($valid = $this->isFormValid($form)) {
if ($cancelled || $valid) {
// Redirect to /hello/world
return $this->postActionRedirect(
array(
'returnUrl' => $this->generateUrl('plugin_helloworld_world'),
'contentTemplate' => 'HelloWorldBundle:Default:world',
'flashes' => $flashes
)
);
} // Otherwise show the form again with validation error messages
}
https://developer.mautic.org/#plugin-directory-structure 16/222
17/12/2017 Mautic Developer Documentation
}
}
The controller method called is determined by the route dened in the cong. Take this example,
The controller is noted as HelloWorldBundle:Default:admin . Broken down, that will translate to:
HelloWorldBundle \MauticPlugin\HelloWorldBundle\Controller
Default DefaultController
admin adminAction()
What about route placeholders? Symfony is super smart and will pass those into the controllers method as arguments (the methods
arguments must be the same as the routes placeholders to be matched up).
The matching method for that route will look be public function worldAction($world = 'earth') .
Notice that because the route denes a default for name , the controller method must also set the same default. If the route looked like this
instead:
https://developer.mautic.org/#plugin-directory-structure 17/222
17/12/2017 Mautic Developer Documentation
Mautic has several controllers that provide some helper functions.
MAUTIC\COREBUNDLE\CONTROLLER\COMMONCONTROLLER
Controllers extending this will make MauticFactory available via $this->factory and Request via $this->request .
DELEGATEVIEW($ARGS)
Mautic is ajax driven and thus must support both http requests and ajax requests for content. delegateView is wrapper method that
determines if the request is for ajax content or the full DOM then generates and returns the appropriate response.
The $args argument is an array with the required elements for generating the view, ajax or http. It will accept the following parameters:
Array of variables with values made available to the template. Each key will be a variable
viewParameters OPTIONAL array
available to the template.
Array of variables returned as part of the ajax response used by Mautic and/or the plugins
passthroughVars OPTIONAL array
onLoad JS callback.
Due to the use of ajax, there are some elements of the passthroughVars array that Mautic will use internally to manipulate the user
interface. For responses that include main content, i.e. routes a user would click to, should set at least activeLink and route .
activeLink OPTIONAL string The ID of the menu item that should be activated dynamically to match the ajax response
route OPTIONAL string The route that should be pushed to the browsers address bar to match the ajax response
Used to generate the Javascript method to call after the ajax content has been injected into the
DOM. The same function will also be called on a page refresh/full page load if set via
$view['slots'] in the template. For example, if this is set as helloWorldDetails , Mautic will
mauticContent OPTIONAL string
check for the existence of and executes Mautic.helloWorldDetailsOnLoad() . Refer to
Processing Ajax Content for more information regarding this and Asset Helper for injecting
assets into the head for ajax generated content.
A Mautic namespaced JS function that will be executed before the response is injected into the
callback OPTIONAL string DOM. If set, Mautic will pass the response to the function and not process the content. It will
be up to the callback function to handle the rest of the process.
redirect OPTIONAL string The URL to force a page redirect rather than inject ajax content.
jQuery selector to inject the content into. By default, the apps main content selector will be
target OPTIONAL string
used.
Determines if Mautic should replace the target selector with the ajax content or set as its inner
replaceContent OPTIONAL string
HTML. Return true as a string to replace the selector.
DELEGATEREDIRECT($URL)
If an ajax request, a json response with {redirect: $url} will be returned allowing the executing JS code to force the redirect.
https://developer.mautic.org/#plugin-directory-structure 18/222
17/12/2017 Mautic Developer Documentation
POSTACTIONREDIRECT($ARGS)
Similar to delegateView(), this method will delegate the appropriate response based on the request. This method can be used after
performing some action, such as saving a form. It accepts the same elements in the $args array as delegateView() but also accepts the
following:
The URL to redirect to. It will default to /s/dashboard if not set. This will also auto-populate
returnUrl OPTIONAL string
passthroughVars[route] if not set.
Array of ash messages to display after redirecting. See Flash Messages for more
ashes OPTIONAL array
information.
By default, the request is forwarded to a controller method rather than directly loading a view
template. This means that contentTemplate should be in controller notation
forwardController OPTIONAL bool (BundleName:ControllerName:controllerMethod) rather than view notation
(BundleName:ViewName:template.html.php). Set this to false to directly load a view
template rather than forwarding to another controller.
MAUTIC\COREBUNDLE\CONTROLLER\FORMCONTROLLER
This controller extends CommonController and provides helper methods for managing forms. See Forms for more information.
MAUTIC\COREBUNDLE\CONTROLLER\AJAXCONTROLLER
This controller also extends CommonController and is a companion to some of the built-in Javascript helpers. See Javascript methods for
more information.
MODELS
<?php
// plugins/HelloWorldBundle/Model/ContactModel.php
namespace MauticPlugin\HelloWorldBundle\Model;
use Mautic\CoreBundle\Model\CommonModel;
/**
* Send contact email
*
* @param array $data
*/
public function sendContactEmail($data)
{
// Get mailer helper - pass the mautic.helper.mailer service as a dependency
$mailer = $this->mailer;
$mailer->message->addTo(
$this->factory->getParameter('mailer_from_email')
);
$this->message->setFrom(
array($data['email'] => $data['name'])
);
$mailer->message->setSubject($data['subject']);
$mailer->message->setBody($data['message']);
$mailer->send();
https://developer.mautic.org/#plugin-directory-structure 19/222
17/12/2017 Mautic Developer Documentation
}
}
Models are used to retrieve and process data between controllers and views. Models arent required for plugins but, if used, Mautic
provides means to easily obtain the model objects and some commonly used methods.
MODEL CLASSES
Models should be registered as model services. The names of these services should match the following nomenclature: mautic.UNIQUE_
BUNDLE_IDENTIFIER.model.MODEL_IDENTIFIER . UNIQUE_BUNDLE_IDENTIFIER can be whatever is desired but must be unique across all Mautic
bundles and plugins. MODEL_IDENTIFIER just has to be unique for the given bundle. For example, the model example code could be
registered as mautic.helloworld.model.contact . This allows the helper functions to retrieve model objects to nd the correct model
service.
Custom models can extend one of two Mautic base models to leverage some helper functions:
\MAUTIC\COREBUNDLE\MODEL\ABSTRACTCOMMONMODEL
This is the basic model that mainly provides access to services frequently used with models.
Property Service
$this->factory Mautics factory service - deprecated as of 2.0; use direct dependency injection where possible
\MAUTIC\COREBUNDLE\MODEL\FORMMODEL
The FormModel extends AbstractCommonModel and provides a set of helper methods for interacting with entities and repositories. To read
more about these methods, refer to the Database section.
<?php
If using a model in another service or model, inject the model service as a dependency. If in a controller, use the getModel() helper
function.
VIEWS
<?php
//plugins/HelloWorldBundle/Views/World/details.html.php
https://developer.mautic.org/#plugin-directory-structure 20/222
17/12/2017 Mautic Developer Documentation
// Set tmpl for parent template
$view['slots']->set('tmpl', 'Details');
<div>
<!-- Desired content/markup -->
</div>
<?php
// plugins/HelloWorldBundle/Views/World/index.html.php
<div class="helloworld-content">
<?php $view['slots']->output('_content'); ?>
</div>
Views take data given it from the controller and displays the content to the user. Templates can be called from the controller or from within
other templates.
It was discussed in the Controllers delegateView() method how to render a view from a controller. Remember that delegateView uses
contentTemplate to determine what view to render.
Similar to controller notation, views are noted as HelloWorldBundle:Contact:form.html.php which will point to the le
/path/to/mautic/plugins/HelloWorldBundle/Views/Contact/form.html.php .
View notation is in the format of BundleName:ViewName:template.html.php . To use a view that has been nested in Views, use
BundleName:ViewName\Subfolder:template.html.php .
VIEW PARAMETERS
Remember the array passed via viewParameters in the Controllers delegateView() method? Here is where the elements of that array will
be made available as variables.
For example, $world will be available and assigned the value of mars from the following example:
https://developer.mautic.org/#plugin-directory-structure 21/222
17/12/2017 Mautic Developer Documentation
By default there are a couple variables available and should not be overridden by the controller
Variable Description
Contains all the helper objects available to templates along with providing methods for extending and/or rendering other
$view
templates.
$app Gives access to request and session to views via $app->getRequest() and $app->getSession()
EXTENDING VIEWS
<?php
<?php
// Extends the "slim" document which includes just the head and body with main content; does not include menu, page header, etc.
$view->extend('MauticCoreBundle:Default:content.html.php');
Because of the use of Ajax, views must also be able to return main content vs the entire document. This is done by extending Mautics base
templates. Notice the notation is the same as what is used in controllers.
To determine if the request is Ajax or not, use $app->getRequest()->isXmlHttpRequest() . Another option is to make the determination in the
controller and pass it in the viewParameters array.
Of course, this can also be used to extend custom templates as demonstrated in this code example.
It may help to note that extended templates are rendered inside out. So if HelloWorldBundle:World:details.html.php extends
HelloWorldBundle:World:index.html.php which extends MauticCoreBundle:Default:content.html.php , the content of details.html.php
will be rendered rst and injected into index.html.php as it is rendered. HelloWorldBundle:World:template1.html.php will be rendered
last.
To include the content from the sub-template in the parent template, use $view['slots']->output('_content'); . See the Slots Helper for
more information.
To render the content of another template from within a template, simply use echo $view->render('BundleName:ViewName:template.html.
php', array('parameter' => 'value'));
TEMPLATE HELPERS
There are a number of template helper objects and helper view templates that are built into Mautic.
SLOTS HELPER
<?php
https://developer.mautic.org/#plugin-directory-structure 22/222
17/12/2017 Mautic Developer Documentation
$view['slots']->append('name', ' and more content');
$view['slots']->append('existingArray',
array(
'append' => 'me'
)
);
As seen with extending views, the slots helper is used to pass content up through parent templates. Remember that extended templates
are rendered inside out. So, content can be set in a sub template and accessed from the parent template but content set in a parent
template, will not be available to the sub-template.
ASSET HELPER
<?php
The asset helper, accessed via $view['assets'] , is used to load assets into the DOM including images, script and stylesheets.
$view['assets'] should always be used to ensure that assets work with Mautic installed in the web root, installed in a
subdirectory, ran under the dev environment (index_dev.php), and/or ran under the prod environment.
The asset helper also provides a way to insert scripts and stylesheets into the head for ajax loaded content using $view['assets']->inclu
deScript() and $view['assets']->includeStylesheet() .
ROUTER HELPER
<a href="<?php echo $view['router']->generate('plugin_helloworld_world', array('world' => 'mars')); ?>" data-toggle="ajax" />Mars</a>
TRANSLATION HELPER
DATE HELPER
https://developer.mautic.org/#plugin-directory-structure 23/222
17/12/2017 Mautic Developer Documentation
<?php
// Can be string or \DateTime object; if string, it's assumed local time unless noted otherwise via third argument to helper methods
$datetime = '2015-04-12 20:56:00';
// Formats date as Yesterday, 8:02 pm (Today or Tomorrow); otherwise 'x days ago'
$text = $view['date']->toText($datetime);
The date helper can be used to format dates based on system and/or user settings.
The rst argument to the various methods can either be a date/time string or a \DateTime object. If a string, it is expected to be formatted as
Y-m-d H:i:s and already in the users and/or systems local time. If it is not, pass the format as the second argument and the timezone
(string) as the third.
FORM HELPER
@todo
AJAX LINKS
<a href="<?php echo $view['router']->generate('plugin_helloworld_world', array('world' => 'mars')); ?>" data-toggle="ajax" />Mars</a>
AJAX MODALS
https://developer.mautic.org/#plugin-directory-structure 24/222
17/12/2017 Mautic Developer Documentation
Mautic uses Bootstrap modals but Bootstrap lacks an easy way to dynamically retrieve content more than once. Thus, Mautic provides the
attribute data-toggle="ajaxmodal" to help with this.
data-target should be the selector of the model to inject the content into. Mautic has a modal, #MauticSharedModal on standby to be used
for this very purpose.
AJAX FORMS
Mautic provides a way to execute a javascript function after it injects ajax content into the DOM. This can be useful to activate various JS
driven features such as typeaheads, charts, bind events, etc.
To take advantage of this, utilize the mauticContent element in the passthroughVars array from the controllers delegateView(). The value of
this variable will determine what function should be called after the content has been injected.
For example, the method Mautic.helloWorldDetailsOnLoad() will be called for the following:
When the user browses away from the page, Mautic.helloWorldDetailsOnUnload() will be called to give opportunity to destroy objects if
necessary.
Both the OnLoad and OnUnload methods are passed two arguments.
Argument Description
container The selector that was used as the target of the ajax content.
response The object from the ajax response, i.e. set in the passthroughVars from the Controller
mauticContent should also be set via $view['slots'] in the views main page.
$view['slots']->set('mauticContent', 'helloBundleDetails');
Doing so will ensure Mautic.helloWorldDetailsOnLoad() is also called when there is a page refresh.
Services
https://developer.mautic.org/#plugin-directory-structure 25/222
17/12/2017 Mautic Developer Documentation
These are the services used commonly throughout Mautic.
FACTORY SERVICE
\Mautic\Factory\MauticFactory is deprecated as of 2.0 and will be phased out through 2.x release cycles and completely removed in 3.0.
Direct dependency injection into the services should be used instead where possible.
For custom services, pass mautic.factory as an argument and MauticFactory will be passed into the __construct of the service.
USER
<?php
$user = $this->get('mautic.helper.user')->getUser();
$firstName = $user->getFirstname();
$lastName = $user->getLastname();
$email = $user->getEmail();
$profile = $user->getProfile();
$role = $user->getRole()->getName();
if ($role->isAdmin()) {
// do something
}
getUser() will return the entity, \Mautic\UserBundle\Entity\User that can then be used to get information about the currently logged in
user.
SECURITY
<?php
$security = $this->get('mautic.security');
https://developer.mautic.org/#plugin-directory-structure 26/222
17/12/2017 Mautic Developer Documentation
)
) {
//do something
}
if ($permissions['plugin:helloWorld:worlds:view']) {
// do something
}
TRANSLATOR
<?php
$translator = $this->get('translator');
// Simple string
echo $translator->trans('plugin.helloworld.goodbye');
// Plural translations
$planetCount = 3;
echo $translator->transChoice('plugin.helloworld.number_of_planets', $planetCount, array('%planets%' => $planetCount));
// Use the first key if it exists, otherwise use the second (helpful to prevent managing duplicate keys with the same string)
echo $translator->transConditional('plugin.helloworld.planets.' . $planet, 'plugin.helloworld.dwarf_planets. ' . $planet);
Use the translator service to include translated strings in the code. Depending on where the translation is necessary will determine how to
obtain the service.
To use the template service in view templates, simply use the template helper, $view['translator'] .
https://developer.mautic.org/#plugin-directory-structure 27/222
17/12/2017 Mautic Developer Documentation
The translator service has the following functions to help with translating strings:
Simple translation
trans($id, array $parameters = array(), $domain = null, $locale = null)
Pluralization
transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
ROUTER
<?php
$router = $this->get('router');
// Relative URL
$url = $router->generateUrl('plugin_helloworld_admin');
// Absolute URL
$absoluteUrl = $router->generateUrl('plugin_helloworld_admin', array(), true);
<?php
// Deprecated - use path or url instead
$url = $view['router']->generate('plugin_helloworld_admin'); // result is /hello/admin
For views, use the $view['router'] helper. The difference with the template helper is that url() or path() is used instead of generate
Url() of the router service.
REQUEST
<?php
$request = $this->get('request_stack')->getCurrentRequest();
// $_GET
$get = $request->query->all();
// $_POST
$post = $request->request->all();
// $_COOKIE
$cookies = $request->cookies->all();
// $_SERVER
$server = $request->server->all();
// Headers
https://developer.mautic.org/#plugin-directory-structure 28/222
17/12/2017 Mautic Developer Documentation
$headers = $request->headers->all();
If the controller is extending one of Mautics controllers, it is already available via $this->request . Alternatively, Symfony will auto-inject the
request object into the controller action method if the variable is type-hinted as Symfony\Component\HttpFoundation\Request .
For services, pass the request_stack service then use $request = $requestStack->getCurrentRequest() .
SESSION
<?php
$session = $this->get('session');
$requestSession = $request->getSession(); // Shortcut to session
DATABASE/ENTITY MANAGER
https://developer.mautic.org/#plugin-directory-structure 29/222
17/12/2017 Mautic Developer Documentation
<?php
// From controller
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('HelloWorldBundle:World');
$worlds = $repository->getEntities();
$repository->saveEntities($worlds);
ORM/entity manager:
The entity manager can be used to interact with the bundles repositories and entities. See Database for more info.
CONFIG PARAMETERS
<?php
$config = $this->get('mautic.helper.core_parameters');
EVENT DISPATCHER
<?php
$dispatcher = $this->get('event_dispatcher');
if ($dispatcher->hasListeners(HelloWorldEvents::ARMAGEDDON)) {
$event = $dispatcher->dispatch(HelloWorldEvents::ARMAGEDDON, new ArmageddonEvent($world));
if ($event->shouldPanic()) {
throw new \Exception("Run for the hills!");
}
}
PATHS HELPER
<?php
$pathsHelper = $this->get('mautic.helper.paths');
https://developer.mautic.org/#plugin-directory-structure 30/222
17/12/2017 Mautic Developer Documentation
$relativeImagesDir = $pathsHelper->getSystemPath('images'); // media/images
$absoluteImageDir = $pathsHelper->getSystemPath('images', true); // /home/user/public_html/media/images
This helper should be used when retrieving system paths for Mautic (images, themes, cache, etc)
There is also a tmp or temporary option to store temporary les. It should be used by developers for such use case instead of the general
cache location.
IP LOOKUP HELPER
<?php
$ipHelper = $this->get('mautic.helper.ip_lookup');
echo $details['city'];
This helper can be used to retrieve the real IP for the request.
<?php
$configHelper = $this->get('mautic.helper.bundle');
This can be used to get the conguration array of a bundle/plugins Cong/cong.php le.
COOKIE HELPER
<?php
$cookieHelper = $this->get('mautic.helper.cookie');
$cookieHelper->setCookie('name', 'value', 3600);
$cookieHelper->deleteCookie('name');
The cookie helper can be used to set cookies based on system settings.
MAIL HELPER
<?php
$mailer = $this->get('mautic.helper.mailer')->getMailer();
https://developer.mautic.org/#plugin-directory-structure 31/222
17/12/2017 Mautic Developer Documentation
$mailer->addTo($toAddress, $toName);
// Set subject
$mailer->setSubject($email['subject']);
// Set content
$mailer->setBody($content);
$mailer->parsePlainText($content);
// Send the mail, pass true to dispatch through event listeners (for replacing tokens, etc)
if ($mailer->send(true)) {
<?php
// Using queue() for tokenization support
use Mautic\EmailBundle\Swiftmailer\Exception\BatchQueueMaxException;
$mailer = $this->get('mautic.helper.mailer')->getMailer();
$failed = array();
$mailer->enableQueue();
foreach ($emailList as $email) {
try {
if (!$mailer->addTo($email['email'], $email['name'])) {
// Clear the errors so it doesn't stop the next send
$mailer->clearErrors();
$failed[] = $email;
continue;
}
} catch (BatchQueueMaxException $e) {
// Queue full so flush (send) then try again
if (!$mailer->flushQueue()) {
$errors = $mailer->getErrors();
$failed = array_merge($failed, $errors['failures']);
}
// Flush pending
if (!$mailer->flushQueue()) {
// ...
}
https://developer.mautic.org/#plugin-directory-structure 32/222
17/12/2017 Mautic Developer Documentation
The mail helper can be used to send email, running the content through the event listeners to search/replace tokens, manipulate the
content, etc.
Some transports, such as Mandrill, support tokenized emails for multiple recipients. The mail helper makes it easy to leverage this feature
by using its queue() and flushQueue() functions in place of send() . If sending a batch of emails, it is recommended to use the queue()
function. Although these classes will still work with using just send() for one off emails, if sending a batch of the same email to multiple
contacts, enable tokenization/batch mode with enableQueue() .
If using an Email entity ( \Mautic\EmailBundle\Entity\Email ), just pass the Email entity to $mailer->setEmail($email) and the subject,
body, assets, etc will be extracted and automatically set.
ATTACHMENTS
Attachments can be attached to emails by using the attachFile() function. You can also attach Mautic assets ( \Mautic\AssetBundle\En
tity\Asset ) via attachAsset() .
MODEL FACTORY
<?php
$channel = 'email';
$channelId = 1;
if ($modelFactory->hasModel($channel)) {
$model = $modelFactory->getModel($channel);
if ($entity = $model->getEntity($channelId)) {
echo $entity->getName();
}
}
Mautic/CoreBundle/Factory/ModelFactory can be used in services that a model dependency is unknown at the time the service is created.
This is great for scenarios where the channel and channel ID are stored in a database and the executing code needs to obtain information
on the channel entity (name, etc).
It has two methods: hasModel($modelNameKey) and getModel($modelNameKey) . hasModel simple checks to see if a model exists. It uses the
same format as using the controller helper method getModel() . For example, to obtain the Mautic\EmailBundle\Model\EmailModel class,
you could use something like the code example.
Database
<?php
// plugins/HelloWorldBundle/Entity/World.php
namespace MauticPlugin\HelloWorldBundle\Entity;
/**
* Class World
*/
class World extends CommonEntity
{
/**
https://developer.mautic.org/#plugin-directory-structure 33/222
17/12/2017 Mautic Developer Documentation
* @var int
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $description;
/**
* @var Category
*/
private $category;
/**
* @var int
*/
private $visitCount;
/**
* @var int
*/
private $population = 0;
/**
* @var bool
*/
private $isInhabited = false;
/**
* @param ORM\ClassMetadata $metadata
*/
public static function loadMetadata (ORM\ClassMetadata $metadata)
{
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable('worlds')
->setCustomRepositoryClass('MauticPlugin\HelloWorldBundle\Entity\WorldRepository');
// Helper functions
$builder->addIdColumns();
$builder->addCategory();
$builder->addNamedField('visitorCount', 'int', 'visitor_count');
$builder->addField('population', 'int');
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
https://developer.mautic.org/#plugin-directory-structure 34/222
17/12/2017 Mautic Developer Documentation
}
/**
* @param mixed $name
*
* @return World
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $description
*
* @return World
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @return Category
*/
public function getCategory()
{
return $this->category;
}
/**
* @param mixed $category
*
* @return World
*/
public function setCategory(Category $category)
{
$this->category = $category;
return $this;
}
/**
* @return mixed
*/
public function getVisitCount()
{
return $this->visitCount;
}
/**
* @param mixed $visitCount
*
* @return World
*/
public function setVisitCount($visitCount)
{
$this->visitCount = $visitCount;
https://developer.mautic.org/#plugin-directory-structure 35/222
17/12/2017 Mautic Developer Documentation
return $this;
}
/**
* Increase the visit count by one
*/
public function upVisitCount()
{
$this->visitCount++;
}
/**
* Get planet population
*/
public function getPopulation()
{
return $this->population;
}
/**
* @param int $population
*
* @return World
*/
public function setPopulation($population)
{
$this->population = $population;
return $this;
}
/**
* @return boolean
*/
public function isIsInhabited()
{
return $this->isInhabited;
}
/**
* @param boolean $isInhabited
*
* @return World
*/
public function setIsInhabited($isInhabited)
{
$this->isInhabited = $isInhabited;
return $this;
}
}
<?php
// plugins/HelloWorldBundle/Entity/WorldRepository.php
namespace MauticPlugin\HelloWorldBundle\Entity;
use Mautic\CoreBundle\Entity\CommonRepository;
/**
* WorldRepository
*/
class WorldRepository extends CommonRepository
{
https://developer.mautic.org/#plugin-directory-structure 36/222
17/12/2017 Mautic Developer Documentation
$q = $this
->createQueryBuilder('w')
->leftJoin('a.category', 'c');
$args['qb'] = $q;
return parent::getEntities($args);
}
}
Mautic uses Doctrine, a database object relational mapper (ORM) and database abstraction layer (DBAL) library.
Most of Mautic use entity and repository classes to dene the schema and interact with the database.
USAGE
Refer to Symfonys and Doctrines documentation on the specics of how to interact with the Database.
METADATA/SCHEMA
Mautic uses Doctrines PHP Driver to dene schema. The plugin doesnt necessarily have to use entities but should at least dene Entity
classes to create its schema.
INSTALLING/UPDATING SCHEMA
When an plugin is installed or updated, the bundles onInstall or onUpgrade functions are called. These functions can be used to manipulate
the database schema. See Install/Upgrade.
TABLE PREFIX
Mautic allows custom table prexes. If using ORM, there is no need to include the prex as Mautic will automatically handle it. However, if
there is a need to use Doctrines DBAL layer directly, the contstant MAUTIC_TABLE_PREFIX can be used in conjuction with the table name.
When using ORM, Mautic will automatically convert DateTime properties to UTC and to the system/users prole timezone on retrieval.
However, if using DBAL, DateTime strings must be converted to UTC before persisting and to the local timezone on retrieval. See
Date/Time Helper to assist with conversions.
For arrays, ORM will auto serialize and unserialize. DBAL will need to manually handle this.
Permissions are calculated based on bits assigned to an plugins level and permission. Bits are integers that increase by doubling the value.
1, 2, 4, 8, 16, 32, 64, 128, 512, 1024, and so forth. The bits should never be assigned numbers in between such as 3 or 5 as the permission
will not be correctly calculated in such cases.
For example, lets say HelloWorldBundle needs to manage access to users Worlds entity. A permission set for plugin:helloWorld:worlds
might look like
Permission Bit
view 1
edit 2
https://developer.mautic.org/#plugin-directory-structure 37/222
17/12/2017 Mautic Developer Documentation
Permission Bit
create 4
delete 8
full 16
plugin:helloWorld:worlds:view is a typically notation for requesting permission in Mautic. The notation tells Mautic to check for
the `view` permission for the plugin, HelloWorldBundle, within the `worlds` level. Levels allow plugins to set permissions for multiple
areas.
Mautic will take the summation of the bits for the permissions given to a role and store it in the database. For example, if a role is given view
and edit access, the stored bit is 3. If given view and create access, the stored bit is 5.
When a permission check is required, e.g. plugin:helloWorld:worlds:create , Mautic will check if bit of 4 is set in the roles generated bit
for plugin:helloWorld:worlds . If so, permission is granted.
The permission full is reserved to grant access to all previous permissions within the level and thus should always be the highest
bit.
USING PERMISSIONS
<?php
$security = $this->get('mautic.security');
https://developer.mautic.org/#plugin-directory-structure 38/222
17/12/2017 Mautic Developer Documentation
),
'RETURN_ARRAY'
);
if ($permissions['plugin:helloWorld:worlds:view']) {
// do something
}
To determine if a user has a specic permission, use Mautics security service which can be obtained from the mautic.security service.
As suggested above, Mautic uses a special permission notation to refer to a specic permission. For core bundles, bundleName:permis
sionLevel:permission is used. For plugins, append plugin: , i.e. plugin:bundleName:permissionLevel:permission . plugin: tells Mautic to
look for the permission class in the plugins/ directory and MauticPlugin namespace.
The permission level and permissions are set by the core bundle or plugin. For example, Mautics core UserBundle has users and roles
levels with view , edit , create , delete and full permissions for each.
<?php
// plugins/HelloWorldBundle/Security/Permissions/HelloWorldPermissions.php
namespace MauticPlugin\HelloWorldBundle\Security\Permissions;
use Symfony\Component\Form\FormBuilderInterface;
use Mautic\CoreBundle\Security\Permissions\AbstractPermissions;
/**
* Class HelloWorldPermissions
*/
class HelloWorldPermissions extends AbstractPermissions
{
/**
* Define available permissions
*
* @param $params
*/
public function __construct($params)
{
parent::__construct($params);
$this->permissions = array(
// Custom level
'worlds' => array(
// Custom permissions
'use_telescope' => 1,
'send_probe' => 2,
'visit' => 4,
// Full will almost always be included and should be significantly higher than the
// others in case new permissions need to be added later
'full' => 1024
)
);
https://developer.mautic.org/#plugin-directory-structure 39/222
17/12/2017 Mautic Developer Documentation
/**
* Append the permission form fields to the Role form
*
* @param FormBuilderInterface $builder
* @param array $options
* @param array $data
*/
public function buildForm(FormBuilderInterface &$builder, array $options, array $data)
{
// Add standard category form fields
$this->addStandardFormFields('helloWorld', 'categories', $builder, $data);
/**
* Permission set identifier; should be bundleName
*
* @return string
*/
public function getName()
{
return 'helloWorld';
}
}
An plugin can create its own set of permissions by creating a Permission class. See the code example for a skeleton outline of what the
class will look like.
Then, for most permission classes, three methods are needed: __construct() , buildForm() and getName() .
__construct()
The construct method should do two things. It should call parent::__construct($params) or it should set $this->params = $params; .
Then it should dene $this->permissions . $this->permissions is an array of permission levels that are each arrays with permissions
assigned to bits. For example, in the code block, a custom permission level of worlds is dened with the permissions of use_telescope ,
https://developer.mautic.org/#plugin-directory-structure 40/222
17/12/2017 Mautic Developer Documentation
send_probe , visit and full . To check to see if a user has permission to the level worlds and permission send_probe , $mauticSecurity-
>isGranted('plugin:helloWorld:worlds:send_probe') would be used.
Method Description
addStandardPermissions() Set view, edit, create, delete, publish (with option to exclude), and full permissions.
Set creator level restrictions: viewown, viewother, editown, editother, create, deleteown, deleteother,
addExtendedPermissions()
publishown (with option to exclude), publishother (with option to exclude), and full
buildForm()
The buildForm method will append the permission toggles to the Roles form (see Forms for details on form builders). Review the
comments in the code sample.
There are complimentary helper methods for the common permission sets:
Method Description
addExtendedFormFields() Appends the extended, aka creator restricted, permissions to the form
getName() This method is absolutely required and should match both the bundleName and the name of the le. For example, if Hello
WorldBundle is the bundles name, then this would be helloWorld with a lename of HelloWorldPermissions.php .
PERMISSION ALIASES
<?php
To add a permission alias, use the getSynonym() method. Basically this method is called before each requested permission is determined
giving opportunity to change the permission level or name as needed.
For example, parent::getSynonym() will recognize editown as edit if editown isnt dened in the permission class $this->permissions
property for the requested level.
<?php
/**
* @param array $permissions Plugin specific permissions
* @param $allPermissions All role permissions
* @param bool $isSecondRound Is round two after permissions have been updated by all permission classes
*
* @return bool Return true if a second round is required; default false
https://developer.mautic.org/#plugin-directory-structure 41/222
17/12/2017 Mautic Developer Documentation
*/
public function analyzePermissions(array &$permissions, $allPermissions, $isSecondRound = false)
{
foreach ($permissions as $level => &$perms) {
foreach ($perms as $perm) {
$include = array();
switch ($perm) {
case 'send_probe':
$include = array('use_telescope');
break;
case 'visit':
$include = array('use_telescope', 'send_probe');
break;
}
if (!empty($include)) {
foreach ($include as $r) {
list($ignore, $r) = $this->getSynonym($level, $r);
if ($this->isSupported($level, $r) && !in_array($r, $perms)) {
$perms[] = $r;
}
}
}
}
}
// Return true if this method needs a second round after all the other bundles have adjusted permissions
return false;
}
Plugins can adjust permissions based on other selected permissions in order to prevent user error. For example, if a user has permission
to edit , then the user also needs permission to view whether that was selected in the Role form or not. The method
analyzePermissions() can be be used for this which gives opportunity to the plugin to modify permissions based on other selections before
persisting to the database.
Sometimes, it may be necessary to re-adjust based on a permission that is outside the plugins control. In this case, analyzePermissions()
can return true and it will be called again after all the permissions have been analyzed by the other bundles and plugins. In this case, the
argument $isSecondRound will be true.
If it is necessary to perform some logic other than simply comparing bits, the permission class can override the parents public function
isGranted($userPermissions, $name, $level) and do whatever is necessary for its own permission levels and individual permissions.
The same can be applied for the method isSupported() which is used to determine if a bundle or plugin includes the requested permission
and permission level. This can also be used to provide BC support.
Each conguration option desired should be dened and have a default set in the plugins cong le. This prevents Symfony from throwing
errors if the parameter is used during cache compilation or if accessed directly from the container without checking if it exists rst. Dening
the parameters in the plugins cong le will ensure that it always exists.
To add cong options to the Conguration page, an event subscriber, a cong form type, and a specic view are required.
https://developer.mautic.org/#plugin-directory-structure 42/222
17/12/2017 Mautic Developer Documentation
To translate the plugins tab in the conguration form, be sure to include mautic.config.tab.helloworld_config in the plugins
messages.ini le. Of course replace helloworld_cong with whatever is used as the formAlias when registering the form in the event
subscriber (explained below).
<?php
// plugins/HelloWorldBundle/EventListener/ConfigSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\ConfigBundle\Event\ConfigEvent;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\ConfigBundle\ConfigEvents;
use Mautic\ConfigBundle\Event\ConfigBuilderEvent;
/**
* Class ConfigSubscriber
*/
class ConfigSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return array(
ConfigEvents::CONFIG_ON_GENERATE => array('onConfigGenerate', 0),
ConfigEvents::CONFIG_PRE_SAVE => array('onConfigSave', 0)
);
}
/**
* @param ConfigBuilderEvent $event
*/
public function onConfigGenerate(ConfigBuilderEvent $event)
{
$event->addForm(
array(
'formAlias' => 'helloworld_config',
'formTheme' => 'HelloWorldBundle:FormTheme\Config',
'parameters' => $event->getParametersFromConfig('HelloWorldBundle')
)
);
}
/**
* @param ConfigEvent $event
*/
public function onConfigSave(ConfigEvent $event)
{
/** @var array $values */
$values = $event->getConfig();
https://developer.mautic.org/#plugin-directory-structure 43/222
17/12/2017 Mautic Developer Documentation
The event subscriber will listen to the ConfigEvents::CONFIG_ON_GENERATE and ConfigEvents::CONFIG_PRE_SAVE events.
The ConfigEvents::CONFIG_ON_GENERATE is dispatched when the conguration form is built giving the plugin an opportunity to inject its own
tab and cong options.
To do this, the plugin must register its conguration details through the method assigned to the ConfigEvents::CONFIG_ON_GENERATE event.
The \Mautic\CongBundle\Event\CongBuilderEvent object is passed into the method and expects the method to call addForm() .
addForm() expects an array with the following elements:
Key Description
formAlias Alias of the form type class that sets the expected form elements
The ConfigEvents::CONFIG_PRE_SAVE is called before the values from the form are rendered and saved to the local.php le. This gives the
plugin an opportunity to clean up or manipulate the data before it is written.
Remember that the subscriber must be registered through the plugins cong in the services[events] section.
CONFIG FORM
<?php
// plugins/HelloWorldBundle/Form/Type/ConfigType.php
namespace MauticPlugin\HelloWorldBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Class ConfigType
*/
class ConfigType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'custom_config_option',
'text',
array(
'label' => 'plugin.helloworld.config.custom_config_option',
'data' => $options['data']['custom_config_option'],
'attr' => array(
'tooltip' => 'plugin.helloworld.config.custom_config_option_tooltip'
)
)
);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'helloworld_config';
}
}
https://developer.mautic.org/#plugin-directory-structure 44/222
17/12/2017 Mautic Developer Documentation
The form type is used to generate the form elds in the main conguration form. Refer to Forms for more information on using form types.
Remember that the form type must be registered through the plugins cong in the services[forms] section.
CONFIG TEMPLATE
<?php
// plugins/HelloWorldBundle/Views/FormTheme/Config/_config_helloworld_config_widget.html.php
?>
Registering a formTheme as HelloWorldBundle:FormTheme\Config in the event listener told the CongBundle to look in the
HelloWorldBundles Views/FormTheme/Cong folder for templates. Specically, it will look for a template named _config_{formAlias}_wid
get.html.php where {formAlias} is the same as formAlias set in the plugins ConfigEvents::CONFIG_ON_GENERATE event listener.
The template should be in a panel format to match the rest of the cong UI.
<?php
// To obtain just the tracking ID; pass true as an argument to force regeneration of the tracking ID and cookies
list($trackingId, $trackingIdIsNewlyGenerated) = $leadModel->getTrackingCookie();
// Set a lead for system use purposes (i.e. events that use getCurrentLead()) but without generating tracking cookies
$leadModel->setSystemCurrentLead($lead);
In Mautic 1.4, Leads were renamed to Contacts. However, much of the code still refers to contacts as leads.
https://developer.mautic.org/#plugin-directory-structure 45/222
17/12/2017 Mautic Developer Documentation
Many plugins extending Mautic will be manipulating leads in one way or another. Here is a quick summary of how to obtain the current lead
and/or manipulate the leads data.
LEAD TRACKING
Leads are tracked by two cookies. The rst cookie notes which ID the lead is tracked under Mautic as. The second is to track the leads
activity for the current session (defaults to 30 minutes and resets during each lead interaction).
mautic_session_id holds the value of the leads current session ID. That value is then name of the cookie that holds the leads ID.
Review the sample code on how to obtain the currently tracked lead.
As of Mautic 2.2.0, a cookie is also placed on any domain with mtc.js embedded (thats allowed by Mautics CORS settings) as mtc_id .
This will contain the ID of the currently tracked contact.
<?php
// Currently tracked lead based on cookies
$leadModel = $this->getModel('lead');
$lead = $leadModel->getCurrentLead();
$leadId = $lead->getId();
// Updated/new fields
$leadFields = array(
'firstname' => 'Bob',
//...
);
if (array_key_exists($k, $uniqueLeadFields)) {
$uniqueLeadFieldData[$k] = $v;
}
}
// If there are unique identifier fields, check for existing leads based on lead data
if (count($inList) && count($uniqueLeadFieldData)) {
$existingLeads = $this->getDoctrine()->getManager()->getRepository('MauticLeadBundle:Lead')->getLeadsByUniqueFields(
$uniqueLeadFieldData,
$leadId // If a currently tracked lead, ignore this ID when searching for duplicates
);
if (!empty($existingLeads)) {
// Existing found so merge the two leads
$lead = $leadModel->mergeLeads($lead, $existingLeads[0]);
}
https://developer.mautic.org/#plugin-directory-structure 46/222
17/12/2017 Mautic Developer Documentation
// If the IP is not already associated, do so (the addIpAddress will automatically handle ignoring
// the IP if it is set to be ignored in the Configuration)
if (!$leadIpAddresses->contains($ipAddress)) {
$lead->addIpAddress($ipAddress);
}
}
To create a new lead, use the \Mautic\LeadBundle\Entity\Lead entity. Review the code sample.
Extending Mautic
EXTENDING API
<?php
// plugins/HelloWorldBundle/Config/config.php
return array(
// ...
// ...
// ...
);
<?php
// plugins/HelloWorldBundle/Controller/ApiController.php
namespace Mautic\LeadBundle\Controller\Api;
use FOS\RestBundle\Util\Codes;
use Mautic\ApiBundle\Controller\CommonApiController;
/**
* Get a list of worlds
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function getWorldsAction()
https://developer.mautic.org/#plugin-directory-structure 47/222
17/12/2017 Mautic Developer Documentation
{
if (!$this->get('mautic.security')->isGranted('plugin:helloWorld:worlds:view')) {
return $this->accessDenied();
}
return $this->handleView($worlds);
}
}
To add custom API endpoints, simply dene the routes under the API rewall in the plugins cong le. This will place the route behind /api
which will only be accessible if the requester has been authorized via OAuth.
The api controller(s), should extend Mautic\ApiBundle\Controller\CommonApiController to leverage the helper methods provided and to
utilize the REST views.
EXTENDING BROADCASTS
Broadcasts are communications sent in bulk through a channel such as email (segment emails). Mautic 2.2.0 introduced a new event to
execute the sending of these bulk communications via the mautic:broadcasts:send command.
<?php
// plugins\HelloWorldBundle\EventListener\BroadcastSubscriber
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\CoreEvents;
use Mautic\CoreBundle\Event\ChannelBroadcastEvent;
use MauticPlugin\HelloWorldPlugin\Model\WorldModel;
/**
* Class BroadcastSubscriber
*/
class BroadcastSubscriber extends CommonSubscriber
{
/**
* @var WorldModel
*/
protected $model;
/**
* BroadcastSubscriber constructor.
*
* @param WorldModel $model
*/
public function __construct(WorldModel $model)
{
$this->model = $model;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
CoreEvents::CHANNEL_BROADCAST => ['onChannelBroadcast', 0]
];
https://developer.mautic.org/#plugin-directory-structure 48/222
17/12/2017 Mautic Developer Documentation
}
To hook into the mautic:broadcasts:send command, create a listening for the \Mautic\CoreBundle\CoreEvents::CHANNEL_BROADCAST event.
The event listener should check for the appropriate context and ID. See example code.
EXTENDING CAMPAIGNS
<?php
// plugins/HelloWorldBundle/EventListener/CampaignSubscriber.php
namespace MauticPlugin\HelloWorldBundle\Events;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\CampaignBundle\Event as Events;
use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Event\CampaignExecutionEvent;
/**
* Class CampaignSubscriber
*/
class CampaignSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return array(
CampaignEvents::CAMPAIGN_ON_BUILD => array('onCampaignBuild', 0),
HelloWorldEvents::BLASTOFF => array('executeCampaignAction', 0),
HelloWorldEvents::VALIDATE_VISIT => array('validateCampaignDecision', 0)
);
}
/**
* Add campaign decision and actions
*
* @param Events\CampaignBuilderEvent $event
*/
public function onCampaignBuild(Events\CampaignBuilderEvent $event)
{
// Register custom action
$event->addAction(
'helloworld.send_offworld',
array(
'eventName' => HelloWorldEvents::BLASTOFF,
'label' => 'plugin.helloworld.campaign.send_offworld',
'description' => 'plugin.helloworld.campaign.send_offworld_descr',
https://developer.mautic.org/#plugin-directory-structure 49/222
17/12/2017 Mautic Developer Documentation
// Set custom parameters to configure the decision
'formType' => 'helloworld_worlds',
// Set a custom formTheme to customize the layout of elements in formType
'formTheme' => 'HelloWorldBundle:FormTheme\SubmitAction',
// Set custom options to pass to the form type, if applicable
'formTypeOptions' => array(
'world' => 'mars'
)
)
);
// Register custom decision (executes when a lead "makes a decision" i.e. executes some direct action
$event->addDecision(
'helloworld.visits_mars',
array(
'eventName' => HelloWorldEvents::VALIDATE_VISIT,
'label' => 'plugin.helloworld.campaign.visits_mars',
'description' => 'plugin.helloworld.campaign.visits_mars_descr',
// Same as registering an action
'formType' => false,
'formTypeOptions' => array()
)
);
}
/**
* Execute campaign action
*
* @param CampaignExecutionEvent $event
*/
public function executeCampaignAction (CampaignExecutionEvent $event)
{
// Do blastoff
$event->setResult(true);
}
/**
* Validate campaign decision
*
* @param CampaignExecutionEvent $event
*/
public function validateCampaignDecision (CampaignExecutionEvent $event)
{
$valid = ($event->getEventDetails()->getId() === $event->getConfig()['id']);
$event->setResult($valid);
}
}
Plugins can add their own campaign actions, decisions, or conditions by listening to the \Mautic\CampaignBundle\CampaignEvents::CAMPAI
GN_ON_BUILD event. Read more about listeners and subscribers.
CAMPAIGN ACTIONS
To add an action, use the $event->addAction($identifier, $parameters) method. $identifier must be something unique. The $parame
ters array can contain the following elements:
label REQUIRED string The language string to use for the draggables label
The name of the event that should be dispatched to handle this action. The plugin
eventName REQUIRED string
will need to also create its own listener for the event.
description OPTIONAL string The language string to use for the draggables tooltip
https://developer.mautic.org/#plugin-directory-structure 50/222
17/12/2017 Mautic Developer Documentation
formType OPTIONAL string The alias of a custom form type used to set cong options for the decision
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
Array of keys registered as decisions that this action can attached to. Defaults to
associatedDecisions OPTIONAL array
any decision.
Array of anchors (the places on an event in the builder this action can be attached
to). The format is eventType.anchorName. Event types can be source, decision,
action, or condition. anchorName includes top, bottom, inaction (yes/green),
anchorRestrictions OPTIONAL array action (no/red) or leadsource. For example, by passing an array with deci
sion.inaction , this action will not be attachable to the inaction/red anchor of a
decision.
The listener for dispatched event will have the Mautic\CampaignBundle\Event\CampaignExecutionEvent injected. To note that the action was
successfully executed, use $event->setResult($result) . $result can be a boolean or an array. Setting false will cause the action to be
retried. If an array, it will be stored in the campaign event logs metadata array (useful for displaying information in the contact time-line).
Use $event->setFailed() to note that an event failed but should not be retried. Failed events do not appear in a contacts time-line.
CAMPAIGN DECISIONS
<?php
// Trigger configured 'helloworld.visits_mars' decisions
// Some optional unique identifier for this specific trigger that is used mainly for debug logging; for example, can be a concatenation of the decision
name + lead ID
$uniqueTriggerId = 'something_something';
Campaign decisions are registered exactly as a campaign action except it uses the $event->addDecision($identifier, $parameters)
method. The only difference in the $parameters arguments is that the listener for the eventName is used to validate the decision rather than
execute some action and it accepts a associatedActions array instead of associatedDecisions . For example, if the decision is congured
to only apply to a specic ID chosen by the user (dened in the formType ), the listener could compare the decisions $event->getEventDe
tails()->getId() (see example) with the events $event->getConfig()['id'] . If the decision should execute the actions associated with it,
set $event->setResult(true); . Otherwise $event->setResult(false); and nothing will be executed or logged.
For custom decisions to work, there must be a trigger executed when the lead makes the decision. Thus, where ever is appropriate in the
plugins code logic, add something similar to whats in the example code block.
The triggerEvent() method will pull all the triggered decisions ( helloworld.visits_mars in the code example) for published campaigns
the lead is in, dispatch the decisions event (if congured) for validation, then execute the associated actions if appropriate.
CAMPAIGN CONDITIONS
https://developer.mautic.org/#plugin-directory-structure 51/222
17/12/2017 Mautic Developer Documentation
Campaign conditions are registered with addCondition() and accepts the same arguments as addDecision() . The listener also receives
an instance of Mautic\CampaignBundle\Event\CampaignExecutionEvent . To mark a condition as true or false, use $event->setResult($re
sult); .
EXTENDING CATEGORIES
Mautic has a CategoryBundle that can be leveraged to incorporate categories into a plugin.
ADDING CATEGORIES
As of Mautic 1.2.1, register categories through the plugins cong.php le by adding the following as a key to the returned cong array:
The category keys need be prexed with plugin: as it is used in determining permissions to manage categories. The helloWorld should
match the permission class name.
To add a category menu item for the plugin, simply add the following to menu cong for whichever menu the item should appear ( main or
admin ):
The bundle value needs be prexed with plugin: as it is used in determining permissions to manage categories. The helloWorld should
be the bundle name of the plugin.
There is no need to add custom routes for categories. However, when generating a URL to the plugins category list, use
To add a category select list to a form, use category as the form type and pass bundle as an option:
//add category
$builder->add('category', 'category', array(
'bundle' => 'plugin:helloWorld'
));
To restrict access to catgories, use the following in the plugins Permission class.
The two standard helper methods will add the permissions of view , edit , create , delete , publish , and full for categories.
https://developer.mautic.org/#plugin-directory-structure 52/222
17/12/2017 Mautic Developer Documentation
CONTACT TIMELINE/HISTORY
<?php
// plugins/HelloWorldBundle/EventListener/LeadSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\LeadBundle\Event\LeadTimelineEvent;
use Mautic\LeadBundle\LeadEvents;
/**
* Class LeadSubscriber
*/
class LeadSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return [
LeadEvents::TIMELINE_ON_GENERATE => ['onTimelineGenerate', 0]
];
}
/**
* Compile events for the lead timeline
*
* @param LeadTimelineEvent $event
*/
public function onTimelineGenerate(LeadTimelineEvent $event)
{
// Add this event to the list of available events which generates the event type filters
$eventTypeKey = 'visited.worlds';
$eventTypeName = $this->translator->trans('mautic.hello.world.visited_worlds');
$event->addEventType($eventTypeKey, $eventTypeName);
return;
}
// If isEngagementCount(), this event should only inject $stats into addToCounter() to append to data to generate
// the engagements graph. Not all events are engagements if they are just informational so it could be that this
// line should only be used when `!$event->isEngagementCount()`. Using TimelineTrait will determine the appropriate
// return value based on the data included in getQueryOptions() if used in the stats method above.
$event->addToCounter($eventTypeKey, $stats);
if (!$event->isEngagementCount()) {
// Add the events to the event array
foreach ($stats['results'] as $stat) {
if ($stat['dateSent']) {
$event->addEvent(
[
// Event key type
'event' => $eventTypeKey,
// Event name/label - can be a string or an array as below to convert to a link
https://developer.mautic.org/#plugin-directory-structure 53/222
17/12/2017 Mautic Developer Documentation
'eventLabel' => [
'label' => $stat['name'],
'href' => $this->router->generate(
'mautic_dynamicContent_action',
['objectId' => $stat['dynamic_content_id'], 'objectAction' => 'view']
)
],
// Translated string displayed in the Event Type column
'eventType' => $eventTypeName,
// \DateTime object for the timestamp column
'timestamp' => $stat['dateSent'],
// Optional details passed through to the contentTemplate
'extra' => [
'stat' => $stat,
'type' => 'sent'
],
// Optional template to customize the details of the event in the timeline
'contentTemplate' => 'MauticDynamicContentBundle:SubscribedEvents\Timeline:index.html.php',
// Font Awesome class to display as the icon
'icon' => 'fa-envelope'
]
);
}
}
}
}
}
To inject events into a contacts timeline, create an event listener that listens to the LeadEvents::TIMELINE_ON_GENERATE event. Using this
event, the plugin can inject unique items into the timeline and also into the engagements graph on each page.
The event listener will receive a Mautic\LeadBundle\Event\LeadTimelineEvent object. The commonly used methods are dened below:
Method Description
getQueryOptions() Used to get pagination, lters, etc needed to generate an appropriate query
Used to add total number of events (across all pages) to the counters. This also generates the numbers for the
addToCounter()
engagements graph.
addEvent() Required - Injects an event into the timeline. Accepts an array with the keys dened as below.
addEvent($event) Key Denitions Key|Required|Type|Description ||-| event|REQUIRED|string|The key for this event.
Eg. world.visited eventType|REQUIRED|string|The translated string representing this event type. Eg. Worlds visited
timestamp|REQUIRED|\DateTime|DateTime object when this event took place eventLabel|OPTIONAL|string/array|The translated string to
display in the event name. Examples include names of items, page titles, etc. This can also be an array of [label => , 'href => ] to have
the entry converted to a link. This will default to eventType if not dened. extra|OPTIONAL|array|Whatever should be passed through to the
content template to generate the details view for this event contentTemplate|OPTIONAL|string|Template that should be used to generate
the details view for this event. Eg. HelloBundle:SubscribedEvents\Timeline:index.html.php icon|OPTIONAL|Font Awesome class
<?php
//plugins/HelloWorldBundle/Entity/WorldRepository.php
https://developer.mautic.org/#plugin-directory-structure 54/222
17/12/2017 Mautic Developer Documentation
namespace Mautic\LeadBundle\Entity;
use Mautic\CoreBundle\Entity\CommonRepository;
use Mautic\LeadBundle\Entity\TimelineTrait;
/**
* Class WorldRepository
*/
class WorldRepository extends CommonRepository
{
use TimelineTrait;
/**
* @param $leadId
* @param array $options
*/
public function getTimelineStats($leadId, array $options = [])
{
$query = $this->getEntityManager()->getConnection()->createQueryBuilder();
To assist with the generation of events, the Mautic\LeadBundle\Entity\TimelineTrait has been created.
To leverage this, accept the array from $event->getQueryOptions() in the repository method. Create a DBAL QueryBuilder object ( $this-
>getEntityManager()->getConnection()->createQueryBuilder() ) and dene the basics of the array, including ltering by lead id and search
lter. Then pass the QueryBuilder object to the getTimelineResults() method along with the following arguments:
$query REQUIRED QueryBuilder DBAL QueryBuilder object dening basics of the query.
Name of the column (with table prex) that should be used when sorting by
$eventNameColumn REQUIRED string
event name
Name of the column (with table prex) that should be used when sorting by
$timestampColumn REQUIRED string
timestamp
When using DBAL, arrays are not auto unserialized by Doctrine. Dene the
$serializedColumns OPTIONAL array
columns here (as returned by the query results) to auto unserialize.
When using DBAL, datetime columns are not auto converted to \DateTime
$dateTimeColumns OPTIONAL array objects by Doctrine. Dene the columns here (as returned by the query
results) to auto do so.
Callback to custom parse a result. This is optional and mainly used to handle
$resultsParserCallback OPTIONAL callback a column result when all results are already being looped over for
$serializedColumns and $dateTimeColumns.
https://developer.mautic.org/#plugin-directory-structure 55/222
17/12/2017 Mautic Developer Documentation
EXTENDING EMAILS
<?php
// plugins/HelloWorldBundle/EventListener/EmailSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\EmailBundle\EmailEvents;
use Mautic\EmailBundle\Event\EmailBuilderEvent;
use Mautic\EmailBundle\Event\EmailSendEvent;
/**
* Class EmailSubscriber
*/
class EmailSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return array(
EmailEvents::EMAIL_ON_BUILD => array('onEmailBuild', 0),
EmailEvents::EMAIL_ON_SEND => array('onEmailGenerate', 0),
EmailEvents::EMAIL_ON_DISPLAY => array('onEmailGenerate', 0)
);
}
/**
* Register the tokens and a custom A/B test winner
*
* @param EmailBuilderEvent $event
*/
public function onEmailBuild(EmailBuilderEvent $event)
{
// Add email tokens
$content = $this->templating->render('HelloWorldBundle:SubscribedEvents\EmailToken:token.html.php');
$event->addTokenSection('helloworld.token', 'plugin.helloworld.header', $content);
/**
* Search and replace tokens with content
*
* @param EmailSendEvent $event
*/
public function onEmailGenerate(EmailSendEvent $event)
{
// Get content
$content = $event->getContent();
https://developer.mautic.org/#plugin-directory-structure 56/222
17/12/2017 Mautic Developer Documentation
There are two way to extend emails: email tokens used to insert dynamic content into an email and a/b test winning criteria . Both leverage
the \Mautic\EmailBundle\EmailEvents::EMAIL_ON_BUILD event. Read more about listeners and subscribers.
EMAIL TOKENS
Email tokens are placeholders that are inserted into an email that can be replaced by dynamic content when the email is sent or viewed in
the browser.
$event->addTokenSection($uniqueId, $headerTranslationKey, $htmlContent) is used to generate the section for drag and drop tokens in
the email builder.
$headerTranslationKey is the translation key that will be used to create the sections header.
$htmlContent is the HTML that will be inserted into the builders token list for this tokens section. $this->templating->render() can be
used to render a specic views content (using view notation. There is free reign as to what the HTML will look like but the important part is
that the elements representing the tokens must have the attribute data-token="{token_text}" in order for the builder to recognize them.
For example, <a href="#" data-token="{hello}" class="btn btn-default btn-block">Translated Token Text</a>
To convert the token into a link while requesting what the links text should be, use the attributes data-token='<a href="%url=
{hello}%">%text%</a>' data-drop="showBuilderLinkModal" (replacing hello with the plugins custom token).
To request simple feedback from the user and inject it into the token, use the attributes data-token='{hello=%world%}' data-drop="show
BuilderFeedbackModal" . A modal will appear with a simple input box. Whatever the user inputs will replace %world% .
If you need more control or more customization, create and dene a custom JS function within the Mautic namespace (i.e. Mautic.custom
Function and use the attribute data-drop="customFunction" . When a user drops the token, Mautic.customFunction() passing the
arguments event (jQuery Event), ui (jQuery UI object with draggable, helper, etc), editorId (ID of the inline CkEditor).
Mautic.insertBuilderEditorToken(editorId, token);
};
To add a custom an a/b test winner criteria, i.e. a test to compare specic aspects of an email to determine what made it more successful
over its variants, use $event->addAbTestWinnerCriteria($uniqueId, $parameters) .
group REQUIRED string Translation string to group criteria by in the dropdown select list
label OPTIONAL string Label for this option in the drop down list
https://developer.mautic.org/#plugin-directory-structure 57/222
17/12/2017 Mautic Developer Documentation
Static callback function that will be called to determine the winner when the email
callback REQUIRED mixed
detail page is viewed
formType OPTIONAL string The alias of a custom form type used to set cong options for the decision
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
The callback can accept the following variables (determined via ReectionMethod::invokeArgs()):
$parent Mautic\EmailBundle\Entity\Email Email entity for the parent of the email entity
The callback function should return an array keyed with the following elements:
Passed to the view dened by supportTemplate below in order to render visual support for the winners
support mixed
(such as a graph, etc)
View notation to render content for the A/B stats modal. For example,
supportTemplate string
HelloWorldBundle:SubscribedEvents\AbTest:graph.html.php
return array(
'winners' => $winners,
'support' => $support,
'supportTemplate' => 'HelloWorldBundle:SubscribedEvents\AbTest:graph.html.php'
);
<?php
// plugins/HelloWorldBundle/EventListener/MonitoredInboxSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\EmailBundle\EmailEvents;
use Mautic\EmailBundle\Event\MonitoredEmailEvent;
use Mautic\EmailBundle\Event\ParseEmailEvent;
use Mautic\EmailBundle\MonitoredEmail\Mailbox;
/**
* Class MonitoredInboxSubscriber
https://developer.mautic.org/#plugin-directory-structure 58/222
17/12/2017 Mautic Developer Documentation
*/
class MonitoredInboxSubscriber extends CommonSubscriber
{
private $bundle = 'HelloWorldBundle';
private $monitor = 'deep_space_emails';
/**
* @return array
*/
static public function getSubscribedEvents()
{
return [
EmailEvents::MONITORED_EMAIL_CONFIG => ['onConfig', 0],
EmailEvents::EMAIL_PRE_FETCH => ['onPreFetch', 0],
EmailEvents::EMAIL_PARSE => ['onParse', 0],
];
}
/**
* Inject the IMAP folder settings into the Configuration
*
* @param MonitoredEmailEvent $event
*/
public function onConfig(MonitoredEmailEvent $event)
{
/**
* The first argument is something unique to recognize this plugin.
* The second argument should be something unique to identify this monitored inbox.
* The third argument is the label for this monitored inbox.
*/
$event->addFolder($this->bundle, $this->monitor, 'mautic.world.monitored_deep_space_emails');
}
/**
* Inject search criteria for which messages to fetch from the configured folder.
*
* @param ParseEmailEvent $event
*/
public function onPreFetch(ParseEmailEvent $event)
{
$event->setCriteriaRequest($this->bundle, $this->monitor, Mailbox::CRITERIA_UNSEEN. " " . Mailbox::CRITERIA_FROM ." aliens@andromeda");
}
/**
* Parse the messages
*
* @param ParseEmailEvent $event
*/
public function onParse(ParseEmailEvent $event)
{
if ($event->isApplicable($this->bundle, $this->monitor)) {
$messages = $event->getMessages();
Plugins have access to hook into the mautic:email:fetch command to fetch email from a specic inbox/folder and process the content of
the message. Starting in 2.1.1, the plugin also has access to inject specic search criteria for the messages to be processed.
To do this, the plugin needs to add an event listener for three events:
1. EmailEvents::MONITORED_EMAIL_CONFIG This event is dispatched to inject the elds into Mautics Conguration to congure the IMAP
inbox and folder that should be monitored.
https://developer.mautic.org/#plugin-directory-structure 59/222
17/12/2017 Mautic Developer Documentation
2. EmailEvents::EMAIL_PRE_FETCH This event is dispatched during the execution of the mautic:email:fetch command. Its used to
inject search criteria for the messages desired.
3. EmailEvents::EMAIL_PARSE This event parses the messages fetched by the command.
EXTENDING FORMS
<?php
// plugins/HelloWorldBundle/EventListener/FormSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use MauticPlugin\HelloWorldBundle\HelloWorldEvents;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\FormBundle\Event as Events;
use Mautic\FormBundle\FormEvents;
/**
* Class FormSubscriber
*/
class FormSubscriber extends CommonSubscriber
{
/**
* {@inheritdoc}
*/
static public function getSubscribedEvents()
{
return array(
FormEvents::FORM_ON_BUILD => array('onFormBuilder', 0)
);
}
/**
* Add a simple email form
*
* @param FormBuilderEvent $event
*/
public function onFormBuilder(Events\FormBuilderEvent $event)
{
// Register a form submit actions
$event->addSubmitAction(
'helloworld.sendemail',
[
// Label to group by in the dropdown
'group' => 'plugin.helloworld.header',
https://developer.mautic.org/#plugin-directory-structure 60/222
17/12/2017 Mautic Developer Documentation
$event->addFormField(
'helloworld.customfield',
[
// Field label
'label' => 'plugin.helloworld.formfield.customfield',
Forms can be extended by listening to the \Mautic\FormBundle\FormEvents::FORM_ON_BUILD event. Read more about listeners and
subscribers.
FORM FIELDS
To add a custom form eld, use the $event->addFormField($identifier, $parameters) method. $identifier must be something unique.
The $parameters array can contain the following elements:
label REQUIRED string The language string for the option in the dropdown
formType REQUIRED string The alias of a custom form type used to set cong options
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
Callback function to use to validate the value; the function should accept the
valueConstraints OPTIONAL mixed
arguments \Mautic\FormBundle\Entity\Field $field and $filteredValue .
To add an action, use the $event->addSubmitAction($identifier, $parameters) method. $identifier must be something unique. The
$parameters array can contain the following elements:
label REQUIRED string The language string for the option in the dropdown
description OPTIONAL string The language string to use for the options tooltip
https://developer.mautic.org/#plugin-directory-structure 61/222
17/12/2017 Mautic Developer Documentation
This is the custom event name that will be dispatched to handle this action ( call
eventName REQUIRED string
back has been deprecated)
formType OPTIONAL string The alias of a custom form type used to set cong options
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
Static callback function called after a submission (submit action logic goes here).
callback DEPRECATED mixed
Deprecated - use eventName instead.
The subscriber registered to listen to the eventName will be passed an instance of Mautic\FormBundle\Events\SubmissionEvent with the
details about the post.
Sometimes, it is necessary to handle something after all the other submit actions have done their thing - like redirect to another page. This
is done by registering a post submit callback through the subscriber that processes the action. You can either inject the Symfony\Com
ponent\HttpFoundation\Response at that time with $event->setPostSubmitCallbackResponse($response); or register another custom event
to be dispatched after all submit actions have been processed using $event->setPostSubmitCallback($key, ['eventName' =>
HelloWorld::ANOTHER_CUSTOM_EVENT]); .
FORM VALIDATIONS
To add a custom validation, use the $event->addValidator($identifier, $parameters) method. $identifier must be something unique.
The $parameters array can contain the following elements:
eventName REQUIRED string The name of the custom event that will be dispatched to validate the form or specic eld
The key to a custom form type (for example something registered by addFormField() ) to limit this
eldType optional string
listener to. Otherwise every eld will be sent to listener.
The listener for the form event will receive a Mautic\FormBundle\Event\ValidationEvent object. Obtain the eld with $event->getField();
do the logic then to fail a validation, execute $event->failedValidation('I said so.'); .
EXTENDING INTEGRATIONS
<?php
<?php
// plugins\HelloWorldBundle\Integration\MarsIntegration
namespace MauticPlugin\HelloWorldBundle\Integration;
use Mautic\PluginBundle\Entity\Integration;
use Mautic\PluginBundle\Integration\AbstractIntegration;
use Mautic\PluginBundle\Helper\oAuthHelper;
/**
* Class MarsIntegration
*/
class MarsIntegration extends AbstractIntegration
{
https://developer.mautic.org/#plugin-directory-structure 62/222
17/12/2017 Mautic Developer Documentation
/**
* Returns the name of the social integration that must match the name of the file
* For example, IcontactIntegration would need Icontact here
*
* @return string
*/
public function getName()
{
return 'Mars';
}
/**
* Display name for the integration which defaults to getName() unless defined here
*/
public function getDisplayName()
{
return 'Red Mars'
}
/**
* Get the type of authentication required for this API. Values can be none, key, oauth2 or callback
* (will call $this->authenticationTypeCallback)
*
* @return string
*/
public function getAuthenticationType()
{
return 'oauth2';
}
/**
* OAuth2 authentication URL
*/
public function getAuthenticationUrl()
{
return 'https://somesite.com/oauth/authorize';
}
/**
* OAuth2 access token URL
*/
public function getAccessTokenUrl()
{
return 'https://somesite.com/oauth/access_token';
}
/**
* Get a list of supported features for this integration
*
* @return array
*/
public function getSupportedFeatures()
{
return array(
'public_profile',
'public_activity'
);
}
}
Integrating 3rd party services in Mautic can be done by dening an Integration class for the service. For example, the MauticSocialBundle
has several social media service classes dened in \Plugins\MauticSocialBundle\Integration. Each integration class handles the
authorization process, integration conguration, etc.
INTEGRATION CLASS
Each plugin can have multiple integrations by dening each as its own Integration class in the bundles Integration folder. The class should
extend \Mautic\PluginBundle\Integration\AbstractIntegration . It denes the integration and provides a number of helper functions
https://developer.mautic.org/#plugin-directory-structure 63/222
17/12/2017 Mautic Developer Documentation
including OAuth authorization/request signing functions.
INTEGRATION IMAGE
Each integration is displayed on a card in the Manage Plugins area. To set an image for the integration, include an image in the bundles
Assets\img. It should be 128x128px, be in a png, and have the same name as returned by getName() as lower case. For example, \Mau
ticPlugin\HelloWorldBundle\Integration\MarsIntegration should have an image plugins\HelloWorldBundle\Assets\img\mars.png .
AUTHORIZATION
Out of the box, the AbstractIntegration class can handle standard key, OAuth1a, and OAuth2 specications. The authorization type is
dened by the getAuthenticationType() function. Each input required by the user (i.e username, password, etc) are dened by an array of
keyName => label elements returned by getRequiredKeyFields() . This function is not required if using standard specs of key, OAuth1a, or
OAuth2.
FUNCTIONS
Some of the main functions used are described below. Review the AbstractIntegration class and the functions docblocks for more details.
Keys saved by the integration are encrypted. To access the unencrypted versions in the Integration class, use the array $this->keys .
Any of the functions dened in AbstractIntegration can be overridden per special needs of the specic Integration being implemented.
Returns an array of keyName => label elements for settings required from the user, i.e.
Auth getRequiredKeyFields username, password, client id, client secret, key, etc. Each element will be displayed as an
input in the integrations settings.
Auth & Used to dene the username for the integration. It defaults to client_id for authentication
getClientIdKey
Request type oauth2 and 'keyName for the keyName authentication type.
Auth & Used to dene the password for the integration. By default, only oauth2 uses this and
getClientSecretKey
Request returns 'client_secret.
Auth getAuthLoginUrl Denes the login URL for the oauth1a spec
Auth getRequestToken Used by the oauth1a spec to retrieve a request token during authorization
Auth getRequestTokenUrl Used by the oauth1a spec to dene the request token URL
Auth getAuthenticationUrl Denes the login URL for the oauth2 spec
Auth getAccessTokenUrl Denes the access token URL for the oauth2 spec
Used to dene the callback URL for oauth1a or oauth2 specs. This defaults to the
Auth getAuthCallbackUrl
mautic_integration_auth_callback route.
Auth getErrorsFromResponse Called by extractAuthKeys() to extract errors from the response into a string.
Auth & Called by makeRequest() to manipulate or prepare parameters, settings, headers, etc
prepareRequest
Request before sending to the URL
Auth &
parseCallbackResponse Called by makeRequest() to parse the response for the request into an array.
Request
https://developer.mautic.org/#plugin-directory-structure 64/222
17/12/2017 Mautic Developer Documentation
Auth & Returns the keyName thats used to sign a request. Used by oauth1a (oauth_token) and
getAuthTokenKey
Request oauth2 (access_token) specs.
General isCongured Called to determine if the integration has been correctly congured.
Called to determine if the integration is authorized (or peforms a reauth if an oauth2 spec
General isAuthorized
has refresh tokens stored)
Can be used to make API requests. It automatically handles standard key, oauth1a and
Request makeRequest
oauth2 specs.
Returns an array of options of what to display in integrations conguration form. The two
options used at this time is requires_callback (true to show a readonly input with the
Form getFormSettings
callback returned by getAuthCallbackUrl()) and requires_authorization (true to display
the authorization button).
Form getFormNotes Returns an array of helper notes to display in the various areas of the form.
MAKEREQUEST()
makeRequest() can be used to automatically sign outgoing requests and/or authentication processes. Of course, any integration can inherit
and override this class to suit the integrations needs. It accepts the following parameters:
An array of parameters to submit with the request. If $method is GET, these will be appended to the query
$parameters array
string. Otherwise, they will be part of the POST body.
$method string The request method i.e. get, post, put, patch, delete
$settings array Congures the behavior of the makeRequest function. Built in optional settings are below.
SETTINGS
auth_type string Overrides the authentication type for the request. If not set, getAuthenticationType() is used.
content_type string Sets the content type header for the request.
encode_parameters string If set to json, parameters in the POST will be json encoded prior to making the request.
return_raw bool If true, return the response rather than running it through parseCallbackResponse rst.
Used by prepareRequest() and parseCallbackResponse() to change the behavior based on whether the
authorize_session bool
if the request is obtaining authorization or just making an API call.
https://developer.mautic.org/#plugin-directory-structure 65/222
17/12/2017 Mautic Developer Documentation
EXTENDING MAINTENANCE CLEANUP
<?php
// plugins\HelloWorldBundle\EventListener\MaintenanceSubscriber
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Doctrine\DBAL\Connection;
use Mautic\CoreBundle\CoreEvents;
use Mautic\CoreBundle\Event\MaintenanceEvent;
use Mautic\CoreBundle\Factory\MauticFactory;
/**
* Class MaintenanceSubscriber
*/
class MaintenanceSubscriber extends CommonSubscriber
{
/**
* @var Connection
*/
protected $db;
/**
* MaintenanceSubscriber constructor.
*
* @param MauticFactory $factory
* @param Connection $db
*/
public function __construct(MauticFactory $factory, Connection $db)
{
parent::__construct($factory);
$this->db = $db;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
CoreEvents::MAINTENANCE_CLEANUP_DATA => ['onDataCleanup', -50]
];
}
/**
* @param $isDryRun
* @param $date
*
* @return int
*/
public function onDataCleanup (MaintenanceEvent $event)
{
$qb = $this->db->createQueryBuilder()
->setParameter('date', $event->getDate()->format('Y-m-d H:i:s'));
if ($event->isDryRun()) {
$rows = (int) $qb->select('count(*) as records')
->from(MAUTIC_TABLE_PREFIX.'worlds', 'w')
->where(
$qb->expr()->gte('w.date_added', ':date')
)
->execute()
->fetchColumn();
} else {
$rows = (int) $qb->delete(MAUTIC_TABLE_PREFIX.'worlds')
->where(
$qb->expr()->lte('date_added', ':date')
)
https://developer.mautic.org/#plugin-directory-structure 66/222
17/12/2017 Mautic Developer Documentation
->execute();
}
To hook into the mautic:maintenance:cleanup command, create a listening for the \Mautic\CoreBundle\CoreEvents::MAINTENANCE_CLEA
NUP_DATA event. The event listener should check if data should be deleted or a counted. Use $event->setStat($key, $affectedRows, $sql,
$sqlParameters) to give feedback to the CLI command. Note that $sql and $sqlParameters are only used for debugging and shown only
in the dev environment.
The plugin should check if a dry run is requested using `$event->isDryRun()` before deleting records!
<?php
// plugins/HelloWorldBundle/EventListener/PageSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\PageBundle\PageEvents;
use Mautic\PageBundle\Event\PageBuilderEvent;
use Mautic\PageBundle\Event\PageSendEvent;
/**
* Class PageSubscriber
*/
class PageSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return array(
PageEvents::PAGE_ON_BUILD => array('onPageBuild', 0),
PageEvents::PAGE_ON_DISPLAY => array('onPageDisplay', 0)
);
}
/**
* Register the tokens and a custom A/B test winner
*
* @param PageBuilderEvent $event
*/
public function onPageBuild(PageBuilderEvent $event)
{
// Add page tokens
$content = $this->templating->render('HelloWorldBundle:SubscribedEvents\PageToken:token.html.php');
$event->addTokenSection('helloworld.token', 'plugin.helloworld.header', $content);
https://developer.mautic.org/#plugin-directory-structure 67/222
17/12/2017 Mautic Developer Documentation
// Static callback function that will be used to determine the winner
'callback' => '\MauticPlugin\HelloWorldBundle\Helper\AbTestHelper::determinePlanetVisitWinner'
)
);
}
/**
* Search and replace tokens with content
*
* @param PageSendEvent $event
*/
public function onPageDisplay(PageSendEvent $event)
{
// Get content
$content = $event->getContent();
There are two way to extend pages: page tokens used to insert dynamic content into a page and a/b test winning criteria . Both leverage the
\Mautic\PageBundle\PageEvents::PAGE_ON_BUILD event. Read more about listeners and subscribers.
PAGE TOKENS
Custom landing page A/B test winner criteria is handled exactly the same as page A/B test winner criteria with the only differences being
that the callback function is passed Mautic\PageBundle\Entity\Page $page and Mautic\PageBundle\Entity\Page $parent instead. Of
course $children is an ArrayCollection of Page entities as well.
EXTENDING POINTS
Custom point actions and triggers can be added by listening to their respective on build events. Read more about listeners and subscribers.
POINT ACTIONS
To add a custom point action used to give a lead x points for doing a certain action, add a listener to the \Mautic\PointBundle\PointE
vents::POINT_ON_BUILD event then congure the custom point action with $event->addAction($identifier, $parameters) method. $iden
tifier must be something unique. The $parameters array can contain the following elements:
label REQUIRED string The language string for the option in the dropdown
formType OPTIONAL string The alias of a custom form type used to set cong options.
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
Static callback function used to validate the action. Return true to add the points to
callback OPTIONAL mixed
the lead.
In order for the custom point action to work, add something like the following in the code logic when the lead executes the custom action:
https://developer.mautic.org/#plugin-directory-structure 68/222
17/12/2017 Mautic Developer Documentation
$this->getModel('point')->triggerAction('page.hit', $event->getHit());
POINT TRIGGERS
To add a custom point trigger used to execute a specic action once a lead hits X number of points, add a listener to the \Mautic\Point
Bundle\PointEvents::TRIGGER_ON_BUILDevent then congure the custom point trigger with $event->addEvent($identifier, $parameters)
method. $identifier must be something unique. The $parameters array can contain the following elements:
label REQUIRED string The language string for the option in the dropdown
formType OPTIONAL string The alias of a custom form type used to set cong options.
formTypeOptions OPTIONAL array Array of options to include into the formTypes $options argument
formTypeCleanMasks OPTIONAL array Array of input masks to clean a values from formType
callback OPTIONAL mixed Static callback function used to execute the custom action.
EXTENDING REPORTS
<?php
// plugins\HelloWorldBundle\EventListener\ReportSubscriber
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\CoreBundle\Helper\GraphHelper;
use Mautic\ReportBundle\Event\ReportBuilderEvent;
use Mautic\ReportBundle\Event\ReportGeneratorEvent;
use Mautic\ReportBundle\Event\ReportGraphEvent;
use Mautic\ReportBundle\ReportEvents;
use Mautic\CoreBundle\Helper\Chart\ChartQuery;
use Mautic\CoreBundle\Helper\Chart\LineChart;
/**
* Class ReportSubscriber
*/
class ReportSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents ()
{
return array(
ReportEvents::REPORT_ON_BUILD => array('onReportBuilder', 0),
ReportEvents::REPORT_ON_GENERATE => array('onReportGenerate', 0),
ReportEvents::REPORT_ON_GRAPH_GENERATE => array('onReportGraphGenerate', 0)
);
}
/**
* Add available tables, columns, and graphs to the report builder lookup
*
* @param ReportBuilderEvent $event
*
* @return void
*/
public function onReportBuilder (ReportBuilderEvent $event)
https://developer.mautic.org/#plugin-directory-structure 69/222
17/12/2017 Mautic Developer Documentation
{
// Use checkContext() to determine if the report being requested is this report
if ($event->checkContext(array('worlds'))) {
// Define the columns that are available to the report.
$prefix = 'w.';
$columns = array(
$prefix . 'visit_count' => array(
'label' => 'mautic.hellobundle.report.visit_count',
'type' => 'int'
),
$prefix . 'world' => array(
'label' => 'mautic.hellobundle.report.world',
'type' => 'text'
),
);
// Several helper functions are available to append common columns such as categories, publish state fields, lead, etc. Refer to the Report
BuilderEvent class for more details.
$columns = $filters = array_merge($columns, $event->getStandardColumns($prefix), $event->getCategoryColumns());
// Optional to override and update filters, i.e. change it to a select list for the UI
$filters[$prefix.'world']['type'] = 'select';
$filters[$prefix.'world']['list'] = array(
'earth' => 'Earth',
'mars' => 'Mars'
);
/**
* Initialize the QueryBuilder object used to generate the report's data.
* This should use Doctrine's DBAL layer, not the ORM so be sure to use
* the real schema column names (not the ORM property names) and the
* MAUTIC_TABLE_PREFIX constant.
*
* @param ReportGeneratorEvent $event
*
* @return void
*/
public function onReportGenerate (ReportGeneratorEvent $event)
{
$context = $event->getContext();
if ($context == 'worlds') {
$qb = $event->getQueryBuilder();
$event->setQueryBuilder($qb);
}
}
/**
* Generate the graphs
*
* @param ReportGraphEvent $event
*
* @return void
https://developer.mautic.org/#plugin-directory-structure 70/222
17/12/2017 Mautic Developer Documentation
*/
public function onReportGraphGenerate (ReportGraphEvent $event)
{
if (!$event->checkContext('worlds')) {
return;
}
$graphs = $event->getRequestedGraphs();
$qb = $event->getQueryBuilder();
switch ($graph) {
case 'mautic.hellobundle.graph.line.visits':
$chart = new LineChart(null, $options['dateFrom'], $options['dateTo']);
$chartQuery->modifyTimeDataQuery($queryBuilder, 'date_added', 'v');
$visits = $chartQuery->loadAndBuildTimeData($queryBuilder);
$chart->setDataset($options['translator']->trans('mautic.hellobundle.graph.line.visits'), $visits);
$data = $chart->render();
$data['name'] = $graph;
$data['iconClass'] = 'fa-tachometer';
$event->setGraph($graph, $data);
break;
}
}
}
}
Adding and rendering custom reports are done by listening to the \Mautic\ReportBundle\ReportEvents::REPORT_ON_BUILD ,
ReportEvents::REPORT_ON_GENERATE and ReportEvents::REPORT_ON_GRAPH_GENERATE events.
Dening the report is done through the ReportEvents::REPORT_ON_BUILD event. This is where the plugin will dene the context of the report,
available columns for table data, available lters for the table data (defaults to columns) and available graphs. See the code examples on
ReportBuilder for details.
COLUMN DEFINITION
alias OPTIONAL string An alias for the returned value. Useful in conjuction with formula
formula OPTIONAL string SQL formula instead of a column. e.g. SUBSTRING_INDEX(e.type, \'.\', 1)
Route name to convert the value into a hyperlink. Used usually with an ID of an Entity. The route
link OPTIONAL string
must accept objectAction and objectId parameters.
FILTER DEFINITION
Filter denitions are optional as Mautic will default to the column list. But sometimes its useful to replace lter values with a select list. Filter
denitions can accept the same properties as columns but can also accept the following:
https://developer.mautic.org/#plugin-directory-structure 71/222
17/12/2017 Mautic Developer Documentation
Used when type is select for a lter. Provides the dropdown options for a select input. Format
list OPTIONAL array
should be value => label
The ReportEvents::REPORT_ON_GENERATE event is dispatched when a report is to be generated and displayed. In this function, the plugin
should dene the QueryBuilder object used to generate the table data.
Note that the ReportEvents::REPORT_ON_GENERATE event should use Doctrines DBAL layer QueryBuilder obtained via $qb =
$event->getQueryBuilder(); .
There are a number of helper functions to append joins for commonly used relationships such as category, leads, ip address, etc. Refer to
the ReportGeneratorEvent class for more details.
GRAPHS
Graphs are generated using ReportEvents::REPORT_ON_GRAPH_GENERATE event. The listener should check the context then generate and set
the graph data. There are several classes to assist with generating classes. See
EXTENDING WEBHOOKS
Webhooks allow for Mautic to send data to external services via an endpoint url.
ADDITIONAL STEPS
Additional steps that you must take in your own bundle are:
1. Create your own event dispatching for your bundles custom event and payload
2. Register your custom event listeners in your bundles conguration le as a service.
3. Refer to receiving webhooks section to receive payloads in your application.
<?php
namespace Mautic\YourBundle\EventListener;
use Mautic\WebhookBundle\WebhookEvents;
use Mautic\WebhookBundle\Event\WebhookBuilderEvent;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\YourBundle\YourBundleEvents;
/**
* Class WebhookSubscriber
*
* @package Mautic\YourBundle\EventListener
*/
https://developer.mautic.org/#plugin-directory-structure 72/222
17/12/2017 Mautic Developer Documentation
/**
* Add event triggers and actions
*
* @param WebhookBuilderEvent $event
*/
public function onWebhookBuild(WebhookBuilderEvent $event)
{
// add checkbox to the webhook form for new leads
$type = array(
'label' => 'mautic.bundlename.webhook.event.type.new',
'description' => 'mautic.bundlename.webhook.event.type.new_desc', // note: we don't currently use a description, but may in the future so we
have supported it here
);
// Note: you may create multiple arrays and call the $event->addEvent method multiple times
// in this function to add several types all at once.
}
}
?>
Add an event listener for the WebhookEvents::WEBHOOK_ON_BUILD event, call the addEvent method and pass it an argument for your payload
event constant, and an array of a label and a description to be added to the Webhook user interface.
YourBundle::ACTION_TO_TRIGGER is a constant that should be an event registered in your bundle. We use the constant to save the type in
the database and query for later. You will use the same constant later, so its important to be consistent.
Add an event listener which extends the WebhookSubscriberBase class. This event should be dispatched in your bundle when you
wish to create a payload.
<?php
namespace Mautic\YourBundle\EventListener;
use Mautic\WebhookBundle\EventListener\WebhookSubscriberBase;
// you should change this to the event type that you are going to use.
// in our case it will be a lead event.
use Mautic\LeadBundle\Event\LeadEvent;
use JMS\Serializer\Serializer;
https://developer.mautic.org/#plugin-directory-structure 73/222
17/12/2017 Mautic Developer Documentation
use Mautic\CoreBundle\Factory\MauticFactory;
use Doctrine\ORM\NoResultException;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\LeadBundle\Event\PointsChangeEvent;
use Mautic\ApiBundle\Serializer\Exclusion\PublishDetailsExclusionStrategy;
/**
* Class LeadSubscriber
*
* @package Mautic\Webhook\EventListener
*/
class LeadSubscriber extends WebhookSubscriberBase
{
/**
* @return array
*/
static public function getSubscribedEvents ()
{
return array(
// note this is the same constant we would have used in the addEvent() listener!
LeadEvents::LEAD_POST_SAVE => array('onLeadNewUpdate', 0)
)
}
/*
* Generic method to execute when a lead does something
*/
public function onLeadNewUpdate(LeadEvent $event)
{
// serializer groups are defined and optionally used in your bundle's entity.
// Use these format your payload in JSON formats.
$serializerGroups = array("leadDetails", "userList", "publishDetails", "ipAddress");
// again please note the use of the constant here - this should be consistent with the constant we register to the webhook form
$webhookEvents = $this->getEventWebooksByType(LeadEvents::LEAD_POST_SAVE);
// The webhook model is made available because we've extended the WebhookSubscriberBase class.
$this->webhookModel->QueueWebhooks($webhookEvents, $payload, $serializerGroups);
}
}
}
The next step is to add an event listener for the action you want to actually use for creating payloads. This could be anything you want, your
bundle will have to have an event type and use the event dispatcher to execute the event.
Here is an example listener to create a lead payload whenever a new lead is added to Mautic.
You can add the listener to any bundle. Be sure to register it in your bundles cong.php le.
The event constant that you return in the getSubscriberEvents() method should match the event type from the previous listener.
This is used in a database query, so it must match exactly for the payload to be included in the hook POST to the endpoint URL.
https://developer.mautic.org/#plugin-directory-structure 74/222
17/12/2017 Mautic Developer Documentation
You can refer to the model for more documentation on the QueueWebhooks method. In short you want to pass the event entities that this
payload is being queued against The payload, which is an array, and nally the serializer groups for formatting the JSON.
This should complete the set up, registering and executing custom webhook events and payloads.
Webhooks enable Mautic to send data for leads, points, and email opens to outside applications. It does this by taking an outside
applications endpoint url, and sending an HTTP post request to that location. In that post we include the relevant data the the event that
has been red.
To listen to the webhook posts, developers should create a publicly accessible endpoint location in their application. That endpoint should
be available to receive a POST request from Mautic. The contents of the payload will vary based on the events that the user wishes to
include in the payload.
An excellent way of testing to see the data that will be included is using Requestb.in. Requestb.in allows users to view the full contents of
the hook payload. Developers can refer to a post to the bin to see the contents and craft the way their application receives that input
accordingly.
EXTENDING UI
INJECTING BUTTONS
<?php
// plugins/HelloWorldBundle/Event/ButtonSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\CoreEvents;
use Mautic\CoreBundle\Event\CustomButtonEvent;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\CoreBundle\Templating\Helper\ButtonHelper;
use Mautic\LeadBundle\Entity\Lead;
/**
* @param CustomButtonEvent $event
*/
public function injectViewButtons(CustomButtonEvent $event)
{
// Injects a button into the toolbar area for any page with a high priority (displays closer to first)
$event->addButton(
[
'attr' => [
'class' => 'btn btn-default btn-sm btn-nospin',
'data-toggle' => 'ajaxmodal',
'data-target' => '#MauticSharedModal',
'href' => $this->router->generate('mautic_world_action', ['objectAction' => 'doSomething']),
'data-header' => 'Extra Button',
],
'tooltip' => $this->translator->trans('mautic.world.dosomething.btn.tooltip'),
https://developer.mautic.org/#plugin-directory-structure 75/222
17/12/2017 Mautic Developer Documentation
'iconClass' => 'fa fa-star',
'priority' => 255,
],
ButtonHelper::LOCATION_TOOLBAR_ACTIONS
);
//
if ($lead = $event->getItem()) {
if ($lead instanceof Lead) {
$sendEmailButton = [
'attr' => [
'data-toggle' => 'ajaxmodal',
'data-target' => '#MauticSharedModal',
'data-header' => $this->translator->trans(
'mautic.world.dosomething.header',
['%email%' => $event->getItem()->getEmail()]
),
'href' => $this->router->generate(
'mautic_world_action',
['objectId' => $event->getItem()->getId(), 'objectAction' => 'doSomething']
),
],
'btnText' => 'Extra Button',
'iconClass' => 'fa fa-star',
'primary' => true,
'priority' => 255,
];
// Inject a button into the page actions for the specified route (in this case /s/contacts/view/{contactId})
$event
->addButton(
$sendEmailButton,
// Location of where to inject the button; this can be an array of multiple locations
ButtonHelper::LOCATION_PAGE_ACTIONS,
['mautic_contact_action', ['objectAction' => 'view']]
)
// Inject a button into the list actions for each contact on the /s/contacts page
->addButton(
$sendEmailButton,
ButtonHelper::LOCATION_LIST_ACTIONS,
'mautic_contact_index'
);
}
}
}
}
As of Mautic 2.3.0, support for plugins to inject buttons throughout Mautics UI has been added by listening to the CoreEvents::VIEW_IN
JECT_CUSTOM_BUTTONS event.
Location Description
https://developer.mautic.org/#plugin-directory-structure 76/222
17/12/2017 Mautic Developer Documentation
Location Description
Buttons use a priority system to determine order. The higher the priority, the closer to rst the button is displayed. The lower the priority, the
closer to last. For a button dropdown, setting a button as primary will display the button in the button group rather than the dropdown.
The array dening the button can include the following keys:
attr array Array of attributes to be appended to the button (data attributes, href, etc)
iconClass string Font Awesome class to use as the icon within the button
primary boolean For button dropdown formats, this will display the button in the group rather than in the dropdown
Determines the order of buttons. Higher the priority, closer to the rst the button will be placed. Buttons with the
priority int
same priority wil be ordered alphabetically.
If a button is to display a conrmation modal, the key confirm can be used. A confirm array can have the following keys:
cancelCallback string Mautic namespaced Javascript method to be executed when the cancel button is clicked
conrmCallback string Mautic namespaced Javascript method to be executed when the conrm button is clicked
precheck string Mautic namespaced Javascript method to be executed prior to displaying the conrmation modal
https://developer.mautic.org/#plugin-directory-structure 77/222
17/12/2017 Mautic Developer Documentation
On the same nested level as the confirm key can include primary and/or priority .
<?php
$dropdownOpenHtml = '<button type="button" class="btn btn-default btn-nospin dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa
fa-caret-down"></i></button>'
."\n";
$dropdownOpenHtml .= '<ul class="dropdown-menu dropdown-menu-right" role="menu">'."\n";
A plugin can dene its own locations that other plugins can leverage by using the template buttons helper.
Type Description
Miscellaneous
FLASH MESSAGES
<?php
$this->addFlash(
'mautic.translation.key',
array('%placeholder%' => 'some text'),
'notice', // Notification type
'flashes', // Translation domain
$addNotification // Add a notification entry
);
<?php
// From within a model or other service with access to the translator and session services
$translatedString = $this->translator->trans(,
array(
'%placeholder%' => 'some text'
),
'flashes'
https://developer.mautic.org/#plugin-directory-structure 78/222
17/12/2017 Mautic Developer Documentation
);
$this->session->getFlashBag()->add('notice', $translatedString);
To create an alert, aka ash message, you can use the ash bag in the session.
If your controller extends one of Mautics common controllers, you can simply use the helper function addFlash() .
From a model, or any service, you can use the session to obtain the ash bag.
$flashBag = $this->get('session')->getFlashBag();
NOTIFICATIONS
<?php
// From within a controller
<?php
// From within a model or other service that has access to the mautic.core.model.notification service
Mautic also has a notication center. By default, addFlash() will also add a notication to the center. But, a message can be manually added
as well.
Controllers can use the helper function while models and other services can obtain the NoticationModel.
HELPERS
Mautic has many helper classes available. A few of the most commonly used ones are highlighted below.
INPUT HELPER
The input helper can be used to ensure clean strings from user input.
<?php
use \Mautic\CoreBundle\Helper\InputHelper;
// ...
$clean = InputHelper::clean($input);
$clean = InputHelper::int($input);
$clean = InputHelper::alphanum($input);
$clean = InputHelper::html($input);
DATE/TIME HELPER
The date/time helper can be used to convert between UTC and the local timezone.
<?php
https://developer.mautic.org/#plugin-directory-structure 79/222
17/12/2017 Mautic Developer Documentation
CHARTQUERY AND GRAPHS
There are several classes available to assist with generating chart data.
<?php
use Mautic\CoreBundle\Helper\Chart\LineChart;
use Mautic\CoreBundle\Helper\Chart\ChartQuery;
CHARTQUERY
ChartQuery is a helper class to get the chart data from the database. Instantiate it with the Doctrine connection object, date from and date
to. Those dates must be instances of the DateTime class. ChartQuery will automatically guess the time unit (hours, days, weeks, months or
years) based on the items between the date range. However, if you want to receive the data from a specic time unit, pass it as the fourth
parameter (H, d, W, m, Y).
ChartQuery also lls in the missing items (if any) which is required to display the data properly in the line chart generated by the ChartJS.
LINECHART
LineChart is used in Mautic to display a date/time related data where the time is on the horizontal axis and the values are in the vertical
axis. ChartJS line charts can display multiple datasets in one chart. Instantiate the LineChart with a unit (null for unit guessing), from date,
to date (the same as for the ChartQuery) and a date format (null for automatically generated date format).
All the params you need to instantiate the LineChart are used to generate the labels of the horizontal axis. To add the dataset to the
LineChart object, use the setDataset($label, $data) method where the label is string and data is an array generated by the ChartQuery.
The color of each dataset will be generated automatically.
Call the render() method to get the data prepared for ChartJS.
PIECHART
A PieChart can be instantiated simply by new PieChart() . To add a dataset, use again the setDataset($label, $value) method where the
label is a string and value is integer.
Call the render() method to get the data prepared for ChartJS.
BARCHART
BarChart is used to display different variants of the same value where the variants are in the horizontal axis and the value is in vertical axis.
To create a bar chart, use new BarChart($labels) where labels is an array of all the variants. Each variant can have multiple datasets. To
add a dataset, use the setDataset($label, $data, $order) method where the label is string, data is array of values for each variant. Order
can be used to move the dataset before already created dataset.
Call the render() method to get the data prepared for ChartJS.
<?php echo $view->render('MauticCoreBundle:Helper:chart.html.php', array('chartData' => $data, 'chartType' => 'line', 'chartHeight' => 300)); ?>
FRONTEND
At the frontend, simply use the prepared chart template, pass in the chart data, the chart type (line/bar/pie) and the chart height. The width
is responsive.
COMMANDS
https://developer.mautic.org/#plugin-directory-structure 80/222
17/12/2017 Mautic Developer Documentation
Support for new CLI commands can be added using Symfonys console component.
MODERATED COMMANDS
<?php
// plugins\HelloWorldBundle\Command\WorldCommand.php
namespace MauticPlugin\HelloWorldBundle\Command;
use Mautic\CoreBundle\Command\ModeratedCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* CLI Command to send a scheduled broadcast.
*/
class WorldCommand extends ModeratedCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
// ...
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// Validate if the command is already has an instance running
// A third argument can be passed here if this command is running something unique such as an ID
if (!$this->checkRunStatus($input, $output)) {
return 0;
}
return 0;
}
}
Mautic provide an method for moderating commands meaning it will only allow one instance to run at a time. To utilize this method, extend
the Mautic\CoreBundle\Command\ModeratedCommand class.
FORMS
Mautic leverages Symfonys Form component and form classes. Refer to Symfonys documentation for more information.
FORM TYPES
As stated in Symfonys documentation referenced above, form type classes are the best way to go. Mautic makes it easy to register form
type services through the bundles cong le. Refer to the Services section.
DATA SANITIZATION
https://developer.mautic.org/#plugin-directory-structure 81/222
17/12/2017 Mautic Developer Documentation
<?php
// plugins/HelloWorldBundle/Form/Type/WorldType.php
// ...
use Mautic\CoreBundle\Form\EventListener\CleanFormSubscriber;
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventSubscriber(
new CleanFormSubscriber(
[
'content' => 'html',
'customHtml' => 'html'
]
)
);
// ...
}
// ...
Form data is not automatically sanitized. Mautic provides a form event subscriber to handle this.
The array provided to CleanFormSubscriber should contain the names of the form elds as keys and the values the masks to use to sanitize
the data. Any un-specied form eld will use the clean mask by default.
MANIPULATING FORMS
A form event listener must be used if a form needs to be manipulated based on submitted data such as changing dened elds, adjust
constraints, or changing select choices based on submitted values. Refer to Symfonys documentation on this.
VALIDATING DATA
<?php
// plugins/HelloWorldBundle/Entity/World.php
// ...
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Form\Form;
// ...
/**
* @param ClassMetadata $metadata
*/
public static function loadValidatorMetadata (ClassMetadata $metadata)
{
$metadata->addPropertyConstraint(
'name',
new NotBlank(
array(
'message' => 'mautic.core.name.required'
)
)
);
$metadata->addPropertyConstraint(
https://developer.mautic.org/#plugin-directory-structure 82/222
17/12/2017 Mautic Developer Documentation
'population',
new NotBlank(
array(
'message' => 'mautic.core.value.required',
'groups' => array('VisitedWorld')
)
)
);
}
/**
* @param Form $form
*
* @return array
*/
public static function determineValidationGroups (Form $form)
{
$data = $form->getData();
$groups = array('AllWorlds');
return $groups;
}
// ...
If the underlying data of a form is an Entity object, a static method loadValidatorMetadata can be dened in the Entity class. This will
automatically be called when Symfony is processing form data.
A form can also use validation_groups to change the order of data to be validated or only validate if certain criteria is true. For example,
only validate a password conrmation eld if the rst password eld passes validation. When registering a validation group in the form type
class, one can use static callback that can be used to determine what validation group(s) should be used.
<?php
// plugins/HelloWorldBundle/Form/Type/WorldType.php
//...
/**
* {@inheritdoc}
*/
public function setDefaultOptions (OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MauticPlugin\HelloWorld\Entity\World',
'validation_groups' => array(
'MauticPlugin\HelloWorld\Entity\World',
'determineValidationGroups',
)
));
}
// ...
USING CONSTRAINTS
A form type service can also register constraints when dening the form elds.
<?php
// plugins/HelloWorldBundle/Form/Type/WorldType.php
// ...
https://developer.mautic.org/#plugin-directory-structure 83/222
17/12/2017 Mautic Developer Documentation
use Symfony\Component\Validator\Constraints\NotBlank;
// ...
// ...
EVENTS
<?php
// plugins\HelloWorldBundle\EventListener\LeadSubscriber
namespace MauticPlugin\HelloWorldBundle\EventListener;
/**
* Class LeadSubscriber
*
* @package Mautic\LeadBundle\EventListener
*/
class LeadSubscriber extends CommonSubscriber
{
/**
* @return array
*/
static public function getSubscribedEvents()
{
return array(
LeadEvents::LEAD_POST_SAVE => array('onLeadPostSave', 0),
LeadEvents::LEAD_POST_DELETE => array('onLeadDelete', 0)
);
}
// do something
}
https://developer.mautic.org/#plugin-directory-structure 84/222
17/12/2017 Mautic Developer Documentation
$deletedId = $lead->deletedId;
// do something
}
}
Mautic leverages Symfonys EventDispatcher to execute and communicate various actions through Mautic. Plugins can hook into these to
extend the functionality of Mautic. Refer to Extending Mautic for some of the ways to do this.
SUBSCRIBERS
The easiest way to listen to various events is to use an event subscriber. Read more about subscribers in Symfonys documentation.
Plugin event subscribers can extend \Mautic\CoreBundle\EventListener\CommonSubscriber which gives access to commonly used
dependencies and also allows registering the subscriber service through the bundless cong le. But, it does not have to and instead See
Services for more information on registering event services.
AVAILABLE EVENTS
There are many events available throughout Mautic. Depending on the desired functionality, look at the core bundles *Event.php le in the
root of the bundle. For example, Lead related events are dened and described in app\bundles\LeadBundle\LeadEvents.php . These nal
classes provide the names of the events to listen to. Always use the event constants to ensure future changes to event names will not break
the plugin.
CUSTOM EVENTS
<?php
// plugins\HelloWorldBundle\HelloWorldEvents.php
namespace MauticPlugin\HelloWorldBundle;
/**
* Class HelloWorldEvents
*/
final class HelloWorldEvents
{
/**
* The helloworld.armageddon event is dispatched when a world is doomed by a giant meteor
*
* The event listener receives a MauticPlugin\HelloWorldBundle\Event\ArmageddonEvent instance.
*
* @var string
*/
const ARMAGEDDON = 'helloworld.armageddon';
}
1) Class dening the available events for the plugin using a final class with constants
<?php
// plugins\HelloWorldBundle\Event\ArmageddonEvent.php
namespace MauticPlugin\HelloWorldBundle\Event;
use MauticPlugin\HelloWorldBundle\Entity\World;
class ArmageddonEvent
{
/** @var World */
protected $world;
https://developer.mautic.org/#plugin-directory-structure 85/222
17/12/2017 Mautic Developer Documentation
/** @var bool */
protected $falseAlarm = false;
2) The Event class that is received by the listeners. This class should extend Symfony\Component\EventDispatcher\Event . It will be created
when the event is dispatched and should have any information listeners need to act on it.
<?php
$dispatcher = $this->get('event_dispatcher');
if ($dispatcher->hasListeners(HelloWorldEvents::ARMAGEDDON)) {
$event = $dispatcher->dispatch(HelloWorldEvents::ARMAGEDDON, new ArmageddonEvent($world));
if ($event->shouldPanic()) {
throw new \Exception("Run for the hills!");
}
}
3) The code that dispatches the event where appropriate using the event_dispatcher service.
Mautic has some helper methods with adding support for translated content to an entity.
\MAUTIC\COREBUNDLE\ENTITY\TRANSLATIONINTERFACE
This Entity interface ensures that everything is needed in order for Mautic to handle translations correctly for an entity.
\MAUTIC\COREBUNDLE\ENTITY\TRANSLATIONENTITYTRAIT
This trait provides properties needed to dene an Entitys language and relationships to other items. In the Entitys loadMetadata() method,
be sure to call $this->addTranslationMetadata() .
\MAUTIC\COREBUNDLE\TRANSLATIONMODELTRAIT
This trait provides the method getTranslatedEntity() that will determine the entity to use as the translation based on the $lead and/or the
HTTP_ACCEPT_LANGUAGE header. It also has a postTranslationEntitySave() that should be called at the end of the Entitys saveEntity()
method.
\MAUTIC\COREBUNDLE\DOCTRINE\TRANSLATIONMIGRATIONTRAIT
To ease the generation of schema to match the Entity, use this trait then execute $this->addTranslationSchema() .
Add a locale and translatedParent form elds like the code example.
https://developer.mautic.org/#plugin-directory-structure 86/222
17/12/2017 Mautic Developer Documentation
<?php
// plugins/HelloWorldPlugin/Form/Type/WorldType.php
$builder->add(
'language',
'locale',
array(
'label' => 'mautic.core.language',
'label_attr' => array('class' => 'control-label'),
'attr' => array(
'class' => 'form-control',
'tooltip' => 'mautic.page.form.language.help',
),
'required' => false,
'empty_data' => 'en'
)
);
Mautic has some helper methods with adding support for creating variants of a given entity. This becomes particularly useful for A/B testing.
\MAUTIC\COREBUNDLE\ENTITY\VARIANTINTERFACE
This Entity interface ensures that everything is needed in order for Mautic to handle the variants correctly for an entity.
\MAUTIC\COREBUNDLE\ENTITY\VARIANTENTITYTRAIT
This trait provides properties needed to dene an Entitys relationship to other items. In the Entitys loadMetadata() method, be sure to call
$this->addVariantMetadata() .
\MAUTIC\COREBUNDLE\VARIANTMODELTRAIT
This trait provides the methods preVariantSaveEntity() , postVariantSaveEntity() and convertVariant() . preVariantSaveEntity()
should be executed prior to saveEntity then postVariantSaveEntity() . See example.
<?php
// plugins/HelloWorldBundle/Model/WorldModel.php
parent::saveEntity($entity, $unlock);
https://developer.mautic.org/#plugin-directory-structure 87/222
17/12/2017 Mautic Developer Documentation
\MAUTIC\COREBUNDLE\DOCTRINE\VARIANTMIGRATIONTRAIT
To ease the generation of schema to match the Entity, use this trait then execute $this->addVariantSchema() .
Add variantParent elds like the code example. In the example, the variantParent value is set in the controller due to a Add A/B Test
button is clicked. The specic use for the plugin may require a select list rather than a hidden eld. Change this to meet the codes needs.
<?php
// plugins/HelloWorldPlugin/Form/Type/WorldType.php
Themes
Custom themes for public facing areas of Mautic can be generated but require a bit of Twig experience.
The themes use the same templating formats as Symfonys twig templates.
themes/blank/
- - - cong.json
- - - thumbnail.png
- - - html/
- - - - - - base.html.twig
- - - - - - email.html.twig
- - - - - - form.html.twig
- - - - - - message.html.twig
- - - - - - page.html.twig
https://developer.mautic.org/#plugin-directory-structure 88/222
17/12/2017 Mautic Developer Documentation
subfolder. You can download an existing theme via the Theme Manager to see an example ZIP le.
features array Array of features the theme supports. Options currently are email, form, and/or page
Theme Thumbnail
The thumbnail should be a screenshot of the theme with demo content. The width x height should be 575 x 600 px. This thumbnail will be
available for Mautic users for quick theme preview in the Email edit form, Landing Page edit form and the Theme Manager.
Mautic will be look for thumbnail.png for default but if you want a specic image for your [email, page, form] template you can add a
thumbnail_feature.png.
Example
email thumbnail_email.png
form thumbnail_form.png
page thumbnail_page.png
Slots
SLOT DEFINITION
The slot can be dened by a single HTML attribute data-slot="{slot type here}" . For example, the text slot can be dened even with the
demo content.
When the theme is opened in the builder, the div with attribute data-slot="text" will make the text inside the div editable within the inline
Froala editor.
Example:
https://developer.mautic.org/#plugin-directory-structure 89/222
17/12/2017 Mautic Developer Documentation
<div data-slot=text>
<a>@JaneDoe</a> has invited you to join Awesome inc!
</div>
IMAGE
Inserts a single image into the div. User can click on it and edit it with options which provides Froala editor (link, change image source, alt
text, )
BUTTON
Inserts a HTML button. User can dene text, URL as well as padding, size and position.
TEXT
Inserts a new text slot which you can edit with a HTML editor, so you can insert even media like images and videos in it.
SEPARATOR
SLOT CONTAINERS
As stated before, users can drag & drop the new slots into the theme. So as a theme developer, you have to dene where the user can drop
the slots. You can do it again with a single HTML attribute data-slot-container="1" .
Example:
<div data-slot-container="1">
<div data-slot=text>
<a>@JaneDoe</a> has invited you to join Awesome inc!
</div>
</div>
This way the builder will let users drop the new slots into this container. In the example above there is already one predened slot which
user can move to another container, remove or edit.
This functionality will provide you with lots of creative freedom for designing and developing your own unique email and landing pages.
Have a unique design? Share it with the community! We would love to see how youre using Mautic to engage your audience.
Sections
Sections are full width parts of the theme which can let user to change the background color in the section wrapper (full monitor width) and
in the section content itself. Since Mautic 2.7.0 its possible to move the sections up or down, delete the sections and even create a new
ones with layout of 1,2 or 3 columns.
SECTION
The section holds the content. It should be centered and should have xed width. This xed width should be consistent with all other
sections. Section also wraps the content. The section can be any block HTML element with attribute data-section="1" .
Example:
<div data-section="1">
<div data-slot-container="1">
<div data-slot=text>
https://developer.mautic.org/#plugin-directory-structure 90/222
17/12/2017 Mautic Developer Documentation
<a>@JaneDoe</a> has invited you to join Awesome inc!
</div>
</div>
</div>
SECTION WRAPPER
Section wrapper must have 100% width of the browser window. You thus have to split your theme into several rows if you want to enable
the users to change the background of each section. The section wrapper can be any block HTML element with attribute data-section-
wrapper .
Example:
<div data-slot-container="1">
<div data-section="1">
<div data-slot-container="1">
<div data-slot=text>
<a>@JaneDoe</a> has invited you to join Awesome inc!
</div>
</div>
</div>
</div>
EMAIL.HTML.TWIG
{# themes/HelloBundle/html/email.html.twig #}
<html>
<head>
<title>{subject}</title>
</head>
<body style="margin:0">
<div data-section-wrapper="1">
<center>
<table data-section="1" style="width: 600;" width="600" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<div data-slot-container="1" style="min-height: 30px">
<div data-slot="text">
<br>
<h2>Hello there!</h2>
<br>
We haven't heard from you for a while...
<br>
<br>
{unsubscribe_text} | {webview_text}
<br>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</center>
</div>
</body>
https://developer.mautic.org/#plugin-directory-structure 91/222
17/12/2017 Mautic Developer Documentation
</html>
This le denes the document for building an email template. Of course this le should follow html based email etiquette. Throughout the
document should be output for the slots dened as data attributes.
FORM.HTML.TWIG
{# themes/thellotheme/html/form.html.twig #}
{% extends ":"~template~":base.html.twig" %}
{% block content %}
{% if message is defined %}
<div>
<h2>{{ message|raw }}</h2>
</div>
{% endif %}
<div>
{% if header is defined %}
<h4>{{ header }}</h4>
{% endif %}
{{ content|raw }}
</div>
{% endblock %}
This le generates the html document for a form when viewed via its public URL. This does not style the elds of a form. That will be
described below.
To provide custom form eld templates or to manipulate the form body, create the following directory structure:
themes/HelloWorld/
- - - html/
- - - - - - MauticFormBundle
- - - - - - - - - Builder < for customizing the form structure itself
- - - - - - - - - Field < for customizing form eld types
Copy from app/bundles/FormBundle/Views/Builder/form.html.php in the themes Builder directory or one or more of the elds templates in
app/bundles/FormBundle/Views/Field/*.html.php into the themes Field directory. Then customize to the desired layout. Note that these
must be PHP templates.
The embedded forms can be styled by the themes/{your theme name}/html/MauticFormBundle/Builder/style.html.twig le. The best way
is to copy the content of the default form styles and modify them to your needs.
MESSAGE.HTML.TWIG
{# themes/hellotheme/html/message.html.twig #}
{% extends ":"~template~":base.html.twig" %}
{% block content %}
<div>
<h2>{{ message|raw }}</h2>
{% if content is defined %}
<div>{{ content|raw }}</div>
{% endif %}
https://developer.mautic.org/#plugin-directory-structure 92/222
17/12/2017 Mautic Developer Documentation
</div>
{% endblock %}
This le is a simple message le mainly used as the landing page for when a lead unsubscribes or resubscribes to the systems emails. But
may be used by other areas so should be included in all themes.
It requires echo'ing two variables: message and content . message houses the string message such as You have been unsubscribed
content will either be empty or house the HTML of a form thats been associated with the email as an unsubscribe form.
PAGE.HTML.TWIG
{# themes/hellotheme/html/message.html.twig #}
{% extends ":"~template~":base.html.twig" %}
{% block content %}
<!DOCTYPE html>
<html>
<head>
{% if page is defined %}
<title>{pagetitle}</title>
<meta name="description" content="{pagemetadescription}">
{% endif %}
{{ outputHeadDeclarations() }}
</head>
<body>
{{ outputScripts('bodyOpen') }}
{% block content %}{% endblock %}
{{ outputScripts('bodyClose') }}
</body>
</html>
{% endblock %}
page.html.twig is exactly the same as email.html.twig except that itll be used for landing pages instead. Thus, it can be more robust with the
HTML document.
REST API
Mautic provides a REST API to manipulate leads and/or obtain information for various entities of Mautic.
All Mautic API endpoints require an OAuth1a signtature or OAuth2 access token.
Error Handling
If an OAuth error is encountered, itll be a JSON encoded array similar to:
{
"error": "invalid_grant",
"error_description": "The access token provided has expired."
}
https://developer.mautic.org/#plugin-directory-structure 93/222
17/12/2017 Mautic Developer Documentation
{
"error": {
"message": "You do not have access to the requested area/action.",
"code": 403
}
}
$version will be in a semantic versioning format: [major].[minor].[patch] . For example: 2.4.0 . If youll try it on the latest GitHub
version, the version will have -dev at the end. Like 2.5.1-dev .
Authorization
Mautic uses OAuth or Basic Authentication (as of Mautic 2.3.0) for API authorization. It supports both OAuth 1a and OAuth 2; however, as
of 1.1.2, the administrator of the Mautic instance must choose one or the other. Of course OAuth 2 is only recommended for servers
secured behind SSL. Basic authentication must be enabled in Conguration -> API Settings.
The Mautic administrator should enable the API in the Conguration -> API Settings. This will add the API Credentials to the admin menu.
A client/consumer ID and secret should then be generated which will be used in the following processes.
All authorization requests should be made to the specic Mautic instances URL, i.e. https://your-mautic.com .
The OAuth processes can be a pain. If possible, its best to use an OAuth library for the language being used. If PHP, it is
recommended that Mautics PHP library be used.
OAUTH 1A
<?php
use Mautic\Auth\ApiAuth;
https://developer.mautic.org/#plugin-directory-structure 94/222
17/12/2017 Mautic Developer Documentation
// Initiate the auth object
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
// Initiate process for obtaining an access token; this will redirect the user to the authorize endpoint and/or set the tokens when the user is redirected
back after granting authorization
if ($auth->validateAccessToken()) {
if ($auth->accessTokenUpdated()) {
$accessTokenData = $auth->getAccessTokenData();
The OAuth 1a method is recommended for servers that are not behind https. Note that OAuth 1a access tokens do not expire.
OAuth 1a can be a complicated method due to the need to generate a signature for the request. If anything is off with the signature, the
request will not be validated.
AUTHORIZATION
The rst step is to obtain a request token that will be used when directing the user to the authorization page.
POST /oauth/v1/request_token
Authorization:
OAuth oauth_callback="https%3A%2F%2Fyour-callback-uri.com",
oauth_consumer_key="CONSUMER_KEY",
oauth_nonce="UNIQUE_STRING",
oauth_signature="GENERATED_REQUEST_SIGNATURE",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_version="1.0"
Review Generating the Authorization Header on the specics of generating the OAuth header.
oauth_token=REQUEST_TOKEN&oauth_token_secret=REQUEST_TOKEN_SECRET&oauth_expires_in=3600
Parse the string and use the parameters in the next step as indicated.
These must be preserved in some kind of persistent storage as they will be used when obtaining the access token.
Note that the refresh token is only good for the number of seconds specied in oauth_expires_in .
Now redirect the user to the authorization endpoint oauth/v1/authorize with the request token as part of the URLs query.
If the callback is something different than what is congured in Mautic, url encode it and include in the query as oauth_callback .
/oauth/v1/authorize?oauth_token=REQUEST_TOKEN&oauth_callback=https%3A%2F%2Fyour-callback-uri.com
https://developer.mautic.org/#plugin-directory-structure 95/222
17/12/2017 Mautic Developer Documentation
The user will login and Mautic will redirect back to the either the consumers congured callback or to the oauth_callback included in the
query.
The callback will include oauth_token and oauth_verifier in the URLs query.
Compare the oauth_token in the query with that obtained in step two to ensure they are the same and prevent cross-site request forgery.
Generate the Authorization header and make a POST to the access token endpoint /oauth/v1/access_token .
When generating the header, the oauth_token_secret returned in step two should be used as the TOKEN_SECRET in the composite key.
oauth_verifier from step two should be part of the Authorization header generated.
POST /oauth/v1/access_token
Authorization:
OAuth oauth_callback="https%3A%2F%2Fyour-callback-uri.com",
oauth_consumer_key="CONSUMER_KEY",
oauth_nonce="UNIQUE_STRING",
oauth_signature="GENERATED_REQUEST_SIGNATURE",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_verifier="OAUTH_VERIFIER_FROM_STEP_TWO"
oauth_version="1.0"
The response should include a query string with the access token:
oauth_token=ACCESS_TOKEN&oauth_token_secret=ACCESS_TOKEN_SECRET
Mautics OAuth 1a access tokens do not expire but the user can deauthorize them. If the access token is invalid, a `401` response
will be returned.
The oauth_token can be included in the authorize header and the oauth_token_secret should be used as the TOKEN_SECRET in the
composite key when signing API requests.
Key Description
Optional, URL encoded callback to redirect the user to after authorization. If the callback URL is set in
oauth_callback
Mautic, this must match.
oauth_signature Signature generated from all applicable data for the request
oauth_signature_method Method for creating the signature. Currently, only HMAC-SHA1 is supported.
https://developer.mautic.org/#plugin-directory-structure 96/222
17/12/2017 Mautic Developer Documentation
Key Description
oauth_verier Returned after authorization and used when requesting an access token
When making a GET or POST request with parameters, all parameters should be included in the header as well.
METHOD&URL_ENCODED_URI&NORMALIZED_PARAMETERS
URL_ENCODED_URI should be the base URI the request is made to. It should not include any query parameters (query parameters should be
part of NORMALIZED_PARAMETERS ).
NORMALIZED_PARAMETERS should be a url encoded, alphabetically sorted query string of the above oauth parameters (except oauth_signa
ture ) plus the parameters of the request (query/post body).
Each key and each value of the parameters must be url encoded individually as well.
Then each url encoded key/value pair should be concatenated into a single string with an ampersand (&) as the glue character.
For example, lets say a request includes a query of title=Mr&firstname=Joe&lastname=Smith . The process would look something like the
following (replacing urlencode() with whatever function is appropriate for the language being used). Of course realistically, natural sort and
loop functions would be used.
urlencode(
urlencode(firstname)=urlencode(Joe)
&urlencode(lastname)=urlencode(smith)
&urlencode(oauth_callback)=urlencode(https%3A%2F%2Fyour-callback-uri.com)
&urlencode(oauth_consumer_key)=urlencode(kdjafs7fsdf86ads7a98a87df6ad9fsf98ad7f)
&urlencode(oauth_nonce)=urlencode(ak877asdf6adf68asd9fas)
&urlencode(oauth_signature_method)=urlencode(HMAC-SHA1)
&urlencode(oauth_timestamp)=urlencode(1437604736)
&urlencode(oauth_version)=urlencode(1.0)
&urlencode(title)=urlencode(Mr)
)
Multidimensional arrays should use foo=baz&foo=bar rather than foo[bar]=baz&foo[baz]=bar when generating the normalized
parameters string.
https://developer.mautic.org/#plugin-directory-structure 97/222
17/12/2017 Mautic Developer Documentation
GET&http%3A%2F%2Fyour-mautic.com%2Fapi&firstname%3DJoe%26lastName%3DSmith%26oauth_callback%3Dhttps%253A%252F%252Fyour-call
back-uri.com%26oauth_consumer_key%3Dkdjafs7fsdf86ads7a98a87df6ad9fsf98ad7f%26oauth_nonce%3Dak877asdf6adf68asd9fas%26oauth_
signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1437604736%26oauth_version%3D1.0%26title%3DMr
The composite key is used to encrypt the base string. It is composed of the consumer secret and the token secret if available (post
authorization) combined with an ampersand (&).
CLIENT_SECRET&TOKEN_SECRET
If the token secret is not available, i.e. during the request token process, then an ampersand (&) should still be used.
CLIENT_SECRET&
TOKEN_SECRET Sources
For /oauth/v1/request_token , TOKEN_SECRET is empty.
For /oauth/v1/access_token , TOKEN_SECRET will be the oauth_token_secret returned by the request to /oauth/v1/request_token
For all other API endpoints, TOKEN_SECRET will be the oauth_token_secret returned by the request to /oauth/v1/access_token
Now, using the base string and the composite key, the signature can be generated using the appropriate HMAC function available to the
language used. The signature generated should then be base64 encoded prior to being used in the Authorization header.
base64_encode(
hmac_sha1(BASE_STRING, COMPOSITE_KEY)
)
The resulting string should then be used included in the header as oauth_signature .
To sign the API request, generate the Authorization header using the obtained access token.
POST /api/leads/new
Authorization:
OAuth oauth_callback="https%3A%2F%2Fyour-callback-uri.com",
oauth_consumer_key="CONSUMER_KEY",
oauth_nonce="UNIQUE_STRING",
oauth_signature="GENERATED_REQUEST_SIGNATURE",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_token="ACCESS_TOKEN"
oauth_version="1.0"
https://developer.mautic.org/#plugin-directory-structure 98/222
17/12/2017 Mautic Developer Documentation
title=Mr&firstname=Joe&lastname=Smith
OAUTH 2
<?php
use Mautic\Auth\ApiAuth;
// Initiate process for obtaining an access token; this will redirect the user to the authorize endpoint and/or set the tokens when the user is redirected
back after granting authorization
if ($auth->validateAccessToken()) {
if ($auth->accessTokenUpdated()) {
$accessTokenData = $auth->getAccessTokenData();
AUTHORIZATION
GET /oauth/v2/authorize?
client_id=CLIENT_ID
&grant_type=authorization_code
&redirect_uri=https%3A%2F%2Fyour-redirect-uri.com%2Fcallback
&response_type=code
&state=UNIQUE_STATE_STRING
The state is optional but recommended to prevent CSRF attacks. It should be a uniquely generated string and stored locally in
session, cookie, etc. to be compared with the returned value.
https://developer.mautic.org/#plugin-directory-structure 99/222
17/12/2017 Mautic Developer Documentation
The user will be prompted to login. Once they do, Mautic will redirect back to the URL specied in redirect_uri with a code appended to the
query.
The state returned should be compared against the original to ensure nothing has been tampered with.
Obtain the value of the code from Step One then immediately POST it back to the access token endpoint oauth/v2/token with:
POST /oauth/v2/token
client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&grant_type=authorization_code
&redirect_uri=https%3A%2F%2Fyour-redirect-uri.com%2Fcallback
&code=UNIQUE_CODE_STRING
(note that the post body has been wrapped for legibility)
{
access_token: "ACCESS_TOKEN",
expires_in: 3600,
token_type: "bearer",
scope: "",
refresh_token: "REFRESH_TOKEN"
}
This data should be stored in a secure location and used to authenticate API requests.
REFRESH TOKENS
The responses expires_in is the number of seconds the access token is good for and may differ based on what is congured in Mautic.
The code handling the authorization process should generate an expiration timestamp based on that value. For example <?php $expira
tion = time() + $response['expires_in']; ?> . If the access token has expired, the refresh_token should be used to obtain a new access
token.
The refresh token is by default good for 14 days in which the user will need to reauthorize the application with Mautic. However, the refresh
tokens expiration time is congurable through Mautics Conguration.
The application should monitor for a 400 Bad Response response when requesting a new access token and redirect the user back
through the authorization process.
To obtain a new access token, a POST should be made to the access tokens endpoint oauth/v2/token using the refresh_token grant
type.
POST /oauth/v2/token
client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&grant_type=refresh_token
https://developer.mautic.org/#plugin-directory-structure 100/222
17/12/2017 Mautic Developer Documentation
&refresh_token=REFRESH_TOKEN
&redirect_uri=https%3A%2F%2Fyour-redirect-uri.com%2Fcallback
(note that the post body has been wrapped for legibility)
{
access_token: "NEW_ACCESS_TOKEN",
expires_in: 3600,
token_type: "bearer",
scope: "",
refresh_token: "REFRESH_TOKEN"
}
Authenticating the API request with OAuth2 is easy. Choose one of the following methods that is appropriate for the applications needs.
AUTHORIZATION HEADER
However, note that this method requires that the server Mautic is installed on passes headers to PHP or has access to the apache_re
quest_headers() function. apache_request_headers() is not available to PHP running under fcgi.
METHOD SPECIFIC
The access token can also be appended to the query or included in the body of a POST.
GET https://your-mautic.com/api/leads?access_token=ACCESS_TOKEN
POST https://your-mautic.com/api/leads/new
firstname=John&lastname=Smith&access_token=ACCESS_TOKEN
BASIC AUTHENTICATION
As of Mautic 2.3.0, support for basic authentication can be enabled through Mautics Conguration -> API Settings. As with OAuth2, it is
only recommended to use basic authentication over HTTPS.
1. Combine the username and password of a Mautic user with a colon : . For example, user:password .
2. Base64 encode the string from above. dXNlcjpwYXNzd29yZA== .
3. Add an Authorization header to each API request as Authorization: Basic dXNlcjpwYXNzd29yZA==
Libraries
PHP LIBRARY
Mautic provides a PHP library on Github. It is recommended that it be used in PHP projects. Other languages will need to use custom
means and/or a 3rd party library to handle the OAuth/request processes.
https://developer.mautic.org/#plugin-directory-structure 101/222
17/12/2017 Mautic Developer Documentation
INSTALL VIA COMPOSER
INSTALL MANUALLY
Download the package from Github. Extract then include the following code in your project (of course change the le path if needed):
Refer to the README in the Github repository for further instructions on how to use the library or review the code examples
included throughout this section.
Endpoints
Assets
Use this endpoint to obtain details on Mautics assets.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$assetApi = $api->newApi("assets", $auth, $apiUrl);
GET ASSET
<?php
//...
$asset = $assetApi->get($id);
HTTP REQUEST
GET /assets/ID
https://developer.mautic.org/#plugin-directory-structure 102/222
17/12/2017 Mautic Developer Documentation
RESPONSE
Asset Properties
modiedByUser string Name of the user that last modied the asset
LIST ASSETS
<?php
// ...
HTTP REQUEST
https://developer.mautic.org/#plugin-directory-structure 103/222
17/12/2017 Mautic Developer Documentation
GET /assets
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
CREATE ASSET
<?php
/**
* Local asset example
*/
// Upload a local file first
$apiContextFiles = $this->getContext('files');
$apiContextFiles->setFolder('assets');
$fileRequest = array(
'file' => dirname(__DIR__).'/'.'mauticlogo.png'
);
$response = $apiContextFiles->create($fileRequest);
$data = array(
'title' => 'Mautic Logo sent as a API request',
'storageLocation' => 'local',
'file' => $response['file']['name']
);
$asset = $assetApi->create($data);
/**
* Remote asset example
*/
$data = array(
'title' => 'PDF sent as a API request',
'storageLocation' => 'remote',
'file' => 'https://www.mautic.org/media/logos/logo/Mautic_Logo_DB.pdf'
);
$asset = $assetApi->create($data);
https://developer.mautic.org/#plugin-directory-structure 104/222
17/12/2017 Mautic Developer Documentation
Create a new asset. There are 2 options: local or remote asset.
HTTP REQUEST
POST /assets/new
Post Parameters
Name Description
title string
storageLocation string
le string
RESPONSE
Properties
EDIT ASSET
<?php
$id = 1;
$data = array(
'type' => 'general',
);
Edit a new asset. Asset that this supports PUT or PATCH depending on the desired behavior.
PUT creates a asset if the given ID does not exist and clears all the asset information, adds the information from the request. PATCH fails if
the asset with the given ID does not exist and updates the asset eld values with the values form the request.
HTTP REQUEST
PATCH /assets/ID/edit
To edit a asset and create a new one if the asset is not found:
PUT /assets/ID/edit
Post Parameters
Name Description
title string
storageLocation string
le string
https://developer.mautic.org/#plugin-directory-structure 105/222
17/12/2017 Mautic Developer Documentation
RESPONSE
If PUT , the expected response code is 200 if the asset was edited or 201 if created.
Properties
DELETE ASSET
<?php
$asset = $assetApi->delete($id);
Delete a asset. In case of local storage location, the local le will be deleted as well.
HTTP REQUEST
DELETE /assets/ID/delete
RESPONSE
Properties
Campaigns
Use this endpoint to obtain details on Mautics campaigns.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$campaignApi = $api->newApi("campaigns", $auth, $apiUrl);
GET CAMPAIGN
<?php
//...
$campaign = $campaignApi->get($id);
HTTP REQUEST
GET /campaigns/ID
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 106/222
17/12/2017 Mautic Developer Documentation
Expected Response Code: 200
Campaign Properties
modiedByUser string Name of the user that last modied the campaign
events array Array of Event entities for the campaign. See below.
Event Properties
order int Order in relation to the other events (used for levels)
triggerDate datetime/null Date/time of when the event should trigger if triggerMode is date
https://developer.mautic.org/#plugin-directory-structure 107/222
17/12/2017 Mautic Developer Documentation
Interval unit for when the event should trigger. Options are i = minutes, h = hours, d = days, m =
triggerIntervalUnit string
months, y = years
If the event is connected into an action, this will be no for the non-decision path or yes for the
decisionPath string/null
actively followed path.
LIST CAMPAIGNS
<?php
// ...
HTTP REQUEST
GET /campaigns
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
This endpoint is basically an alias for the stats endpoint with campaign_leads table and campaign_id specied. Other parameters are the
same as in the stats endpoint.
<?php
// ...
https://developer.mautic.org/#plugin-directory-structure 108/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
GET /campaigns/ID/contacts
Query Parameters
RESPONSE
CREATE CAMPAIGN
<?php
$data = array(
'name' => 'Campaign A',
'description' => 'This is my first campaign created via API.',
'isPublished' => 1
);
$campaign = $campaignApi->create($data);
Create a new campaign. To see more advanced example with campaing events and so on, see the unit tests.
HTTP REQUEST
POST /campaigns/new
Post Parameters
Name Description
alias string
isPublished A value of 0 or 1
RESPONSE
Properties
EDIT CAMPAIGN
<?php
$id = 1;
$data = array(
'name' => 'New campaign name',
'isPublished' => 0
);
https://developer.mautic.org/#plugin-directory-structure 109/222
17/12/2017 Mautic Developer Documentation
Edit a new campaign. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a campaign if the given ID does not exist and clears all the campaign information, adds the information from the request.
PATCH fails if the campaign with the given ID does not exist and updates the campaign eld values with the values form the request.
HTTP REQUEST
PATCH /campaigns/ID/edit
To edit a campaign and create a new one if the campaign is not found:
PUT /campaigns/ID/edit
Post Parameters
Name Description
isPublished A value of 0 or 1
RESPONSE
If PUT , the expected response code is 200 if the campaign was edited or 201 if created.
Properties
DELETE CAMPAIGN
<?php
$campaign = $campaignApi->delete($id);
Delete a campaign.
HTTP REQUEST
DELETE /campaigns/ID/delete
RESPONSE
Properties
<?php
//...
$response = $campaignApi->addContact($campaignId, $contactId);
if (!isset($response['success'])) {
https://developer.mautic.org/#plugin-directory-structure 110/222
17/12/2017 Mautic Developer Documentation
// handle error
}
HTTP REQUEST
POST /campaigns/CAMPAIGN_ID/contact/CONTACT_ID/add
RESPONSE
<?php
//...
$response = $listApi->removeContact($contactId, $listId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
POST /campaigns/CAMPAIGN_ID/contact/CONTACT_ID/remove
RESPONSE
Categories
Use this endpoint to obtain details on Mautics categories or to manipulate category memberships.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$categoryApi = $api->newApi("categories", $auth, $apiUrl);
GET CATEGORY
<?php
//...
$category = $categoryApi->get($id);
https://developer.mautic.org/#plugin-directory-structure 111/222
17/12/2017 Mautic Developer Documentation
Get an individual category by ID.
HTTP REQUEST
GET /categories/ID
RESPONSE
Category Properties
modiedByUser string Name of the user that last modied the category
<?php
//...
$categories = $categoryApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
Returns a list of contact categories available to the user. This list is not lterable.
HTTP REQUEST
GET /categories
RESPONSE
Category Properties
https://developer.mautic.org/#plugin-directory-structure 112/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the category
CREATE CATEGORY
<?php
$data = array(
'categoryname' => 'test',
'categoryemail' => '[email protected]',
'categorycity' => 'Raleigh',
);
$category = $categoryApi->create($data);
HTTP REQUEST
POST /categories/new
Post Parameters
Name Description
title string
bundle string
RESPONSE
Properties
https://developer.mautic.org/#plugin-directory-structure 113/222
17/12/2017 Mautic Developer Documentation
EDIT CATEGORY
<?php
$id = 1;
$data = array(
'title' => 'test',
'bundle' => 'asset'
);
Edit a new category. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a category if the given ID does not exist and clears all the category information, adds the information from the request. PATCH
fails if the category with the given ID does not exist and updates the category eld values with the values form the request.
HTTP REQUEST
PATCH /categories/ID/edit
To edit a category and create a new one if the category is not found:
PUT /categories/ID/edit
Post Parameters
Name Description
title string
bundle string
RESPONSE
If PUT , the expected response code is 200 if the category was edited or 201 if created.
Properties
DELETE CATEGORY
<?php
$category = $categoryApi->delete($id);
Delete a category.
HTTP REQUEST
DELETE /categories/ID/delete
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 114/222
17/12/2017 Mautic Developer Documentation
Properties
Companies
Use this endpoint to obtain details on Mautics companies or to manipulate contact-company memberships.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$companyApi = $api->newApi("companies", $auth, $apiUrl);
GET COMPANY
<?php
//...
$company = $companyApi->get($id);
HTTP REQUEST
GET /companies/ID
RESPONSE
Company Properties
modiedByUser string Name of the user that last modied the company
https://developer.mautic.org/#plugin-directory-structure 115/222
17/12/2017 Mautic Developer Documentation
<?php
//...
$companies = $companyApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
Returns a list of contact companies available to the user. This list is not lterable.
HTTP REQUEST
GET /companies
RESPONSE
Company Properties
modiedByUser string Name of the user that last modied the company
CREATE COMPANY
<?php
$data = array(
'companyname' => 'test',
'companyemail' => '[email protected]',
'companycity' => 'Raleigh',
);
$company = $companyApi->create($data);
HTTP REQUEST
POST /companies/new
https://developer.mautic.org/#plugin-directory-structure 116/222
17/12/2017 Mautic Developer Documentation
Post Parameters
Name Description
companyname Company name is the only required eld. Other company elds can be sent with a value
isPublished A value of 0 or 1
RESPONSE
Properties
EDIT COMPANY
<?php
$id = 1;
$data = array(
'companyname' => 'test',
'companyemail' => '[email protected]',
'companycity' => 'Raleigh',
);
Edit a new company. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a company if the given ID does not exist and clears all the company information, adds the information from the request.
PATCH fails if the company with the given ID does not exist and updates the company eld values with the values form the request.
HTTP REQUEST
PATCH /companies/ID/edit
To edit a company and create a new one if the company is not found:
PUT /companies/ID/edit
Post Parameters
Name Description
companyname Company name is the only required eld. Other company elds can be sent with a value
isPublished A value of 0 or 1
RESPONSE
If PUT , the expected response code is 200 if the company was edited or 201 if created.
Properties
https://developer.mautic.org/#plugin-directory-structure 117/222
17/12/2017 Mautic Developer Documentation
Same as Get Company.
DELETE COMPANY
<?php
$company = $companyApi->delete($id);
Delete a company.
HTTP REQUEST
DELETE /companies/ID/delete
RESPONSE
Properties
<?php
//...
$response = $companyApi->addContact($companyId, $contactId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
POST /companies/COMPANY_ID/contact/CONTACT_ID/add
RESPONSE
<?php
//...
$response = $companyApi->removeContact($contactId, $companyId);
if (empty($response['success'])) {
// handle error
}
HTTP REQUEST
POST /companies/COMPANY_ID/contact/CONTACT_ID/remove
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 118/222
17/12/2017 Mautic Developer Documentation
Contacts
Use this endpoint to manipulate and obtain details on Mautics contacts.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$contactApi = $api->newApi("contacts", $auth, $apiUrl);
GET CONTACT
<?php
//...
$contact = $contactApi->get($id);
HTTP REQUEST
GET /contacts/ID
RESPONSE
** Contact Properties **
modiedByUser string Name of the user that last modied the contact
lastActive datetime/null Date/time for when the contact was last recorded as active
https://developer.mautic.org/#plugin-directory-structure 119/222
17/12/2017 Mautic Developer Documentation
Hex value given to contact from Point Trigger denitions based on the number of points the contact
color string
has been awarded
Array of all contact elds with data grouped by eld group. See JSON code example for format. This
elds array
array includes an all key that includes an single level array of eldAlias => contactValue pairs.
LIST CONTACTS
<?php
//...
$contacts = $contactApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
HTTP REQUEST
GET /contacts
** Query Parameters **
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
** Properties **
CREATE CONTACT
<?php
$data = array(
'firstname' => 'Jim',
'lastname' => 'Contact',
'email' => '[email protected]',
'ipAddress' => $_SERVER['REMOTE_ADDR']
);
$contact = $contactApi->create($data);
https://developer.mautic.org/#plugin-directory-structure 120/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
POST /contacts/new
** Post Parameters **
Name Description
* Any contact eld alias can be posted as a parameter. For example, rstname, lastname, email, etc.
Date/time in UTC; preferablly in the format of Y-m-d H:m:i but if that format fails, the string will be sent through PHPs
lastActive
strtotime then formatted
RESPONSE
** Properties **
EDIT CONTACT
<?php
$id = 1;
$data = array(
'email' => '[email protected]',
'ipAddress' => $_SERVER['REMOTE_ADDR']
);
Edit a new contact. Note that this supports PUT or PATCH depending on the desired behavior.
** PUT ** creates a contact if the given ID does not exist and clears all the contact information, adds the information from the request.
PATCH fails if the contact with the given ID does not exist and updates the contact eld values with the values form the request.
HTTP REQUEST
PATCH /contacts/ID/edit
To edit a contact and create a new one if the contact is not found:
PUT /contacts/ID/edit
** Post Parameters **
Name Description
* Any contact eld alias can be posted as a parameter. For example, rstname, lastname, email, etc.
https://developer.mautic.org/#plugin-directory-structure 121/222
17/12/2017 Mautic Developer Documentation
Name Description
Date/time in UTC; preferably in the format of Y-m-d H:m:i but if that format fails, the string will be sent through PHPs
lastActive
strtotime then formatted
RESPONSE
If PUT , the expected response code is 200 if the contact was edited or 201 if created.
** Properties **
DELETE CONTACT
<?php
$contact = $contactApi->delete($id);
Delete a contact.
HTTP REQUEST
DELETE /contacts/ID/delete
RESPONSE
** Properties **
<?php
$data = array(
'eventName' => 'Score via api',
'actionName' => 'Adding',
);
$contactApi->addDnc($contactId, $channel, $reason, $channelId, $comments);
HTTP REQUEST
PATCH /contacts/ID/dnc/add/CHANNEL
Name Description
https://developer.mautic.org/#plugin-directory-structure 122/222
17/12/2017 Mautic Developer Documentation
Name Description
Int value of the reason. Use Contacts constants: Contacts::UNSUBSCRIBED, Contacts::BOUNCED, Contacts::MANUAL.
reason
Default is Manual
RESPONSE
<?php
$contactApi->addDnc($contactId, $channel);
HTTP REQUEST
PATCH /contacts/ID/dnc/remove/CHANNEL
Name Description
RESPONSE
ADD POINTS
<?php
$data = array(
'eventName' => 'Score via api',
'actionName' => 'Adding',
);
$contactApi->addPoints($contactId, $pointDelta, $data);
HTTP REQUEST
To add points to a contact and return a 404 if the lead is not found:
POST /contacts/ID/points/plus/POINTS
Name Description
https://developer.mautic.org/#plugin-directory-structure 123/222
17/12/2017 Mautic Developer Documentation
RESPONSE
SUBTRACT POINTS
<?php
$data = array(
'eventname' => 'Score via api',
'actionname' => 'Subtracting',
);
$contactApi->subtractPoints($contactId, $pointDelta, $data);
HTTP REQUEST
To subtract points from a contact and return a 404 if the contact is not found:
POST /contacts/ID/points/minus/POINTS
Name Description
RESPONSE
<?php
$owners = $contactApi->getOwners();
Get a list of owners that can be used to assign contacts to when creating/editing.
HTTP REQUEST
GET /contacts/list/owners
RESPONSE
** Owner Properties **
https://developer.mautic.org/#plugin-directory-structure 124/222
17/12/2017 Mautic Developer Documentation
<?php
$fields = $contactApi->getFieldList();
HTTP REQUEST
GET /contacts/list/fields
RESPONSE
** Field Properties **
alias string Field alias used as the column name in the database
<?php
HTTP REQUEST
GET /contacts/ID/notes
** Query Parameters **
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
** Note Properties **
https://developer.mautic.org/#plugin-directory-structure 125/222
17/12/2017 Mautic Developer Documentation
type string Type of note. Options are general, email, call, meeting
<?php
$segments = $contactApi->getContactSegments($id);
HTTP REQUEST
GET /contacts/ID/segments
RESPONSE
** List Properties **
dateAdded datetime Date/time string for when the contact was added to the list
manuallyAdded bool True if the contact was manually added to the list versus being added by a lter
manuallyRemoved bool True if the contact was manually removed from the list even though the lists lter is a match
See Segements.
<?php
$campaigns = $contactApi->getContactCampaigns($id);
HTTP REQUEST
GET /contacts/ID/campaigns
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 126/222
17/12/2017 Mautic Developer Documentation
** List Properties **
dateAdded datetime Date/time string for when the contact was added to the campaign
manuallyAdded bool True if the contact was manually added to the campaign versus being added by a contact list
True if the contact was manually removed from the campaign when the contacts list is assigned to the
manuallyRemoved bool
campaign
listMembership array Array of contact list IDs this contact belongs to that is also associated with this campaign
See Campaigns.
<?php
** Query Parameters **
Name Description
id Contact ID
orderBy Column to sort by. Can use any column listed in the response.
HTTP REQUEST
GET /contacts/ID/events
RESPONSE
** List Properties **
https://developer.mautic.org/#plugin-directory-structure 127/222
17/12/2017 Mautic Developer Documentation
timestamp timestamp Date and time when the event was created
<?php
$events = $contactApi->getActivityForContact($id, $search, $includeEvents, $excludeEvents, $orderBy, $orderByDir, $page, $dateFrom, $dateTo);
** Query Parameters **
Name Description
id Contact ID
lters[dateFrom] Date from lter. Must be type of \DateTime for the PHP API libary and in format Y-m-d H:i:s for HTTP param
lters[dateTo] Date to lter. Must be type of \DateTime for the PHP API libary and in format Y-m-d H:i:s for HTTP param
orderBy Column to sort by. Can use any column listed in the response.
HTTP REQUEST
https://developer.mautic.org/#plugin-directory-structure 128/222
17/12/2017 Mautic Developer Documentation
GET /contacts/ID/activity
RESPONSE
** List Properties **
timestamp timestamp Date and time when the event was created
<?php
** Query Parameters **
Name Description
lters[dateFrom] Date from lter. Must be type of \DateTime for the PHP API libary and in format Y-m-d H:i:s for HTTP param
lters[dateTo] Date to lter. Must be type of \DateTime for the PHP API libary and in format Y-m-d H:i:s for HTTP param
orderBy Column to sort by. Can use any column listed in the response.
https://developer.mautic.org/#plugin-directory-structure 129/222
17/12/2017 Mautic Developer Documentation
Name Description
HTTP REQUEST
GET /contacts/events
RESPONSE
** List Properties **
timestamp timestamp Date and time when the event was created
<?php
$companies = $contactApi->getContactCompanies($contactId);
```json
{
"total":1,
"companies":[
{
"company_id":"420",
"date_associated":"2016-12-27 15:03:43",
"is_primary":"0",
"companyname":"test",
"companyemail":"[email protected]",
"companycity":"Raleigh",
https://developer.mautic.org/#plugin-directory-structure 130/222
17/12/2017 Mautic Developer Documentation
"score":"0",
"date_added":"2016-12-27 15:03:42"
}
]
}
HTTP REQUEST
GET /contacts/ID/companies
RESPONSE
List Properties
date_associated datetime Date and time when the contact was associated to the company
date_added datetime Date and time when the company was created
<?php
$devices = $contactApi->getContactDevices($contactId);
```json
{
"total":1,
"devices":[
{
"id":60,
"lead":[],
"clientInfo":[],
"device":"desktop",
"deviceOsName":"Ubuntu",
"deviceOsShortName":"UBT",
"deviceOsPlatform":"x64"
}
]
}
HTTP REQUEST
GET /contacts/ID/devices
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 131/222
17/12/2017 Mautic Developer Documentation
Expected response code: 200
List Properties
id int Device ID
clientInfo array Array with various information about the client (browser)
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$contactApi = $api->newApi("data", $auth, $apiUrl);
<?php
$data = $dataApi->getList();
HTTP REQUEST
GET /data
<?php
$data = $dataApi->get($type, $options);
HTTP REQUEST
GET /data/{type}?dateFrom={YYYY-mm-dd}&dateTo={YYYY-mm-dd}&timeUnit={m}
Returns response which can be directly visualized byt the chartJS library.
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 132/222
17/12/2017 Mautic Developer Documentation
Expected Response Code: 200
HTTP REQUEST
GET /data/{type}?dateFrom={YYYY-mm-dd}&dateTo={YYYY-mm-dd}&timeUnit={m}&dataFormat={raw}
RESPONSE
Dynamic Content
Use this endpoint to obtain details on Mautics web dynamic content.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$dynamicContentApi = $api->newApi("dynamicContents", $auth, $apiUrl);
<?php
//...
$dynamicContent = $dynamicContentApi->get($id);
HTTP REQUEST
GET /dynamiccontents/ID
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 133/222
17/12/2017 Mautic Developer Documentation
createdByUser string Name of the user that created the dynamic content
modiedBy int ID of the user that last modied the dynamic content
modiedByUser string Name of the user that last modied the dynamic content
variantChildren array Array of Dynamic Content entities for variants of this landing dynamic content
variantParent object The parent/main dynamic content if this is a variant (A/B test)
sentCount int Count of how many times the dynamic content was sent
<?php
// ...
HTTP REQUEST
GET /dynamiccontents
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 134/222
17/12/2017 Mautic Developer Documentation
Expected Response Code: 200
Properties
<?php
$data = array(
'name' => 'Dynamic Content A',
'isPublished' => 1
);
$dynamicContent = $dynamicContentApi->create($data);
HTTP REQUEST
POST /dynamiccontents/new
Post Parameters
createdByUser string Name of the user that created the dynamic content
modiedBy int ID of the user that last modied the dynamic content
modiedByUser string Name of the user that last modied the dynamic content
variantChildren array Array of Dynamic Content entities for variants of this landing dynamic content
variantParent object The parent/main dynamic content if this is a variant (A/B test)
sentCount int Count of how many times the dynamic content was sent
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 135/222
17/12/2017 Mautic Developer Documentation
Properties
<?php
$id = 1;
$data = array(
'name' => 'New dynamicContent name',
'isPublished' => 0
);
Edit a new dynamicContent. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a dynamicContent if the given ID does not exist and clears all the dynamic content information, adds the information from the
request. PATCH fails if the dynamic content with the given ID does not exist and updates the dynamic content eld values with the values
form the request.
HTTP REQUEST
To edit a dynamicContent and return a 404 if the dynamic content is not found:
PATCH /dynamiccontents/ID/edit
To edit a dynamicContent and create a new one if the dynamic content is not found:
PUT /dynamiccontents/ID/edit
Post Parameters
createdByUser string Name of the user that created the dynamic content
modiedBy int ID of the user that last modied the dynamic content
modiedByUser string Name of the user that last modied the dynamic content
https://developer.mautic.org/#plugin-directory-structure 136/222
17/12/2017 Mautic Developer Documentation
variantChildren array Array of Dynamic Content entities for variants of this landing dynamic content
variantParent object The parent/main dynamic content if this is a variant (A/B test)
sentCount int Count of how many times the dynamic content was sent
RESPONSE
If PUT , the expected response code is 200 if the dynamic content was edited or 201 if created.
Properties
<?php
$dynamicContent = $dynamicContentApi->delete($id);
Delete a dynamicContent.
HTTP REQUEST
DELETE /dynamiccontents/ID/delete
RESPONSE
Properties
Emails
Use this endpoint to obtain details, create, update or delete Mautics emails.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$emailApi = $api->newApi("emails", $auth, $apiUrl);
GET EMAIL
<?php
//...
$email = $emailApi->get($id);
https://developer.mautic.org/#plugin-directory-structure 137/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
GET /emails/ID
RESPONSE
Email Properties
fromAddress string The from email address if its different than the one in the Mautic conguration
fromName string The from name if its different than the one in the Mautic conguration
replyToAddress string The reply to email address if its different than the one in the Mautic conguration
bccAddress string The BCC email address if its different than the one in the Mautic conguration
modiedByUser string Name of the user that last modied the email
template string The name of the template used as the base for the email
https://developer.mautic.org/#plugin-directory-structure 138/222
17/12/2017 Mautic Developer Documentation
emailType string If it is a segment (former list) email or template email. Possible values are list and 'template
translationChildren array Array of Page entities for translations of this landing page
variantChildren array Array of Email entities for variants of this landing email
lists array Array of segment IDs which should be added to the segment email
LIST EMAILS
<?php
// ...
HTTP REQUEST
GET /emails
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 139/222
17/12/2017 Mautic Developer Documentation
See JSON code example.
Properties
CREATE EMAIL
<?php
$data = array(
'title' => 'Email A',
'description' => 'This is my first email created via API.',
'isPublished' => 1
);
$email = $emailApi->create($data);
HTTP REQUEST
POST /emails/new
Post Parameters
fromAddress string The from email address if its different than the one in the Mautic conguration
fromName string The from name if its different than the one in the Mautic conguration
replyToAddress string The reply to email address if its different than the one in the Mautic conguration
bccAddress string The BCC email address if its different than the one in the Mautic conguration
template string The name of the template used as the base for the email
emailType string If it is a segment (former list) email or template email. Possible values are 'list and 'template
https://developer.mautic.org/#plugin-directory-structure 140/222
17/12/2017 Mautic Developer Documentation
translationChildren array Array of Page entities for translations of this landing page
variantChildren array Array of Email entities for variants of this landing email
lists array Array of segment IDs which should be added to the segment email
RESPONSE
Properties
EDIT EMAIL
<?php
$id = 1;
$data = array(
'title' => 'New email title',
'isPublished' => 0
);
Edit a new email. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a email if the given ID does not exist and clears all the email information, adds the information from the request. PATCH fails if
the email with the given ID does not exist and updates the email eld values with the values form the request.
HTTP REQUEST
PATCH /emails/ID/edit
To edit a email and create a new one if the email is not found:
PUT /emails/ID/edit
https://developer.mautic.org/#plugin-directory-structure 141/222
17/12/2017 Mautic Developer Documentation
Post Parameters
fromAddress string The from email address if its different than the one in the Mautic conguration
fromName string The from name if its different than the one in the Mautic conguration
replyToAddress string The reply to email address if its different than the one in the Mautic conguration
bccAddress string The BCC email address if its different than the one in the Mautic conguration
template string The name of the template used as the base for the email
emailType string If it is a segment (former list) email or template email. Possible values are 'list and 'template
translationChildren array Array of Page entities for translations of this landing page
variantChildren array Array of Email entities for variants of this landing email
https://developer.mautic.org/#plugin-directory-structure 142/222
17/12/2017 Mautic Developer Documentation
lists array Array of segment IDs which should be added to the segment email
RESPONSE
If PUT , the expected response code is 200 if the email was edited or 201 if created.
Properties
DELETE EMAIL
<?php
$email = $emailApi->delete($id);
Delete a email.
HTTP REQUEST
DELETE /emails/ID/delete
RESPONSE
Properties
<?php
HTTP REQUEST
POST /emails/ID/contact/CONTACT_ID/send
Post Parameters
RESPONSE
<?php
$email = $emailApi->send($id);
https://developer.mautic.org/#plugin-directory-structure 143/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
POST /emails/ID/send
RESPONSE
Fields
Use this endpoint to work with Mautics contact/company elds.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$assetApi = $api->newApi("assets", $auth, $apiUrl);
GET FIELD
<?php
//...
$field = $fieldApi->get($id);
HTTP REQUEST
RESPONSE
Field Properties
https://developer.mautic.org/#plugin-directory-structure 144/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the eld
alias string Unique alias of the eld used in the form eld name attributes
object string Which object use the eld. Contact (lead) or Company.
isPubliclyUpdatable boolean True if the eld value can be changed from public requests. The tracking pixel query for example.
True if the eld is unique identier and so the contacts should merge if the value of this eld is the
isUniqueIdentier boolean
same.
<?php
//...
$fields = $fieldApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
https://developer.mautic.org/#plugin-directory-structure 145/222
17/12/2017 Mautic Developer Documentation
Name Description
orderBy Column to sort by. Can use any column listed in the response.
HTTP REQUEST
RESPONSE
Field Properties
modiedByUser string Name of the user that last modied the eld
alias string Unique alias of the eld used in the form eld name attributes
object string Which object use the eld. Contact (lead) or Company.
https://developer.mautic.org/#plugin-directory-structure 146/222
17/12/2017 Mautic Developer Documentation
isPubliclyUpdatable boolean True if the eld value can be changed from public requests. The tracking pixel query for example.
True if the eld is unique identier and so the contacts should merge if the value of this eld is the
isUniqueIdentier boolean
same.
CREATE FIELD
<?php
$data = array(
'label' => 'API test field',
'type' => 'text',
);
$field = $fieldApi->create($data);
HTTP REQUEST
Post Parameters
Name Description
label string
alias string
description string/null
type string
group string
order int
object string
defaultValue string
isRequired boolean
isPubliclyUpdatable boolean
isUniqueIdentier boolean
properties array
RESPONSE
Properties
https://developer.mautic.org/#plugin-directory-structure 147/222
17/12/2017 Mautic Developer Documentation
EDIT FIELD
<?php
$id = 1;
$data = array(
'label' => 'API test field',
'type' => 'text',
);
Edit a new eld. Field that this supports PUT or PATCH depending on the desired behavior.
PUT creates a eld if the given ID does not exist and clears all the eld ineldation, adds the ineldation from the request. PATCH fails if the
eld with the given ID does not exist and updates the eld eld values with the values eld the request.
HTTP REQUEST
To edit a eld and create a new one if the eld is not found:
Post Parameters
Name Description
label string
alias string
description string/null
type string
group string
order int
object string
defaultValue string
isRequired boolean
isPubliclyUpdatable boolean
isUniqueIdentier boolean
properties array
RESPONSE
If PUT , the expected response code is 200 if the eld was edited or 201 if created.
https://developer.mautic.org/#plugin-directory-structure 148/222
17/12/2017 Mautic Developer Documentation
Properties
DELETE FIELD
<?php
$field = $fieldApi->delete($id);
Delete a eld.
HTTP REQUEST
RESPONSE
Properties
Files
This endpoint is useful for working with les of images and assets.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
<?php
// Get list of root media/files directory where the asset files are stored:
$files = $filesApi->setFolder('assets');
$files = $filesApi->getList();
HTTP REQUEST
GET /files/images to get root images directory GET /files/images?subdir=flags to get images/ags directory GET /files/assets to get
root assets directory
https://developer.mautic.org/#plugin-directory-structure 149/222
17/12/2017 Mautic Developer Documentation
RESPONSE
Response Properties
CREATE FILE
<?php
$data = array(
'file' => dirname(__DIR__).'/'.'mauticlogo.png' // Must be a path to an existing file
);
// Create a file in media/files directory where the asset files are stored:
$files = $filesApi->setFolder('assets');
$response = $fileApi->create($data);
Creates a le. The le is sent via regular POST les array like a browser sends it during le upload.
HTTP REQUEST
POST /files/DIR/new
RESPONSE
Response Properties
link string Appears only for les in image directory, not for assets
DELETE FILE
<?php
// Delete a file from root media/images directory:
$response = $fileApi->delete($fileName);
// Delete a file from media/files directory where the asset files are stored:
$files = $filesApi->setFolder('assets');
$response = $fileApi->delete($fileName);
https://developer.mautic.org/#plugin-directory-structure 150/222
17/12/2017 Mautic Developer Documentation
Delete a le.
HTTP REQUEST
DELETE /files/DIR/FILE/delete
RESPONSE
Forms
Use this endpoint to obtain details on Mautics forms.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$formApi = $api->newApi("forms", $auth, $apiUrl);
GET FORM
<?php
//...
$form = $formApi->get($id);
HTTP REQUEST
GET /forms/ID
RESPONSE
Form Properties
https://developer.mautic.org/#plugin-directory-structure 151/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the form
elds array Array of Field entities for the form. See below.
actions array Array of Action entities for the form. See below.
Field Properties
Action Properties
https://developer.mautic.org/#plugin-directory-structure 152/222
17/12/2017 Mautic Developer Documentation
LIST FORMS
<?php
// ...
HTTP REQUEST
GET /forms
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
CREATE FORM
<?php
$data = array(
'name' => 'test',
'formType' => 'standalone',
'description' => 'API test',
'fields' => array(
https://developer.mautic.org/#plugin-directory-structure 153/222
17/12/2017 Mautic Developer Documentation
array(
'label' => 'field name',
'type' => 'text'
)
),
'actions' => array(
array(
'name' => 'action name',
'description' => 'action desc',
'type' => 'lead.pointschange',
'properties' => array(
'operator' => 'plus',
'points' => 2
)
)
)
);
$form = $formApi->create($data);
HTTP REQUEST
POST /forms/new
Post Parameters
Same as Get Form. Form elds and actions can be created/edited via the forms/actions arrays in the form array.
RESPONSE
Properties
EDIT FORM
<?php
$id = 1;
$data = array(
'name' => 'test',
'formType' => 'standalone',
'description' => 'API test',
'fields' => array(
array(
'label' => 'field name',
'type' => 'text'
)
),
'actions' => array(
array(
'name' => 'action name',
'description' => 'action desc',
'type' => 'lead.pointschange',
'properties' => array(
'operator' => 'plus',
'points' => 2
)
)
)
);
https://developer.mautic.org/#plugin-directory-structure 154/222
17/12/2017 Mautic Developer Documentation
Edit a new form. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a form if the given ID does not exist and clears all the form information, adds the information from the request. Form elds and
actions will be also deleted if not present in the request. PATCH fails if the form with the given ID does not exist and updates the form eld
values with the values form the request.
HTTP REQUEST
PATCH /forms/ID/edit
To edit a form and create a new one if the form is not found:
PUT /forms/ID/edit
Post Parameters
Same as Get Form. Form elds and actions can be created/edited via the forms/actions arrays in the form array.
RESPONSE
If PUT , the expected response code is 200 if the form was edited or 201 if created.
Properties
DELETE FORM
<?php
$form = $formApi->delete($id);
Delete a form.
HTTP REQUEST
DELETE /forms/ID/delete
RESPONSE
Properties
The following examples will show how to delete elds with ID 56 and 59.
<?php
HTTP REQUEST
https://developer.mautic.org/#plugin-directory-structure 155/222
17/12/2017 Mautic Developer Documentation
DELETE /forms/ID/fields/delete?fields[]=56&fields[]=59
RESPONSE
Properties
The following examples will show how to delete actions with ID 56 and 59.
<?php
HTTP REQUEST
DELETE /forms/ID/actions/delete?actions[]=56&actions[]=59
RESPONSE
Properties
<?php
HTTP REQUEST
GET /forms/FORM_ID/submissions
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 156/222
17/12/2017 Mautic Developer Documentation
Expected Response Code: 200
Properties
ipAddress array Associative array containing IP address of the client who made the submission
form array Simplied associative array of the form containing id, name, alias and category
lead array Associative array of the lead containing the core values as well as custom elds
dateSubmitted string Date time string holding the UTC date and time when the submission was made
results array Associative array of the form elds as the keys and submission values
<?php
$submissions = $formApi->getSubmissionsForContact($formId, $contactId, $searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
HTTP REQUEST
GET /forms/FORM_ID/submissions/contact/CONTACT_ID
Response and properties same as Get Form Submissions. Parameters too except the ContactId was added.
<?php
//...
$form = $formApi->getSubmission($formId, $submissionId);
HTTP REQUEST
GET /forms/FORM_ID/submissions/SUBMISSION_ID
RESPONSE
Form Properties
Marketing Messages
https://developer.mautic.org/#plugin-directory-structure 157/222
17/12/2017 Mautic Developer Documentation
Use this endpoint to obtain details, create, update or delete Mautics messages.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$messageApi = $api->newApi("messages", $auth, $apiUrl);
<?php
//...
$message = $messageApi->get($id);
HTTP REQUEST
GET /messages/ID
RESPONSE
modiedByUser string Name of the user that last modied the message
https://developer.mautic.org/#plugin-directory-structure 158/222
17/12/2017 Mautic Developer Documentation
<?php
// ...
HTTP REQUEST
GET /messages
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
<?php
$data = array(
'name' => 'Marketing Message A',
'description' => 'This is my first message created via API.',
'isPublished' => 1,
'channels' => array(
'email' => array(
'channel' => 'email',
'channelId' => 44,
'isEnabled' => true,
),
'sms' => array(
'channel' => 'sms',
'channelId' => 1,
'isEnabled' => true,
),
'notification' => array(
'channel' => 'notification',
'channelId' => 75,
'isEnabled' => false,
)
)
);
https://developer.mautic.org/#plugin-directory-structure 159/222
17/12/2017 Mautic Developer Documentation
$message = $messageApi->create($data);
HTTP REQUEST
POST /messages/new
Post Parameters
RESPONSE
Properties
<?php
$id = 1;
$data = array(
'name' => 'New message title',
'isPublished' => 0
);
Edit a new message. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a message if the given ID does not exist and clears all the message information, adds the information from the request.
PATCH fails if the message with the given ID does not exist and updates the message eld values with the values form the request.
HTTP REQUEST
PATCH /messages/ID/edit
To edit a message and create a new one if the message is not found:
PUT /messages/ID/edit
https://developer.mautic.org/#plugin-directory-structure 160/222
17/12/2017 Mautic Developer Documentation
Post Parameters
RESPONSE
If PUT , the expected response code is 200 if the message was edited or 201 if created.
Properties
<?php
$message = $messageApi->delete($id);
Delete a message.
HTTP REQUEST
DELETE /messages/ID/delete
RESPONSE
Properties
Notes
Use this endpoint to obtain details on Mautics contact notes.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
https://developer.mautic.org/#plugin-directory-structure 161/222
17/12/2017 Mautic Developer Documentation
$api = new MauticApi();
$noteApi = $api->newApi("notes", $auth, $apiUrl);
GET NOTE
<?php
//...
$note = $noteApi->get($id);
HTTP REQUEST
GET /notes/ID
RESPONSE
Note Properties
<?php
//...
$notes = $noteApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
HTTP REQUEST
GET /notes
RESPONSE
Note Properties
https://developer.mautic.org/#plugin-directory-structure 162/222
17/12/2017 Mautic Developer Documentation
CREATE NOTE
<?php
$data = array(
'text' => 'Note A',
'type' => 'general',
);
$note = $noteApi->create($data);
HTTP REQUEST
POST /notes/new
Post Parameters
Name Description
text string
type string
datetime datetime
RESPONSE
Properties
EDIT NOTE
<?php
$id = 1;
$data = array(
'text' => 'Note B',
'type' => 'general',
);
Edit a new note. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a note if the given ID does not exist and clears all the note information, adds the information from the request. PATCH fails if
the note with the given ID does not exist and updates the note eld values with the values form the request.
HTTP REQUEST
https://developer.mautic.org/#plugin-directory-structure 163/222
17/12/2017 Mautic Developer Documentation
To edit a note and return a 404 if the note is not found:
PATCH /notes/ID/edit
To edit a note and create a new one if the note is not found:
PUT /notes/ID/edit
Post Parameters
Name Description
text string
type string
datetime datetime
RESPONSE
If PUT , the expected response code is 200 if the note was edited or 201 if created.
Properties
DELETE NOTE
<?php
$note = $noteApi->delete($id);
Delete a note.
HTTP REQUEST
DELETE /notes/ID/delete
RESPONSE
Properties
Notications
Use this endpoint to obtain details on Mautics notications.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
https://developer.mautic.org/#plugin-directory-structure 164/222
17/12/2017 Mautic Developer Documentation
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$notificationApi = $api->newApi("notifications", $auth, $apiUrl);
GET NOTIFICATION
<?php
//...
$notification = $notificationApi->get($id);
HTTP REQUEST
GET /notifications/ID
RESPONSE
Notication Properties
modiedByUser string Name of the user that last modied the notication
https://developer.mautic.org/#plugin-directory-structure 165/222
17/12/2017 Mautic Developer Documentation
LIST NOTIFICATIONS
<?php
// ...
HTTP REQUEST
GET /notifications
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
CREATE NOTIFICATION
<?php
$data = array(
'name' => 'Notification A',
'heading' => 'Hello World!'
'message' => 'This is my first notification created via API.',
);
$notification = $notificationApi->create($data);
HTTP REQUEST
POST /notifications/new
Post Parameters
https://developer.mautic.org/#plugin-directory-structure 166/222
17/12/2017 Mautic Developer Documentation
RESPONSE
Properties
EDIT NOTIFICATION
<?php
$id = 1;
$data = array(
'name' => 'Notification A',
'heading' => 'Hello World!'
'message' => 'This is my first notification created via API.',
);
Edit a new notication. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a notication if the given ID does not exist and clears all the notication information, adds the information from the request.
PATCH fails if the notication with the given ID does not exist and updates the notication eld values with the values form the request.
HTTP REQUEST
PATCH /notifications/ID/edit
To edit a notication and create a new one if the notication is not found:
PUT /notifications/ID/edit
Post Parameters
https://developer.mautic.org/#plugin-directory-structure 167/222
17/12/2017 Mautic Developer Documentation
RESPONSE
If PUT , the expected response code is 200 if the notication was edited or 201 if created.
Properties
DELETE NOTIFICATION
<?php
$notification = $notificationApi->delete($id);
Delete a notication.
HTTP REQUEST
DELETE /notifications/ID/delete
RESPONSE
Properties
Pages
Use this endpoint to obtain details on Mautics landing pages.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
https://developer.mautic.org/#plugin-directory-structure 168/222
17/12/2017 Mautic Developer Documentation
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$pageApi = $api->newApi("pages", $auth, $apiUrl);
GET PAGE
<?php
//...
$page = $pageApi->get($id);
HTTP REQUEST
GET /pages/ID
RESPONSE
Page Properties
modiedByUser string Name of the user that last modied the page
https://developer.mautic.org/#plugin-directory-structure 169/222
17/12/2017 Mautic Developer Documentation
translationChildren array Array of Page entities for translations of this landing page
variantChildren array Array of Page entities for variants of this landing page
LIST PAGES
<?php
// ...
HTTP REQUEST
GET /pages
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
CREATE PAGE
https://developer.mautic.org/#plugin-directory-structure 170/222
17/12/2017 Mautic Developer Documentation
<?php
$data = array(
'title' => 'Page A',
'description' => 'This is my first page created via API.',
'isPublished' => 1
);
$page = $pageApi->create($data);
HTTP REQUEST
POST /pages/new
Post Parameters
Name Description
alias string
isPublished A value of 0 or 1
language string
redirectType int
redirectUrl string
RESPONSE
Properties
EDIT PAGE
<?php
$id = 1;
$data = array(
'title' => 'New page title',
'isPublished' => 0
);
Edit a new page. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a page if the given ID does not exist and clears all the page information, adds the information from the request. PATCH fails if
the page with the given ID does not exist and updates the page eld values with the values form the request.
https://developer.mautic.org/#plugin-directory-structure 171/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
PATCH /pages/ID/edit
To edit a page and create a new one if the page is not found:
PUT /pages/ID/edit
Post Parameters
Name Description
isPublished A value of 0 or 1
language string
redirectType int
redirectUrl string
RESPONSE
If PUT , the expected response code is 200 if the page was edited or 201 if created.
Properties
DELETE PAGE
<?php
$page = $pageApi->delete($id);
Delete a page.
HTTP REQUEST
DELETE /pages/ID/delete
RESPONSE
Properties
https://developer.mautic.org/#plugin-directory-structure 172/222
17/12/2017 Mautic Developer Documentation
Point Actions
Use this endpoint to obtain details on Mautics point actions.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$pointApi = $api->newApi("points", $auth, $apiUrl);
<?php
//...
$point = $pointApi->get($id);
HTTP REQUEST
GET /points/ID
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 173/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the point
delta int The number of points to give the lead when executing this action
<?php
// ...
HTTP REQUEST
GET /points
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
<?php
$data = array(
'name' => 'test',
'delta' => 5,
'type' => 'page.hit',
'description' => 'created as a API test'
);
https://developer.mautic.org/#plugin-directory-structure 174/222
17/12/2017 Mautic Developer Documentation
$point = $pointApi->create($data);
HTTP REQUEST
POST /points/new
Post Parameters
Same as Get Point Action. Point Action elds and actions can be created/edited via the point actions/actions arrays in the point action array.
RESPONSE
Properties
<?php
$id = 1;
$data = array(
'name' => 'test',
'delta' => 5,
'type' => 'page.hit',
'description' => 'created as a API test'
);
Edit a new point action. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a point action if the given ID does not exist and clears all the point action inpoint actionation, adds the inpoint actionation from
the request. Point Action elds and actions will be also deleted if not present in the request. PATCH fails if the point action with the given ID
does not exist and updates the point action eld values with the values point action the request.
HTTP REQUEST
To edit a point action and return a 404 if the point action is not found:
PATCH /points/ID/edit
To edit a point action and create a new one if the point action is not found:
PUT /points/ID/edit
Post Parameters
Same as Get Point Action. Point Action elds and actions can be created/edited via the point actions/actions arrays in the point action array.
RESPONSE
If PUT , the expected response code is 200 if the point action was edited or 201 if created.
Properties
https://developer.mautic.org/#plugin-directory-structure 175/222
17/12/2017 Mautic Developer Documentation
Same as Get Point Action.
<?php
$point = $pointApi->delete($id);
HTTP REQUEST
DELETE /points/ID/delete
RESPONSE
Properties
<?php
$point = $pointApi->getPointActionTypes();
HTTP REQUEST
GET /points/actions/types
RESPONSE
Point Triggers
Use this endpoint to obtain details on Mautics point triggers.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$triggerApi = $api->newApi("pointTriggers", $auth, $apiUrl);
<?php
https://developer.mautic.org/#plugin-directory-structure 176/222
17/12/2017 Mautic Developer Documentation
//...
$trigger = $triggerApi->get($id);
HTTP REQUEST
GET /points/triggers/ID
RESPONSE
modiedByUser string Name of the user that last modied the point
points int The minimum number of points before the trigger events are executed
color string Color hex to highlight the lead with. This value does NOT include the pound sign (#)
events array Array of TriggerEvent entities for this trigger. See below.
https://developer.mautic.org/#plugin-directory-structure 177/222
17/12/2017 Mautic Developer Documentation
<?php
// ...
HTTP REQUEST
GET /points/triggers
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
<?php
$data = array(
'name' => 'test',
'description' => 'created as a API test',
'points' => 5,
'color' => '4e5d9d',
'trigger_existing_leads' => false,
'events' => array(
array(
'name' => 'tag test event',
'description' => 'created as a API test',
'type' => 'lead.changetags',
'order' => 1,
'properties' => array(
'add_tags' => array('tag-a'),
https://developer.mautic.org/#plugin-directory-structure 178/222
17/12/2017 Mautic Developer Documentation
'remove_tags' => array()
)
),
array(
'name' => 'send email test event',
'description' => 'created as a API test',
'type' => 'email.send',
'order' => 2,
'properties' => array(
'email' => 1
)
)
)
);
$trigger = $triggerApi->create($data);
HTTP REQUEST
POST /points/triggers/new
Post Parameters
Same as Get Point Trigger. Point Trigger events can be created/edited via the point trigger event arrays placed in the point trigger array.
RESPONSE
Properties
<?php
$id = 1;
$data = array(
'name' => 'test',
'description' => 'created as a API test',
'points' => 5,
'color' => '4e5d9d',
'trigger_existing_leads' => false,
'events' => array(
array(
'name' => 'tag test event',
'description' => 'created as a API test',
'type' => 'lead.changetags',
'order' => 1,
'properties' => array(
'add_tags' => array('tag-a'),
'remove_tags' => array()
)
),
array(
'name' => 'send email test event',
'description' => 'created as a API test',
'type' => 'email.send',
'order' => 2,
'properties' => array(
'email' => 1
)
)
)
);
https://developer.mautic.org/#plugin-directory-structure 179/222
17/12/2017 Mautic Developer Documentation
Edit a new point trigger. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a point trigger if the given ID does not exist and clears all the point trigger information, adds the information from the request.
Point Trigger events will be also deleted if not present in the request. PATCH fails if the point trigger with the given ID does not exist and
updates the point trigger eld values with the values point trigger the request.
HTTP REQUEST
To edit a point trigger and return a 404 if the point trigger is not found:
PATCH /points/triggers/ID/edit
To edit a point trigger and create a new one if the point trigger is not found:
PUT /points/triggers/ID/edit
Post Parameters
Same as Get Point Trigger. Point Trigger events can be created/edited via the point triggers event arrays placed in the point trigger array.
RESPONSE
If PUT , the expected response code is 200 if the point trigger was edited or 201 if created.
Properties
<?php
$trigger = $triggerApi->delete($id);
HTTP REQUEST
DELETE /points/triggers/ID/delete
RESPONSE
Properties
The following examples will show how to delete events with ID 56 and 59.
<?php
https://developer.mautic.org/#plugin-directory-structure 180/222
17/12/2017 Mautic Developer Documentation
Delete a point trigger events.
HTTP REQUEST
DELETE /points/triggers/ID/events/delete?events[]=56&events[]=59
RESPONSE
Properties
<?php
$point = $pointApi->getEventTypes();
HTTP REQUEST
GET /points/triggers/events/types
RESPONSE
Roles
Use this endpoint to obtain details on Mautics roles (administrators).
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$roleApi = $api->newApi("roles", $auth, $apiUrl);
GET ROLE
<?php
//...
$role = $roleApi->get($id);
HTTP REQUEST
GET /roles/ID
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 181/222
17/12/2017 Mautic Developer Documentation
Expected Response Code: 200
Role Properties
modiedByRole string Name of the role that last modied the contact
isAdmin boolean Whether the role has full access or only some
<?php
//...
$roles = $roleApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
HTTP REQUEST
GET /roles
RESPONSE
Role Properties
https://developer.mautic.org/#plugin-directory-structure 182/222
17/12/2017 Mautic Developer Documentation
modiedByRole string Name of the role that last modied the contact
isAdmin boolean Whether the role has full access or only some
CREATE ROLE
<?php
$data = array(
'name' => 'API test role',
'description' => 'created via AIP',
'rawPermissions' => array (
'email:emails' =>
array (
'viewown',
'viewother',
),
)
);
$role = $roleApi->create($data);
HTTP REQUEST
POST /roles/new
Post Parameters
Name Description
name string
description string
isAdmin boolean
rawPermissions array
RESPONSE
Properties
EDIT ROLE
<?php
$id = 1;
$data = array(
'name' => 'API test role',
https://developer.mautic.org/#plugin-directory-structure 183/222
17/12/2017 Mautic Developer Documentation
'description' => 'created via AIP',
'rawPermissions' => array (
'email:emails' =>
array (
'editown',
'editother',
),
)
);
Edit a new role. Role that this supports PUT or PATCH depending on the desired behavior.
PUT creates a role if the given ID does not exist and clears all the role information, adds the information from the request. PATCH fails if the
role with the given ID does not exist and updates the role eld values with the values form the request.
HTTP REQUEST
PATCH /roles/ID/edit
To edit a role and create a new one if the role is not found:
PUT /roles/ID/edit
Post Parameters
Name Description
name string
description string
isAdmin boolean
rawPermissions array
RESPONSE
If PUT , the expected response code is 200 if the role was edited or 201 if created.
Properties
DELETE ROLE
<?php
$role = $roleApi->delete($id);
Delete a role.
HTTP REQUEST
DELETE /roles/ID/delete
https://developer.mautic.org/#plugin-directory-structure 184/222
17/12/2017 Mautic Developer Documentation
RESPONSE
Properties
Segments
Use this endpoint to obtain details on Mautics contact segments or to manipulate contact memberships.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$segmentApi = $api->newApi("segments", $auth, $apiUrl);
GET SEGMENT
<?php
//...
$segment = $segmentApi->get($id);
HTTP REQUEST
GET /segments/ID
RESPONSE
Segment Properties
https://developer.mautic.org/#plugin-directory-structure 185/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the segment
lters array Smart lters for the segment. See lter properties bellow
isGlobal boolean Whether the segment is global. 0 means only the author will see it.
glue string How to glue the lters to others. Possible values: and , or
eld string Alias of the contact or company eld to based the lter on
object string Object which have the eld. Possible values: lead (for contacts), company
Type of the eld. Possible values: 'boolean, date (format Y-m-d ), datetime (format Y-m-d H:i:s ), email , coun
type string
try , locale , lookup , number , tel , region , select , multiselect , text , textarea , time , timezone , url
Operator used for matching the values. Possible values: =, != , empty , !empty , like , !like , regexp , !regexp ,
operator string
startsWith , endsWith , contains
<?php
//...
$segments = $segmentApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
Returns a list of contact segments available to the user. This list is not lterable.
HTTP REQUEST
GET /segments
RESPONSE
Segment Properties
https://developer.mautic.org/#plugin-directory-structure 186/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the segment
lters array Smart lters for the segment. See lter properties bellow
isGlobal boolean Whether the segment is global. 0 means only the author will see it.
glue string How to glue the lters to others. Possible values: and , or
eld string Alias of the contact or company eld to based the lter on
object string Object which have the eld. Possible values: 'lead (for contacts), company
Type of the eld. Possible values: 'boolean, date (format Y-m-d ), datetime (format Y-m-d H:i:s ), email , coun
type string
try , locale , lookup , number , tel , region , select , multiselect , text , textarea , time , timezone , url
Operator used for matching the values. Possible values: =, != , empty , !empty , like , !like , regexp , !regexp ,
operator string
startsWith , endsWith , contains
CREATE SEGMENT
<?php
$data = array(
'name' => 'Segment A',
'alias' => 'segment-a',
'description' => 'This is my first segment created via API.',
'isPublished' => 1,
'filters' => array(
array(
'glue' => 'and',
'field' => 'email',
'object' => 'lead',
'type' => 'email',
'filter' => '*@gmail.com',
'operator' => 'like',
),
),
);
$segment = $segmentApi->create($data);
POST /segments/new
Post Parameters
Name Description
isPublished A value of 0 or 1
isGlobal boolean
lters array
glue string How to glue the lters to others. Possible values: and , or
eld string Alias of the contact or company eld to based the lter on
object string Object which have the eld. Possible values: 'lead (for contacts), company
Type of the eld. Possible values: 'boolean, date (format Y-m-d ), datetime (format Y-m-d H:i:s ), email , coun
type string
try , locale , lookup , number , tel , region , select , multiselect , text , textarea , time , timezone , url
Operator used for matching the values. Possible values: =, != , empty , !empty , like , !like , regexp , !regexp ,
operator string
startsWith , endsWith , contains
RESPONSE
Properties
EDIT SEGMENT
<?php
$id = 1;
$data = array(
'name' => 'New segment name',
'isPublished' => 0
);
Edit a new segment. Note that this supports PUT or PATCH depending on the desired behavior.
https://developer.mautic.org/#plugin-directory-structure 188/222
17/12/2017 Mautic Developer Documentation
PUT creates a segment if the given ID does not exist and clears all the segment information, adds the information from the request. PATCH
fails if the segment with the given ID does not exist and updates the segment eld values with the values form the request.
HTTP REQUEST
PATCH /segments/ID/edit
To edit a segment and create a new one if the segment is not found:
PUT /segments/ID/edit
Post Parameters
Name Description
isPublished A value of 0 or 1
isGlobal boolean
lters array
glue string How to glue the lters to others. Possible values: and , or
eld string Alias of the contact or company eld to based the lter on
object string Object which have the eld. Possible values: 'lead (for contacts), company
Type of the eld. Possible values: 'boolean, date (format Y-m-d ), datetime (format Y-m-d H:i:s ), email , coun
type string
try , locale , lookup , number , tel , region , select , multiselect , text , textarea , time , timezone , url
Operator used for matching the values. Possible values: =, != , empty , !empty , like , !like , regexp , !regexp ,
operator string
startsWith , endsWith , contains
RESPONSE
If PUT , the expected response code is 200 if the segment was edited or 201 if created.
Properties
DELETE SEGMENT
<?php
$segment = $segmentApi->delete($id);
Delete a segment.
https://developer.mautic.org/#plugin-directory-structure 189/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
DELETE /segments/ID/delete
RESPONSE
Properties
<?php
//...
$response = $segmentApi->addContact($segmentId, $contactId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
POST /segments/SEGMENT_ID/contact/CONTACT_ID/add
RESPONSE
<?php
//...
$response = $segmentApi->removeContact($segmentId, $contactId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
POST /segments/SEGMENT_ID/contact/CONTACT_ID/remove
RESPONSE
Text messages
Use this endpoint to obtain details on Mautics Text Messages (SMSes).
https://developer.mautic.org/#plugin-directory-structure 190/222
17/12/2017 Mautic Developer Documentation
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$smsApi = $api->newApi("smses", $auth, $apiUrl);
<?php
//...
$sms = $smsApi->get($id);
HTTP REQUEST
GET /smses/ID
RESPONSE
modiedByUser string Name of the user that last modied the sms
https://developer.mautic.org/#plugin-directory-structure 191/222
17/12/2017 Mautic Developer Documentation
LIST TEXT MESSAGES
<?php
// ...
HTTP REQUEST
GET /smses
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
RESPONSE
Properties
<?php
$data = array(
'name' => 'Text message A',
'message' => 'This is my first sms created via API.',
'isPublished' => 1
);
$sms = $smsApi->create($data);
HTTP REQUEST
POST /smses/new
Post Parameters
https://developer.mautic.org/#plugin-directory-structure 192/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the sms
RESPONSE
Properties
<?php
$id = 1;
$data = array(
'name' => 'New sms name',
'isPublished' => 0
);
Edit a new sms. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a sms if the given ID does not exist and clears all the sms information, adds the information from the request. PATCH fails if
the sms with the given ID does not exist and updates the sms eld values with the values form the request.
HTTP REQUEST
PATCH /smses/ID/edit
To edit a sms and create a new one if the sms is not found:
https://developer.mautic.org/#plugin-directory-structure 193/222
17/12/2017 Mautic Developer Documentation
PUT /smses/ID/edit
Post Parameters
RESPONSE
If PUT , the expected response code is 200 if the sms was edited or 201 if created.
Properties
<?php
$sms = $smsApi->delete($id);
Delete a sms.
HTTP REQUEST
DELETE /smses/ID/delete
RESPONSE
Properties
Stages
Use this endpoint to obtain details on Mautics contact stages.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
https://developer.mautic.org/#plugin-directory-structure 194/222
17/12/2017 Mautic Developer Documentation
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$stageApi = $api->newApi("stages", $auth, $apiUrl);
GET STAGE
<?php
//...
$stage = $stageApi->get($id);
HTTP REQUEST
GET /stages/ID
RESPONSE
Stage Properties
modiedByUser string Name of the user that last modied the stage
<?php
//...
$stages = $stageApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
https://developer.mautic.org/#plugin-directory-structure 195/222
17/12/2017 Mautic Developer Documentation
HTTP REQUEST
GET /stages
RESPONSE
Stage Properties
modiedByUser string Name of the user that last modied the stage
CREATE STAGE
<?php
$data = array(
'name' => 'Stage A',
'weight' => 5,
'description' => 'This is my first stage created via API.',
'isPublished' => 1
);
$stage = $stageApi->create($data);
HTTP REQUEST
POST /stages/new
https://developer.mautic.org/#plugin-directory-structure 196/222
17/12/2017 Mautic Developer Documentation
Post Parameters
Name Description
weight int
isPublished A value of 0 or 1
RESPONSE
Properties
EDIT STAGE
<?php
$id = 1;
$data = array(
'name' => 'New stage name',
'isPublished' => 0
);
Edit a new stage. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a stage if the given ID does not exist and clears all the stage information, adds the information from the request. PATCH fails if
the stage with the given ID does not exist and updates the stage eld values with the values form the request.
HTTP REQUEST
PATCH /stages/ID/edit
To edit a stage and create a new one if the stage is not found:
PUT /stages/ID/edit
Post Parameters
Name Description
isPublished A value of 0 or 1
weight int
https://developer.mautic.org/#plugin-directory-structure 197/222
17/12/2017 Mautic Developer Documentation
RESPONSE
If PUT , the expected response code is 200 if the stage was edited or 201 if created.
Properties
DELETE STAGE
<?php
$stage = $stageApi->delete($id);
Delete a stage.
HTTP REQUEST
DELETE /stages/ID/delete
RESPONSE
Properties
<?php
//...
$response = $stageApi->addContact($contactId, $stageId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
POST /stages/STAGE_ID/contact/CONTACT_ID/add
RESPONSE
<?php
//...
$response = $stageApi->removeContact($contactId, $stageId);
if (!isset($response['success'])) {
// handle error
}
HTTP REQUEST
https://developer.mautic.org/#plugin-directory-structure 198/222
17/12/2017 Mautic Developer Documentation
POST /stages/STAGE_ID/contact/CONTACT_ID/remove
RESPONSE
Stats
This endpoint is useful for downloading a full statistical table.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$statsApi = $api->newApi("stats", $auth, $apiUrl);
<?php
//...
$tables = $statsApi->get();
HTTP REQUEST
GET /stats
RESPONSE
Stats Properties
availableTables array List of available tables which can be used in this endpoint
<?php
// Example setup variables:
$table = 'asset_downloads';
$start = 0;
$limit = 50;
$order = array(
array(
'col' => 'id',
'dir' => 'asc'
https://developer.mautic.org/#plugin-directory-structure 199/222
17/12/2017 Mautic Developer Documentation
)
);
$where = array(
array(
'col' => 'id',
'expr' => 'gt',
'val' => 3,
)
);
HTTP REQUEST
GET /stats/TABLE
Request Properties
An array of arrays which contain where conditions (example above). As the expr param can be used most of the
where array
methods from DBAL Doctrine where methods.
array(
array(
'col' => 'id',
'expr' => 'eq',
'val' => 3,
)
);
RESPONSE
Stats Properties
Themes
This endpoint is useful for working with Mautic themes.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
https://developer.mautic.org/#plugin-directory-structure 200/222
17/12/2017 Mautic Developer Documentation
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$themesApi = $api->newApi("themes", $auth, $apiUrl);
GET THEME
Returns directly the zip le in the response with the application/zip header on success or a JSON response body with error messages on
fail. The PHP API library will save the zip le to the system temporary directory and provides you with the path.
<?php
$response = $themesApi->get($themeName);
HTTP REQUEST
GET /themes/THEME_NAME
RESPONSE
Changes the default temporary directory where the zip le is created. The directory is created if it does not exist.
<?php
$themesApi->setTemporaryFilePath("/absolute/path/to/a/different/temp/dir");
$response = $themesApi->get($themeName);
Lists all installed themes with the detailes stored in their cong.json les.
<?php
$response = $themesApi->getList();
HTTP REQUEST
GET /themes
RESPONSE
Response Properties
CREATE THEME
Creates a new theme or updates an existing one (based on the le name) from provided zip le.
<?php
$data = array(
'file' => dirname(__DIR__).'/'.'mytheme.zip' // Must be a path to an existing file
);
https://developer.mautic.org/#plugin-directory-structure 201/222
17/12/2017 Mautic Developer Documentation
$response = $themeApi->create($data);
The le is sent via regular POST les array like a browser sends it during le upload.
HTTP REQUEST
POST /themes/new
RESPONSE
DELETE FILE
<?php
$response = $themeApi->delete($themeName);
HTTP REQUEST
DELETE /themes/THEME_NAME/delete
RESPONSE
Tweets
Use this endpoint to obtain details on Mautics tweets. Implemented in Mautic 2.8.0.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$tweetApi = $api->newApi("tweets", $auth, $apiUrl);
GET TWEET
<?php
//...
$tweet = $tweetApi->get($id);
HTTP REQUEST
GET /tweets/ID
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 202/222
17/12/2017 Mautic Developer Documentation
See JSON code example.
Tweet Properties
modiedByUser string Name of the user that last modied the tweet
LIST TWEETS
<?php
// ...
HTTP REQUEST
GET /tweets
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
https://developer.mautic.org/#plugin-directory-structure 203/222
17/12/2017 Mautic Developer Documentation
Name Description
RESPONSE
Properties
CREATE TWEET
<?php
$data = array(
'name' => 'Tweet A',
'heading' => 'Hello World!'
'message' => 'This is my first tweet created via API.',
);
$tweet = $tweetApi->create($data);
HTTP REQUEST
POST /tweets/new
Post Parameters
RESPONSE
Properties
EDIT TWEET
https://developer.mautic.org/#plugin-directory-structure 204/222
17/12/2017 Mautic Developer Documentation
<?php
$id = 1;
$data = array(
'name' => 'Tweet A',
'text' => 'This is my first tweet created via API.',
);
Edit a new tweet. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a tweet if the given ID does not exist and clears all the tweet information, adds the information from the request. PATCH fails if
the tweet with the given ID does not exist and updates the tweet eld values with the values form the request.
HTTP REQUEST
PATCH /tweets/ID/edit
To edit a tweet and create a new one if the tweet is not found:
PUT /tweets/ID/edit
Post Parameters
RESPONSE
If PUT , the expected response code is 200 if the tweet was edited or 201 if created.
Properties
DELETE TWEET
<?php
$tweet = $tweetApi->delete($id);
https://developer.mautic.org/#plugin-directory-structure 205/222
17/12/2017 Mautic Developer Documentation
Delete a tweet.
HTTP REQUEST
DELETE /tweets/ID/delete
RESPONSE
Properties
Users
Use this endpoint to obtain details on Mautics users (administrators).
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$userApi = $api->newApi("users", $auth, $apiUrl);
GET USER
<?php
//...
$user = $userApi->get($id);
HTTP REQUEST
GET /users/ID
RESPONSE
User Properties
https://developer.mautic.org/#plugin-directory-structure 206/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the contact
signature string Signature of the user which can be used in the emails
<?php
//...
$users = $userApi->getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal);
HTTP REQUEST
GET /users
RESPONSE
User Properties
https://developer.mautic.org/#plugin-directory-structure 207/222
17/12/2017 Mautic Developer Documentation
modiedByUser string Name of the user that last modied the contact
signature string Signature of the user which can be used in the emails
CREATE USER
<?php
$data = array(
'username' => 'apitest',
'firstName' => 'John',
'lastName' => 'Doe',
'email' => '[email protected]',
'plainPassword' => array(
'password' => 'topSecret007',
'confirm' => 'topSecret007',
),
'role' => 1,
);
$user = $userApi->create($data);
HTTP REQUEST
POST /users/new
Post Parameters
Name Description
username string
rstName string
lastName string
email string
https://developer.mautic.org/#plugin-directory-structure 208/222
17/12/2017 Mautic Developer Documentation
Name Description
position string
role array
timezone string
onlineStatus string
signature string
plainPassword array
RESPONSE
Properties
EDIT USER
<?php
$id = 1;
$data = array(
'lastName' => 'Doeboe',
);
Edit a new user. User that this supports PUT or PATCH depending on the desired behavior.
PUT creates a user if the given ID does not exist and clears all the user information, adds the information from the request. PATCH fails if
the user with the given ID does not exist and updates the user eld values with the values form the request.
HTTP REQUEST
PATCH /users/ID/edit
To edit a user and create a new one if the user is not found:
PUT /users/ID/edit
Post Parameters
Name Description
username string
rstName string
lastName string
email string
https://developer.mautic.org/#plugin-directory-structure 209/222
17/12/2017 Mautic Developer Documentation
Name Description
position string
role array
timezone string
signature string
RESPONSE
If PUT , the expected response code is 200 if the user was edited or 201 if created.
Properties
DELETE USER
<?php
$user = $userApi->delete($id);
Delete a user.
HTTP REQUEST
DELETE /users/ID/delete
RESPONSE
Properties
<?php
$user = $userApi->getSelf();
HTTP REQUEST
GET /users/self
RESPONSE
Properties
<?php
$permission = array('user:users:create', 'user:users:edit');
https://developer.mautic.org/#plugin-directory-structure 210/222
17/12/2017 Mautic Developer Documentation
$user = $userApi->checkPermission($id, $permission);
HTTP REQUEST
GET /users/ID/permissioncheck
RESPONSE
Properties
Webhooks
Use this endpoint to obtain details on Mautics webhooks. Implemented in Mautic 2.8.0.
<?php
use Mautic\MauticApi;
use Mautic\Auth\ApiAuth;
// ...
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
$apiUrl = "https://your-mautic.com";
$api = new MauticApi();
$webhookApi = $api->newApi("webhooks", $auth, $apiUrl);
GET WEBHOOK
<?php
//...
$webhook = $webhookApi->get($id);
HTTP REQUEST
GET /hooks/ID
RESPONSE
Webhook Properties
https://developer.mautic.org/#plugin-directory-structure 211/222
17/12/2017 Mautic Developer Documentation
LIST WEBHOOKS
<?php
// ...
HTTP REQUEST
GET /webhooks
Query Parameters
Name Description
limit Limit number of entities to return. Defaults to the system conguration for pagination (30).
orderBy Column to sort by. Can use any column listed in the response.
https://developer.mautic.org/#plugin-directory-structure 212/222
17/12/2017 Mautic Developer Documentation
RESPONSE
Properties
CREATE WEBHOOK
<?php
$data = array(
'name' => 'test',
'description' => 'Created via API',
'webhookUrl' => 'http://some.url',
'eventsOrderbyDir' => "ASC",
'triggers' => array(
'mautic.lead_post_save_update',
'mautic.lead_post_save_new',
)
);
$webhook = $webhookApi->create($data);
HTTP REQUEST
POST /hooks/new
Post Parameters
RESPONSE
Properties
EDIT WEBHOOK
<?php
$id = 1;
$data = array(
https://developer.mautic.org/#plugin-directory-structure 213/222
17/12/2017 Mautic Developer Documentation
'name' => 'Rename webhook 1 to this',
);
Edit a new webhook. Note that this supports PUT or PATCH depending on the desired behavior.
PUT creates a webhook if the given ID does not exist and clears all the webhook information, adds the information from the request.
PATCH fails if the webhook with the given ID does not exist and updates the webhook eld values with the values form the request.
HTTP REQUEST
PATCH /hooks/ID/edit
To edit a webhook and create a new one if the webhook is not found:
PUT /hooks/ID/edit
Post Parameters
eventsOrderbyDir Order direction for queued events in one webhook. Can be DESC or ASC
RESPONSE
If PUT , the expected response code is 200 if the webhook was edited or 201 if created.
Properties
DELETE WEBHOOK
<?php
$webhook = $webhookApi->delete($id);
Delete a webhook.
HTTP REQUEST
DELETE /hooks/ID/delete
RESPONSE
https://developer.mautic.org/#plugin-directory-structure 214/222
17/12/2017 Mautic Developer Documentation
Same as Get Webhook.
<?php
$webhook = $webhookApi->getTriggers();
HTTP REQUEST
GET /hooks/triggers
RESPONSE
Webhooks
Webhook is a universal way how to send data about leads, pages, forms and events. The data is sent in real-time when an action occurs so
the system which listens form Mautic webhook data can process them without the need for a periodic scanning if Mautic has some new
data.
Email open
Form submit
Lead delete
Lead point change
Lead update
Lead create
Page hit
Create a webhook
https://developer.mautic.org/#plugin-directory-structure 215/222
17/12/2017 Mautic Developer Documentation
It is possible to create multiple different webhooks. That will allow you to send different information to different apps/scripts.
1. Open the right hand side menu (click the cog icon in the top right corner) and select Webhooks.
2. Create a new webhook.
3. Fill in a Name, Webhook POST Url (see the next paragraph if you dont have one) and select which Webhook Events should trigger
this webhook.
Test a webhook
The easiest way how to test a webhook payload is to use a service like RequestBin. RequestBin lets you create a URL which you can set
as the Webhook POST Url in Mautic. Then click the Apply button to save it and then click the Send Test Payload button. That will send a test
payload data to RequestBin and you will be able to see it at your RequestBin.
When you have created your testing webhook, you can test the real data it sends when a dened action is triggered.
This lag can be more visible when you do a CSV import. It may be slow when it is waiting a second or two for webhook response for every
imported contact.
If you want to avoid this lag, congure the webhook queue in the conguration and add this command to your cron tab: app/console mau
tic:webhooks:process . This way every time the webhook is triggered, the action is queued as a new row into database, so it is much faster
and then the command will make the requests which may take some time. The caveat to this optimisation is that the webhooks are not red
every time the action happens, but every time the command runs.
<?php
// webhookTest.php
https://developer.mautic.org/#plugin-directory-structure 216/222
17/12/2017 Mautic Developer Documentation
/**
* A helper class to log and get the Mautic webhook request
*/
class webhookTest {
/**
* Log a message to a file
*
* @param mixed $message
* @param string $type [info|error|request]
*/
public function log($message, $type = 'info')
{
$prefix = 'webhookLog_';
$file = $type . '.log';
$date = new DateTime();
error_log($date->format('Y-m-d H:i:s') . ' ' . $message . "\n\n", 3, $prefix . $file);
}
/**
* Get the request JSON object and log the request
*
* @return object
*/
public function getRequest()
{
$rawData = file_get_contents("php://input");
$this->log($rawData, 'request');
return json_decode($rawData);
}
}
$webhook = new webhookTest;
$requestData = $webhook->getRequest();
// @todo Process the $requestData as needed
If youd like to extend the webhook functionality with your plugin, read more in the plugin docs.
MauticJS API
Mautic provides a means for plugins to inject custom JavaScript into mtc.js, the PHP generated script that manages Mautics tracking pixel,
dynamic web content, etc. mtc.js is embedded in 3rd party websites to manage communication between those and Mautic.
mtc.js
<?php
// plugins/HelloWorldPlugin/Event/BuildJsSubscriber.php
namespace MauticPlugin\HelloWorldBundle\EventListener;
use Mautic\CoreBundle\CoreEvents;
use Mautic\CoreBundle\Event\BuildJsEvent;
/**
* Class BuildJsSubscriber
*/
class BuildJsSubscriber extends CommonSubscriber
{
/**
* @return array
https://developer.mautic.org/#plugin-directory-structure 217/222
17/12/2017 Mautic Developer Documentation
*/
public static function getSubscribedEvents()
{
return array(
CoreEvents::BUILD_MAUTIC_JS => array('onBuildJs', 0)
);
}
/**
* @param BuildJsEvent $event
*
* @return void
*/
public function onBuildJs(BuildJsEvent $event)
{
$js = <<<JS
MauticJS.documentReady(function() {
// Determine what planet this is coming from
});
JS;
$event->appendJs($js, 'HelloWorld');
}
}
To inject custom Javascript into mtc.js, use an event listener for the CoreEvents::BUILD_MAUTIC_JS event. This event receives a Mautic\Co
reBundle\Event\BuildJsEvent object where $event->appendJs($js, $sectionName); can be used to inject the scripts code.
Only native Javascript or MauticJs API functions should be used since jQuery and other libraries are not guaranteed to be
available in 3rd party websites.
If you wish execute additional code to execute as form is being processed create a MauticFormCallback object. In the example code
replace replaceWithFormName with the name of your form.
ONVALIDATE()
MauticFormCallback['replaceWithFormName'] = {
onValidate: function () {
// before form validation
var formIsGood = True;
var dontUpdate = False;
if(dontUpdate){
https://developer.mautic.org/#plugin-directory-structure 218/222
17/12/2017 Mautic Developer Documentation
return null;
}else if(formIsGood){
return True;
}else if(!formIsGood){
return False;
}
},
};
Called before default form validation and can be used to override default form validation.
Return True to skip the default form validation continue with form processing. Return False to skip the default form validation and prevent
the form submission. Return null to execute default form validation.
ONVALIDATESTART()
MauticFormCallback['replaceWithFormName'] = {
onValidateStart: function () {
// before default validation
},
};
Called at the beginning of the default form validation. Receives no values and return value is not required and not processed.
onValidateStart may not be executed if the default form validation is handled during the `onValidate` callback
ONVALIDATEEND(FORMVALID)
MauticFormCallback['replaceWithFormName'] = {
onValidateEnd: function (formValid) {
// before form submit
},
};
Called after all form validation is complete (default and/or onValidate callback) and before the form is submitted. Receives formValid to
determine if form is valid. Return value is not required and not processed.
ONERRORMARK(CALLBACKDATA)
var callbackData = {
containerId: containerId,
valid: valid,
validationMessage: callbackValidationMessage
};
MauticFormCallback['replaceWithFormName'] = {
onErrorMark: function (callbackData) {
// called during error marking
},
};
Called during error marking. Receives a callbackData object. Return True to skip the default error marking.
ONERRORCLEAR(CONTAINERID)
MauticFormCallback['replaceWithFormName'] = {
onErrorClear: function (containerId) {
// called to clear an existing error
},
};
https://developer.mautic.org/#plugin-directory-structure 219/222
17/12/2017 Mautic Developer Documentation
Called to clear an existing error. Receives containerId with the id of the element containing the error. Return True to skip the default error
clearing.
ONRESPONSE(RESPONSE)
MauticFormCallback['replaceWithFormName'] = {
onResponse: function (response) {
// called to process the response to the form submission
},
};
Called prior to default form submission response processing. Receives response containing the form submission response. Return True to
skip the default form submission response processing.
ONRESPONSESTART(RESPONSE)
MauticFormCallback['replaceWithFormName'] = {
onResponseStart: function (response) {
// called to process the response to the form submission
},
};
Called at the beginning default form submission response processing. Receives response containing the form submission response.
Return value is not required and not processed.
onResponseStart may not be executed if the default response processing is handled during the `onResponse` callback
ONRESPONSEEND(RESPONSE)
MauticFormCallback['replaceWithFormName'] = {
onResponseEnd: function (response) {
// called to process the response to the form submission
},
};
Called at the end default form submission response processing. Receives response containing the form submission response. Return
value is not required and not processed.
onResponseEnd may not be executed if the default response processing is handled during the `onResponse` callback
ONMESSAGESET(MESSAGEOBJECT)
var messageObject = {
message: message,
type: type
};
MauticFormCallback['replaceWithFormName'] = {
onErrorMark: function (messageObject) {
// called prior to default message insertion
},
};
Called prior to default message insertion. Receives a messageObject containing the message and message type. Return True to skip the
default message insertion.
https://developer.mautic.org/#plugin-directory-structure 220/222
17/12/2017 Mautic Developer Documentation
ONSUBMITBUTTONDISABLE(MESSAGEOBJECT)
MauticFormCallback['replaceWithFormName'] = {
onErrorMark: function (messageObject) {
// called prior to default message insertion
},
};
Called prior to default disabling of the submit button. Receives no values. Return True to skip the default disabling of the submit button.
ONSUBMITBUTTONENABLE()
MauticFormCallback['replaceWithFormName'] = {
onErrorMark: function (messageObject) {
// called prior to default message insertion
},
};
Called prior to default enabling of the submit button. Receives no values. Return True to skip the default enabling of the submit button.
This method will transform an object properties into a key=value string, concatenating them with an ampersand. It is used when submitting
data via MauticJS.makeCORSRequest.
MAUTICJS.DOCUMENTREADY(FUNCTIONNAME|FUNCTION)
This method will check if the document has nished rendering, then execute the given function. The function argument can be the name of
a function or an anonymous function.
function test() {
alert('test');
}
MauticJS.documentReady(test);
MAUTICJS.ITERATECOLLECTION(COLLECTION)(FUNCTIONNAME|FUNCTION)
This method will iterate over the provided collection (array, object, HTMLCollection, etc) using the provided function argument. The function
argument can be the name of a function or an anonymous function. The function will receive the collection node and the iteration number as
arguments.
https://developer.mautic.org/#plugin-directory-structure 221/222
17/12/2017 Mautic Developer Documentation
MAUTICJS.LOG(ARGUMENTS)
This method is a lightweight wrapper around console.log . It exists because some browsers do not provide this functionality. It takes any
number of arguments, logs them, then passes those same arguments to the console.log method if it exists.
MauticJS.log('Something happened');
MAUTICJS.CREATECORSREQUEST(METHOD, URL)
This method creates an XMLHttpRequest , then checks to see if it supports the withCredentials property. If not, we are probably on
windows, so it then checks for the existence of XDomainRequest , then creates it if found. Finally, it opens then returns the xhr. It can be used
to send cross domain requests that include the cookies for the domain. It is used internally within the MauticJS.makeCORSRequest method.
MauticJS.createCORSRequest('GET', 'https://mymautic.com/dwc/slot1');
This method uses MauticJS.createCORSRequest to open a cross domain request to the specied URL, then sets the callbackSuccess and
callbackError values appropriately. You may omit either of the callbacks. If you do, the callbacks are replaced with a basic function that uses
MauticJS.log(response) to log the response from the request. The callback methods receive the server response and the xhr object as
arguments. If the response is determined to be a JSON string, it is automatically parsed to a JSON object. The data argument will be
serialized using MauticJS.serialize(data) , then sent with the request to the server. All requests made this way have the X-Requested-
With header set to XMLHttpRequest .
MAUTICJS.PARSETEXTTOJSON(MAYBEJSON)
This method will take a text string and check to see if it is a valid JSON string. If so, it parses it into a JSON object and returns. If not, then it
will simply return the argument passed to it.
MAUTICJS.INSERTSCRIPT(SCRIPTURL)
This method will insert a script tag with the provided URL in the head of your document, before other scripts.
MauticJS.insertScript('http://google.com/ga.js');
https://developer.mautic.org/#plugin-directory-structure 222/222