Skip to content

Home > Developer Guide > Framework > Mixins

Mixins: Standard mixins

???+ tldr "About this document"

This page presents ___the standard library of pre-built mixins___. It assumes you have read about [___the general concepts___](index.md).

Introduction

The "standard mixins" are published by CiviCRM. Standard mixins aim to be short, simple, and portable. They have additional testing and tooling to provide consistent support over time.

It is often safe to copy a standard mixin and run it on an older environment. For example, menu-xml@1.0.0 is distributed with CiviCRM 5.45+ -- but it also works on CiviCRM 5.27. This is called "backporting". If you manage your extension with civix, then backporting is automatic.

List of mixins

Name Minimum Compatible CiviCRM Distributed Since CiviCRM Description
afform-entity-php@1.0.0 5.31 5.50 Scan afformEntities/*.php. Register via internal event.
ang-php@1.0.0 5.27 5.45 Scan ang/*.ang.php. Register via hook_angularModules.
case-xml@1.0.0 5.27 5.45 Scan xml/case/*.xml. Register via hook_caseTypes.
entity-types-php@1 5.45 5.57 Scan xml/schema/**.entityType.php. Register via hook_entityTypes.
menu-xml@1.0.0 5.27 5.45 Scan xml/Menu/*.xml. Register with Menu-Router via hook_xmlMenu.
mgd-php@1.0.0 5.27 5.45 Scan **/*.mgd.php. Register via hook_managed.
mgd-php@1.1.0 5.27 5.50 As above, with extra performance optimization.
scan-classes@1.0.0 5.51 5.52 Scan CRM/**.php and Civi/**.php for key interfaces and annotations. Register via hook_scanClasses.
scan-classes@1.1.0 5.51 5.63 As above, minus a special PHPUnit quirk
setting-php@1.0.0 5.27 5.45 Scan settings/*.setting.php. Register via hook_alterSettingsFolders.
smarty-v2@1.0.0 5.27 5.59 Add templates/**.tpl to Smarty. Register via hook_config.
smarty-v2@1.0.1 5.27 5.60 As above, with slightly different internal API.
theme-php@1.0.0 5.27 5.45 Scan **/*.theme.php. Register via hook_themes.

!!! tip "This table is representative. It may not be completely up-to-date. For an authoritative list of standard mixins, browse civicrm-core:mixin/ and civix:mixin-backports.php."

Civix support

civix is a tool to help extension-developers. It includes built-in support for standard mixins:

  • When you make a new extension, some common mixins are enabled by default.
  • When you generate new skeletal code, it will auto-enable any required mixins. (For example, civix generate:page will auto-enable menu-xml@1.)
  • When you run civix upgrade, it may suggest enabling or disabling specific mixins.
  • If your <compatibility> targets an older version of CiviCRM, then civix will automatically include polyfills and backports.
  • The command civix mixin can be used to view, enable, and disable mixins.

    ```bash

    List the standard mixins. Report on whether they are active.

    civix mixin

    Enable all standard mixins

    civix mixin --enable-all

    Enable specific mixins

    civix mixin --enable=ang-php@1,setting-php@1

    Disable specific mixins

    civix mixin --disable=ang-php@1

    Reset the mixins.

    civix mixin --disable-all --enable=mgd-php@1 ```

!!! info "Civix only supports mixins identified by civix:mixin-backports.php."

Quality assurance

Suppose you want to develop a new standard mixin that's available to other extension-developers. This is much like developing a basic mixin... but harder. Standard mixins need to work across a range of use-cases:

  • Applied to core extensions and contrib extensions
  • Distributed via core tarball and via backport
  • Activated (and deactivated) during installation (and uninstallation)
  • Executed via web and CLI and E2E-test and headless-test
  • Mixed and matched with other standard-mixins

Quality assurance is oriented around an example extension named shimmy. shimmy is not a regular extension. It is dynamically re-generated numerous times. Each time, it uses a different set of mixin options, and it's put through a series of installation and uninstallation tests. This is a brutal process designed to find (and prevent) subtle discrepancies in how mixins interact with system-services and system-caches.

To run the full suite (with all the permutations of shimmy), use this script:

./tools/mixin/bin/test-all

test-all is important for the CI server, but it's an entire suite of tests. If you are trying to debug a specific problem, then you'll need to focus on one instance of shimmy. To do this, pick a folder where you will put shimmy and then run the mixer command.

SHIMMY=$(cv path -c extensionsDir/example-mixin)
./tools/mixin/bin/mixer create -f --bare "$SHIMMY" mgd-php@1 smarty-v2@1

??? question "What are the options in this command?"

* `SHIMMY` is the folder where it will put the extension
* `mixer` is the command that generates the extension
* `-f` forces the command to overwrite any pre-existing content in that path
* `--bare` indicates that you just want to make a lightweight version of the extension. (You are not testing backports.)
* `mgd-php@1 smarty-v2@1` are two mixins that we want to focus on

??? warning "Pick one SHIMMY folder and stick to it."

If you generate two copies of `shimmy` (in different folders), then this will quickly become confusing.

The example above is chosen to match the `test-all` script.

??? question "What does the example extension look like?"

After creating this folder, you can inspect it:

```
find $SHIMMY -type f
```

You should see something that resembles a regular extension:

```
/srv/web/sites/default/files/civicrm/ext/example-mixin/info.xml
/srv/web/sites/default/files/civicrm/ext/example-mixin/shimmy.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/shimmy.civix.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/phpunit.xml.dist
/srv/web/sites/default/files/civicrm/ext/example-mixin/CRM/ShimmyGroup.mgd.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/CRM/BunnyDance.mgd.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/tests/mixin/ManagedCaseTypeTest.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/tests/mixin/ManagedTest.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/tests/mixin/SmartyTest.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/tests/phpunit/E2E/Shimmy/LifecycleTest.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/tests/phpunit/bootstrap.php
/srv/web/sites/default/files/civicrm/ext/example-mixin/templates/CRM/Shimmy/Example.tpl
```

??? question "Where does the example code come from?"

We asked mixer to focus on `mgd-php@1` and `smarty-v2@1`, so it pulled from these sources:

* `mixin/mgd-php@1/example/` - Example data for `mgd-php`
* `mixin/smarty-v2@1/example/` - Example data for `smarty-v2`
* `tests/extensions/shimmy/` - Common boilerplate

Now, you have a regular extension. You can run tests in the usual ways:

cd "$SHIMMY"
phpunit9 --group e2e
phpunit9 --group headless

??? question "How do I run the test in PHPStorm?"

If PhpStorm is already configured to run core tests, then:

* In the `SHIMMY` folder, open `tests/phpunit/E2E/Shimmy/LifecycleTest.php`
* Select a specific test, such as `testLifecycleWithLocalFunctions`.
    * (If you have freedom to choose, then use this -- it's easier to debug.)
* Run this test like usual. It will fail.
* Update the test options ("Run > Edit Configurations"). Find "LifecycleTest" and update it:
    * The workdir should match `SHIMMY` folder
    * The PHPUnit XML file should come from the `SHIMMY` folder.
    * The environment should **not** set `CIVICRM_UF`
* Run this test again. It should execute.