diff --git a/.vale.ini b/.vale.ini index fda54427..b88c2b88 100644 --- a/.vale.ini +++ b/.vale.ini @@ -1,5 +1,5 @@ StylesPath = .github/styles Vocab = Mautic -MinAlertLevel = warning +MinAlertLevel = suggestion [*.{md,rst}] BasedOnStyles = Vale, Google, Mautic diff --git a/docs/components/cache.rst b/docs/components/cache.rst index 035d80c7..326c6966 100644 --- a/docs/components/cache.rst +++ b/docs/components/cache.rst @@ -1,4 +1,124 @@ Cache ##### +Symfony makes heavy use of a filesystem cache. When developing for Mautic, clearing the cache is a regular occurrence. By default, Mautic instances have the cache located in ``var/cache/ENV`` where ``ENV`` is the environment currently accessed - ``dev`` or ``prod``. To rebuild the cache, delete the relevant ``ENV`` folder within the cache directory, or run the Symfony command ``php bin/console cache:clear --env=ENV``. If a specific environment isn't passed to the command via ``--env=ENV``, Mautic uses the ``dev`` environment by default. + + +.. vale off + +In the ``dev`` environment, Mautic doesn't cache translations, views, and assets. However, changes to these files require clearing the cache for them to take effect in the ``prod`` environment. Changes to Mautic config files, Symfony config files, etc., require clearing of the cache regardless of the environment. + +.. vale on + +The typical rule of thumb is, if Mautic isn't 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 ``var/cache/ENV`` folder - replacing ENV with the environment e.g ``dev`` or ``prod`` - then run the command and/or browse to the site to rebuild. + +Cache bundle +************ + +Enables PSR-6 and PSR-16 caching. Check :xref:`Symfony Cache Component` + +Namespace versus tag +==================== + +This bundle introduces tags to the cache. All its adapters are fully tag aware which makes the use of namespace obsolete for daily use. + +Previously, if you wanted to keep control on cache section and didn't want to hold the index of all keys to clear, you would have to use namespace. + +The main disadvantage of this approach is that Mautic creates a new adapter for each namespace. + +From Symfony 3.4, the cache uses tag-aware adapters. If you want to clear all records related to your Bundle or Component, you just need to tag them. + +.. code-block:: php + + /** @var CacheProvider $cache */ + $cache = $this->get('mautic.cache.provider'); + /** @var CacheItemInterface $item */ + $item = $cache->getItem('test_tagged_Item'); + $item->set('yesa!!!'); + $item->tag(['firstTag', 'secondTag']); + $item->expiresAfter(20000); + +All you need to do now is to clear all tagged items: + +.. code-block:: php + + $cache->invalidateTags(['firstTag']); +Pools clearing +============== + +Removing cache items +-------------------- + +Cache Pools include methods to delete a cache item, some of them, or all of them. The most common is ``Psr\\Cache\\CacheItemPoolInterface::deleteItem``, which deletes the cache item identified by the given key. + +.. code-block:: php + + $isDeleted = $cache->deleteItem('user_'.$userId); +Use the ``Psr\\Cache\\CacheItemPoolInterface::deleteItems`` method to delete several cache items simultaneously - it returns true only if all the items have been deleted, even when any or some of them don't exist. + +Configuration +------------- + +Plugins come preconfigured to utilize filesystem caching. + +These are the default settings: + +.. code-block:: php + + 'cache_adapter' => 'mautic.cache.adapter.filesystem', + 'cache_prefix' => 'app', + 'cache_lifetime' => 86400 +They can be overridden in ``local.php`` like this: + +.. code-block:: php + + 'cache_adapter' => 'mautic.cache.adapter.redis', + 'cache_prefix' => 'app_cache', + 'cache_lifetime' => 86400, + +Delivered adapters +------------------ +.. vale off + +- ``mautic.cache.adapter.filesystem`` +- ``mautic.cache.adapter.memcached`` + +.. code-block:: php + 'memcached' => [ + 'servers' => ['memcached://localhost'], + 'options' => [ + 'compression' => true, + 'libketama_compatible' => true, + 'serializer' => 'igbinary', + ], + ], + +- ``mautic.cache.adapter.redis`` + +Redis configuration in ``local.php``: + +.. code-block:: php + + 'redis' => [ + 'dsn' => 'redis://localhost', + 'options' => [ + 'lazy' => false, + 'persistent' => 0, + 'persistent_id' => null, + 'timeout' => 30, + 'read_timeout' => 0, + 'retry_interval' => 0, + ], + ], + +In order to use another adapter, just set it up as a service. + +Clearing the cache +------------------ + +The ``cache:clear`` command clears Mautic's cache. Use this command: + +.. code-block:: bash + + bin/console mautic:cache:clear diff --git a/docs/components/forms.rst b/docs/components/forms.rst index be33e29a..41af7f22 100644 --- a/docs/components/forms.rst +++ b/docs/components/forms.rst @@ -32,6 +32,10 @@ To add a custom Form Field, use the ``$event->addFormField($identifier, $paramet - Required - string - View template used to render the ``formType``, for example ``HelloWorldBundle:SubscribedEvents\FormField:customfield.html.php`` + * - ``help`` + - Optional + - string + - The language string for providing a help text below the form element. * - ``formTypeOptions`` - Optional - array diff --git a/docs/form_hooks/getting_started.rst b/docs/form_hooks/getting_started.rst index 5e41a641..79238d4e 100644 --- a/docs/form_hooks/getting_started.rst +++ b/docs/form_hooks/getting_started.rst @@ -27,7 +27,7 @@ You can define hooks for multiple Forms using the API name of the Form as follow .. Note:: Define the Form hooks somewhere in the DOM before the code that loads the Form. -You'll need to view the HTML of the Form to find it's API name. The easiest way to do this is to browse to the Form's details in Mautic then click the "Manual Copy" button. Look for the following in the second box: +You'll need to view the HTML of the Form to find its API name. The easiest way to do this is to browse to the Form details in Mautic then click the 'Self-hosted' button. Look for the following in the second box: .. code-block:: html diff --git a/docs/index.rst b/docs/index.rst index 03a5b399..83eb42d1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -105,6 +105,7 @@ There are several ways to support Mautic other than contributing with code. plugins/data plugins/translations plugins/continuous-integration + plugins/from-4-to-5 .. toctree:: :maxdepth: 2 @@ -145,6 +146,7 @@ There are several ways to support Mautic other than contributing with code. rest_api/contacts rest_api/fields rest_api/notifications + rest_api/point_groups rest_api/reports rest_api/text_messages diff --git a/docs/links/doctrine_docs_orm.py b/docs/links/doctrine_docs_orm.py index cd9f2836..445c1cbf 100644 --- a/docs/links/doctrine_docs_orm.py +++ b/docs/links/doctrine_docs_orm.py @@ -2,6 +2,6 @@ link_name = "Doctrine ORM" link_text = "Doctrine ORM" -link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/index.html" +link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/index.html" link.xref_links.update({link_name: (link_text, link_url)}) diff --git a/docs/links/doctrine_docs_orm_annotations.py b/docs/links/doctrine_docs_orm_annotations.py index 04bb2f44..b651b610 100644 --- a/docs/links/doctrine_docs_orm_annotations.py +++ b/docs/links/doctrine_docs_orm_annotations.py @@ -2,6 +2,6 @@ link_name = "Doctrine ORM annotations" link_text = "Doctrine ORM annotations" -link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/annotations-reference.html" +link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/annotations-reference.html" link.xref_links.update({link_name: (link_text, link_url)}) diff --git a/docs/links/doctrine_docs_orm_php_mapping.py b/docs/links/doctrine_docs_orm_php_mapping.py index 28c14631..e2e48ead 100644 --- a/docs/links/doctrine_docs_orm_php_mapping.py +++ b/docs/links/doctrine_docs_orm_php_mapping.py @@ -2,6 +2,6 @@ link_name = "Doctrine ORM PHP mapping" link_text = "Doctrine ORM PHP mapping" -link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/php-mapping.html#classmetadatabuilder" +link_url = "https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/php-mapping.html#classmetadatabuilder" link.xref_links.update({link_name: (link_text, link_url)}) diff --git a/docs/links/mautic_php_to_twig.py b/docs/links/mautic_php_to_twig.py new file mode 100644 index 00000000..fff2e8dd --- /dev/null +++ b/docs/links/mautic_php_to_twig.py @@ -0,0 +1,7 @@ +from . import link + +link_name = "PHP to Twig migration" +link_text = "Upgrading PHP to Twig templates" +link_url = "https://github.com/mautic/mautic/blob/5.x/UPGRADE-PHP-TO-TWIG-TEMPLATES.md" + +link.xref_links.update({link_name: (link_text, link_url)}) diff --git a/docs/links/phpstan_baseline.py b/docs/links/phpstan_baseline.py new file mode 100644 index 00000000..45c3a3b0 --- /dev/null +++ b/docs/links/phpstan_baseline.py @@ -0,0 +1,7 @@ +from . import link + +link_name = "PHPSTAN baseline" +link_text = "PHPSTAN baseline" +link_url = "https://phpstan.org/user-guide/baseline" + +link.xref_links.update({link_name: (link_text, link_url)}) diff --git a/docs/links/symfony_cache_component.py b/docs/links/symfony_cache_component.py new file mode 100644 index 00000000..2a06aae1 --- /dev/null +++ b/docs/links/symfony_cache_component.py @@ -0,0 +1,7 @@ +from . import link + +link_name = "Symfony Cache Component" +link_text = "Symfony Cache Component" +link_url = "https://symfony.com/doc/current/components/cache.html" + +link.xref_links.update({link_name: (link_text, link_url)}) \ No newline at end of file diff --git a/docs/plugins/from-4-to-5.rst b/docs/plugins/from-4-to-5.rst new file mode 100644 index 00000000..7e759b43 --- /dev/null +++ b/docs/plugins/from-4-to-5.rst @@ -0,0 +1,124 @@ +Update Plugins for Mautic 5 +======================================= + +Here is a list of steps that most of the Plugins may need to take to upgrade from Mautic 4 to Mautic 5. You should be able to get through each step, make a commit, move to the next one and once you are at finished you have upgraded your Plugin. + +Continuous Integration +------------------------- + +If you don't have CI configured, this is the time to do it. This is an optional step but it makes sense to do it at the beginning rather than later. Here's how to get it done: :doc:`/plugins/continuous-integration`. + +In your PR add also support for PHP 8.1 and 8.2, and upgrade the Mautic version from 4.4 to 5.1. One more thing is that Mautic 5 have ``local.php`` in ``config/local.php`` instead of ``app/config/local.php`` so update that as well. + +Autowiring +------------- + +Mautic 5 comes with autowiring of PHP services which means the developer experience is much improved, and the code size is reduced. + +There is a great doc already written on this topic: :doc:`/plugins/autowiring` - so refer to that for instructions. + +To quickly verify that the wiring of services is complete and configured correctly you may find this command faster than refreshing the browser window: + +``rm -rf var/cache && bin/console`` + + .. note:: Ideally, you should be able to delete the whole ``services`` section from your ``config.php`` file, but do that as a cherry on top once you are sure everything is working as the later steps in this process may yet cause you difficulties. + +``config.php`` - controllers +--------------------------- + +``config.php`` should be much lighter now when all services are gone after autowiring is configured. There is one more thing to verify. The controllers are now defined with a different syntax. Here is an example: + +.. code:: diff + + - 'controller' => 'CronfigBundle:Cronfig:index', + + 'controller' => 'MauticPlugin\CronfigBundle\Controller\CronfigController::indexAction' + +Symfony 5 is much more explicit. That's a good thing even if it's longer. You don't have to guess what the syntax is. It's basically just standard FQCN (Fully Qualified Class Name) with the full method name behind the 2 colons. You don't even need to call the controller method `*Action` any more. + +Rendering views +------------------ + +As Symfony 5 removed the PHP templating engine, Mautic had to switch to Twig. Your Plugin must also update the any views from PHP to Twig. Here is a helpful resource on how to migrate the ``*.html.php`` files to ``*.html.twig`` files: + +:xref:`PHP to Twig migration` + +In the controllers, you'll also have to update the view paths like this: + +.. code:: diff + + - $this->renderView('MauticCoreBundle:Notification:flash_messages.html.php'); + + $this->renderView('@MauticCore/Notification/flash_messages.html.twig'); + +Running this command is faster than refreshing all the views in the browser. It validates the Twig syntax and can guide you through the process: + +``bin/console lint:twig plugins/MyBundle`` + +.. note:: Update MyBundle with your bundle name. + +.. vale off + +The Integration class +------------------------ + +.. vale on + + +If you went ahead and deleted all services from ``config.php``, you may experience problems if you're using Mautic's Integration classes and interfaces. The inner workings of the IntegrationsBundle expects that your Integration has a service key in a specific format. Mautic 6 aims to improve this, but for now, add an alias to ``services.php``: + +.. code:: php + + $services->alias('mautic.integration.[MY_INTEGRATION]', \MauticPlugin\[MY_INTEGRATION]Bundle\Integration\[MY_INTEGRATION]Integration::class); + +.. note:: Replace `[MY_INTEGRATION]` with your Plugin name. + +Compiler passes +------------------ + +If your Plugin uses a compiler pass, you may have to verify that it works correctly. In many cases you may have to change the service alias with FQCN like so: + +.. code:: diff + + - ->setDecoratedService('mautic.form.type.email', 'mautic.form.type.email.inner'); + + ->setDecoratedService(EmailType::class, 'mautic.form.type.email.inner') + +Getting container in tests +----------------------------- + +This one is a quick find and replace: + +.. code:: diff + + - $handlerStack = self::$container->get('mautic.http.client.mock_handler'); + + $handlerStack = static::getContainer()->get(MockHandler::class); + +Notice you can also use FQCN instead of string service keys which is more convenient. + +Automated refactoring +------------------------ + +Your Plugin should be working on Mautic 5 by now. Wouldn't it be great to shorten the code a little more? Mautic 5 uses PHP 8.0+ so can take advantage of the syntax. Rector can upgrade the code for you. + +Run ``bin/rector process plugins/MyBundle`` and review the changes. + +.. note:: Update MyBundle with your bundle name. + +Automated code style +----------------------- + +Another great way how to improve your Plugin code base quality is to run the CS Fixer: ``bin/php-cs-fixer fix plugins/MyBundle``. + +.. note:: Update MyBundle with your bundle name. + +Static analysis +------------------- + +PHPSTAN is another amazing tool that detects bugs for you. It's better to run it on the whole codebase including core Mautic, so it's aware of all classes. + +Run ``composer phpstan`` + +If your Plugin has more PHPSTAN errors than you can handle right now, consider using :xref:`PHPSTAN baseline`. It allows you to store your tech debt to a single file and it forces you to write better code from now on. And you can reduce the baseline by small chunks every month to get to 0. + +Conclusion +---------- + +This list of steps is compiled by Mautic Plugin developers for the Mautic Plugin developers. If you find that some common problem isn't addressed here, please add it. diff --git a/docs/rest_api/contacts.rst b/docs/rest_api/contacts.rst index 829a1d5a..2630a392 100644 --- a/docs/rest_api/contacts.rst +++ b/docs/rest_api/contacts.rst @@ -1055,6 +1055,316 @@ To subtract Points from a Contact and return a 404 if the Contact isn't found: "success": true } +.. vale off + +Get all Contact Point Groups scores +*********************************** + +.. vale on + +Get all Point Group scores for a specific Contact. + +.. vale off + +**HTTP Request** + +.. vale on + +``GET /api/contacts/{leadId}/points/groups`` + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "total": 1, + "groupScores": [ + { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + ] + } + +The response contains a list of Point Group scores for the Contact. + +.. vale off + +Get single Contact Point Group score +************************************ + +.. vale on + +Get the score for a specific Point Group for a Contact. + +.. vale off + +**HTTP Request** + +.. vale on + +``GET /api/contacts/{leadId}/points/groups/{groupId}`` + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response contains the score for the specified Point Group for the Contact. + +.. vale off + +Add Contact Point Group Score +***************************** + +.. vale on + +Add Points to a specific Point Group for a Contact. + +.. vale off + +**HTTP Request** + +.. vale on + + +``POST /api/contacts/{leadId}/points/groups/{groupId}/plus/{value}`` + +**Data Parameters (optional)** + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - ``eventname`` + - Name of the event + * - ``actionname`` + - Name of the action + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response indicates the success of adding Points to the specified Point Group for the Contact. + +.. vale off + +Subtract Contact Point Group score +********************************** + +.. vale on + +Subtract Points from a specific Point Group for a Contact. + +.. vale off + +**HTTP Request** + +.. vale on + +``POST /api/contacts/{leadId}/points/groups/{groupId}/minus/{value}`` + +**Data Parameters (optional)** + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - ``eventname`` + - Name of the event + * - ``actionname`` + - Name of the action + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response indicates the success of subtracting Points from the specified Point Group for the Contact. + +.. vale off + +Set Contact Point Group Score +***************************** + +.. vale on + +Set the Points for a specific Point Group for a Contact. + +.. vale off + +**HTTP Request** + +.. vale on + +``POST /api/contacts/{leadId}/points/groups/{groupId}/set/{value}`` + +**Data Parameters (optional)** + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - ``eventname`` + - Name of the event + * - ``actionname`` + - Name of the action + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response indicates the success of setting the Points for the specified Point Group for the Contact. + +.. vale off + +Divide Contact Point Group score +******************************** + +.. vale on + +Divide the Points of a specific Point Group for a Contact by a value. + +.. vale off + +**HTTP Request** + +.. vale on + +``POST /api/contacts/{leadId}/points/groups/{groupId}/divide/{value}`` + +**Data Parameters (optional)** + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - ``eventname`` + - Name of the event + * - ``actionname`` + - Name of the action + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response indicates the success of dividing the Points of the specified Point Group for the Contact by the specified value. + +.. vale off + +Multiply Contact Point Group score +********************************** + +.. vale on + +Multiply the Points of a specific Point Group for a Contact by a value. + +.. vale off + +**HTTP Request** + +.. vale on + +``POST /api/contacts/{leadId}/points/groups/{groupId}/times/{value}`` + +**Data Parameters (optional)** + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - ``eventname`` + - Name of the event + * - ``actionname`` + - Name of the action + +**Response** + +``Expected Response Code: 200`` + +.. code-block:: json + + { + "groupScore": { + "score": 21, + "group": { + "id": 6, + "name": "A" + } + } + } + +The response indicates the success of multiplying the Points of the specified Point Group for the Contact by the specified value. + + .. vale off List Available Owners diff --git a/docs/rest_api/point_groups.rst b/docs/rest_api/point_groups.rst new file mode 100644 index 00000000..b4b41d0c --- /dev/null +++ b/docs/rest_api/point_groups.rst @@ -0,0 +1,334 @@ +.. vale off + +Point Groups +############ + +.. vale on + +Use this endpoint to manage Contact Point Groups in Mautic. + +.. code-block:: php + + newAuth($settings); + $apiUrl = "https://your-mautic.com"; + $api = new MauticApi(); + $pointGroupApi = $api->newApi("pointGroups", $auth, $apiUrl); + +.. vale off + +Get Point Group +*************** + +.. vale on + +.. code-block:: php + + get($id); + +.. code-block:: json + + "pointGroup": { + "id": 47, + "name": "Group A", + "description": "This is my first Point Group created via API.", + "isPublished": true, + "dateAdded": "2024-02-29T12:17:52+00:00", + "dateModified": null, + "createdBy": 2, + "createdByUser": "Admin User", + "modifiedBy": null, + "modifiedByUser": null, + } + +Get an individual Point Group by ID. + +.. vale off + +**HTTP Request** + +.. vale on + +``GET /points/groups/ID`` + + +**Response** + + +``Expected Response Code: 200`` + +See JSON code example. + +**Point Group Properties** + +.. list-table:: + :header-rows: 1 + + * - Name + - Type + - Description + * - ``id`` + - int + - ID of the Point Group + * - ``name`` + - ``string`` + - Point Group name + * - ``description`` + - ``string`` + - Point Group description + * - ``isPublished`` + - ``boolean`` + - Whether the Point Group is published + * - ``dateAdded`` + - ``datetime`` + - Date/time Point Group was created + * - ``createdBy`` + - ``int`` + - ID of the User that created the Point Group + * - ``createdByUser`` + - ``string`` + - Name of the User that created the Point Group + * - ``dateModified`` + - ``datetime/null`` + - Date/time Point Group was last modified + * - ``modifiedBy`` + - ``int`` + - ID of the User that last modified the Point Group + * - ``modifiedByUser`` + - ``string`` + - Name of the User that last modified the Point Group + +.. vale off + +List Contact Point Groups +************************* + +.. vale on + +.. code-block:: php + + getList($searchFilter, $start, $limit, $orderBy, $orderByDir, $publishedOnly, $minimal); + +.. code-block:: json + + { + "total": 4, + "pointGroups": [ + { + "id": 47, + "name": "Group A", + "description": "This is my first Point Group created via API.", + "isPublished": true, + "dateAdded": "2024-02-29T12:17:52+00:00", + "dateModified": null, + "createdBy": 2, + "createdByUser": "Admin User", + "modifiedBy": null, + "modifiedByUser": null + }, + ... + ] + } + +.. vale off + +**HTTP Request** + +.. vale on + + +``GET /points/groups`` + +**Response** + +``Expected Response Code: 200`` + +See JSON code example. + +**Point Group Properties** + +.. list-table:: + :header-rows: 1 + + * - Name + - Type + - Description + * - ``total`` + - ``int`` + - Count of all Point Groups + * - ``id`` + - ``int`` + - ID of the Point Group + * - ``name`` + - ``string`` + - Point Group name + * - ``description`` + - ``string`` + - Point Group description + * - ``isPublished`` + - ``boolean`` + - Whether the Point Group is published + * - ``dateAdded`` + - ``datetime`` + - Date/time Point Group was created + * - ``createdBy`` + - ``int`` + - ID of the User that created the Point Group + * - ``createdByUser`` + - ``string`` + - Name of the User that created the Point Group + * - ``dateModified`` + - ``datetime/null`` + - Date/time Point Group was last modified + * - ``modifiedBy`` + - ``int`` + - ID of the User that last modified the Point Group + * - ``modifiedByUser`` + - ``string`` + - Name of the User that last modified the Point Group + + +.. vale off + +Create Point Group +****************** + +.. vale on + +.. code-block:: php + + 'Group A', + 'description' => 'This is my first Point Group created via API.' + ]; + + $pointGroup = $pointGroupApi->create($data); + +.. vale off + +**HTTP Request** + +.. vale on + + +``POST /points/groups/new`` + +.. vale off + +**Post Parameters** + +.. vale on + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - name + - Point Group name is the only required field + * - description + - A description of the Point Group. + +**Response** + +``Expected Response Code: 201`` + +**Properties** + +Same as `Get Point Group`. + +.. vale off + +Edit Point Group +**************** + +.. vale on + +.. code-block:: php + + 'New Point Group name', + 'description' => 'Updated description of the Point Group.' + ]; + + $pointGroup = $pointGroupApi->edit($id, $data); + +.. vale off + +**HTTP Request** + +.. vale on + +``PATCH /points/groups/ID/edit`` + +.. vale off + +**Post Parameters** + +.. vale on + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - name + - Point Group name is the only required field + * - description + - A description of the Point Group. + +**Response** + +``Expected Response Code: 200`` + +**Properties** + +Same as `Get Point Group`. + +.. vale off + +Delete Point Group +****************** + +.. vale on + +.. code-block:: php + + delete($id); + +Delete a Point Group. + +.. vale off + +**HTTP Request** + +.. vale on + + +``DELETE /points/groups/ID/delete`` + +**Response** + +``Expected Response Code: 200`` + +**Properties** + +Same as `Get Point Group`. \ No newline at end of file diff --git a/docs/themes/forms.rst b/docs/themes/forms.rst index 849db166..c8bccc0d 100644 --- a/docs/themes/forms.rst +++ b/docs/themes/forms.rst @@ -3,11 +3,33 @@ Customizing Forms To provide custom Form field templates or to manipulate the Form body, create the following directory structure:: + Field/ <– for customizing form field types html/ - MauticFormBundle - Builder <– for customizing the form structure itself - Field <– for customizing form field types + MauticFormBundle/ + Builder/ + _style.html.twig <– for customizing CSS for Form + form.html.twig <– for customizing the form structure itself -Copy from ``app/bundles/FormBundle/Views/Builder/form.html.php`` into the Theme’s Builder directory and/or one or more of the fields templates in ``app/bundles/FormBundle/Views/Field/*.html.php`` into the Theme’s `field` directory. Then customize to the desired layout. Note that these must be PHP templates. +Copy from ``app/bundles/FormBundle/Resources/views/form.html.twig`` into the Theme’s Builder directory and/or one or more of the fields templates in ``app/bundles/FormBundle/Views/Field/*.html.php`` into the Theme’s `field` directory. Then customize to the desired layout. -You can add a custom style sheet to the Form by adding a ``style.html.twig`` with your custom CSS to ``html/MauticFormBundle/Builder``. The best way is to copy the content of the default Form styles and modify them to your needs. +You can add a custom style sheet to the Form by adding a ``_style.html.twig`` with your custom CSS to ``html/MauticFormBundle/Builder``. The best way is to copy the content of the default Form styles and modify them to your needs. + +Customize field types +********************* + +Create a new template in the `Field` directory to change HTML generated by field types. +The best way is to copy the original template from `app/bundles/FormBundle/Resources/views/Field/*.html.twig` and modify it. + + +How to modify templates including base `text.html.twig` template +================================================================ + +Several templates are including the base `text.html.twig` template so you may need modify it. In that case you also need to modify templates including it. Change the `include` statement. + +For example `email.html.twig` including: + + {{ include('@MauticForm/Field/text.html.twig', { ... + +you need change `@MauticForm` to you theme, for example: + + {{ include('@themes/MyTheme/Field/text.html.twig', { ... \ No newline at end of file