Configuring your entity - UltimateModuleCreator/umc-crud GitHub Wiki
Let's say you have your entity in place. You have your data interface, your model, your db schema.
The first thing you need to do is to create your ui config.
For this you need create a virtual type from Umc\Crud\Ui\EntityUiConfig
which is a set of getters for different types of messages. This should be done in etc/adminhtml/etc.xml
<virtualType name="[Entity]UiConfig" type="Umc\Crud\Ui\EntityUiConfig">
<arguments>
<argument name="interface" xsi:type="string">\[Vendor]\[Module]\Api\Data\[Entity]Interface</argument> <!-- here you put the data interface for your entity -->
<!-- The following fields are not mandatory. if not supplied, some default values will be used -->
<argument name="data" xsi:type="array">
<item name="name_attribute" xsi:type="string">title</item><!-- this is the attribute / field name that represents your entity -->
<item name="labels" xsi:type="array">
<!-- Label for the list "back" button-->
<item name="back" xsi:type="string" translatable="true">Back to list</item>
<!-- Label for the form "Save" button-->
<item name="save" xsi:type="string" translatable="true">Save Something</item>
<!-- Label for the form "save and duplicate" button-->
<item name="save_and_duplicate" xsi:type="string" translatable="true"><![CDATA[Save & Duplicate Something]]></item>
<!-- Label for the form "save and close button" button-->
<item name="save_and_close" xsi:type="string" translatable="true"><![CDATA[Save & Go to list]]></item>
<!-- Label for the "delete" button-->
<item name="delete" xsi:type="string" translatable="true">Delete entity</item>
<!-- confirmation message when you are trying to delete an entity instance-->
<item name="delete_message" xsi:type="string" translatable="true">Are you sure you want to delete something?</item>
</item>
<item name="save" xsi:type="array">
<!-- uncomment lines below to remove the "Save and close" and "Save and duplicate" buttons -->
<!--<item name="allow_close" xsi:type="boolean">false</item>-->
<!--<item name="allow_duplicate" xsi:type="boolean">false</item>-->
</item>
<item name="list" xsi:type="array">
<!-- Page title for the list page-->
<item name="page_title" xsi:type="string" translatable="true">Entities</item>
</item>
<item name="messages" xsi:type="array">
<item name="delete" xsi:type="array">
<!-- success message when deleting an entity-->
<item name="success" xsi:type="string" translatable="true">Entity successfully deleted</item>
<!-- error message when deleting a missing entity-->
<item name="missing_entity" xsi:type="string" translatable="true">Couldn't find something to delete</item>
<!-- general error message when deleting an entity-->
<item name="error" xsi:type="string" translatable="true">There was a problem deleting something</item>
</item>
<item name="save" xsi:type="array">
<!-- success message when saving an entity-->
<item name="success" xsi:type="string" translatable="true">Entity successfully saved</item>
<!-- general error message when saving an entity-->
<item name="error" xsi:type="string" translatable="true">There was a problem saving something</item>
<!-- success message when duplicating an entity-->
<item name="duplicate" xsi:type="string" translatable="true">Entity duplicated successfully</item>
</item>
<item name="mass_delete" xsi:type="array">
<!-- success message when mass deleting entities-->
<item name="success" xsi:type="string" translatable="true">%1 something(s) were successfully deleted</item>
<!-- error message when mass deleting entities-->
<item name="error" xsi:type="string" translatable="true">There was a problem deleting something</item>
</item>
</item>
</argument>
</arguments>
</virtualType>
All controllers you create will look the same. They will just extend the proper corresponding controller from the Umc_Crud module and will implement the proper action interface (HttpGetActionInterface
or HttpPostActionInterface
)
Sometimes the data sent via controllers do not map exactly to your table schema so you need to do some data processing in order to make it work.
This is needed in case your entity has multiple select fields, or file uploads or dynamic rows records
if you have multiselect fields construct a virtual type for processing them on save
<virtualType name="[Entity]SaveMultiselectProcessor" type="Umc\Crud\Ui\Form\DataModifier\Multiselect">
<arguments>
<argument name="fields" xsi:type="array">
<item name="field1" xsi:type="string">field1</item>
<!-- add here the names of all your multiselect fields -->
</argument>
</arguments>
</virtualType>
and one for processing them from the db to the form
<virtualType name="[Entity]FormMultiselectModifier" type="Umc\Crud\Ui\Form\DataModifier\Multiselect">
<arguments>
<argument name="fields" xsi:type="array">
<item name="field1" xsi:type="string">field1</item>
<!-- add here the names of all your multiselect fields -->
</argument>
</arguments>
</virtualType>
If you have dynamic rows construct a virtual type for processing them before saving
<virtualType name="[Entity]SaveDynamicRowsProcessor" type="Umc\Crud\Ui\SaveDataProcessor\DynamicRows">
<arguments>
<argument name="fields" xsi:type="array">
<item name="field_name_here" xsi:type="string">field_name_here</item>
<!-- add here the names of all your dynamic rows fields -->
</argument>
</arguments>
</virtualType>
and one for processing from db to form
<virtualType name="[Entity]UiFormDynamicRowsModifier" type="Umc\Crud\Ui\Form\DataModifier\DynamicRows">
<arguments>
<argument name="fields" xsi:type="array">
<item name="serialized_field" xsi:type="string">serialized_field</item>
</argument>
</arguments>
</virtualType>
if you have image uploads it gets a little more complicated.
You need 1 virtual type for upload, 1 for image info, 1 for saving and one for transforming from db format to form.
the file info model needs to be declared in etc/di.xml
because you might need it on frontend also
<virtualType name="[Entity]ImageInfo" type="Umc\Crud\Model\FileInfo">
<arguments>
<argument name="filePath" xsi:type="string">path/where/files/are/uploaded</argument>
</arguments>
</virtualType>
The uploader model should look like this
<virtualType name="[Entity]ImageUploader" type="Umc\Crud\Model\Uploader">
<arguments>
<argument name="baseTmpPath" xsi:type="string">tmp/path/for/image/upload</argument>
<argument name="basePath" xsi:type="string">real/path/for/image/upload</argument>
<argument name="allowedExtensions" xsi:type="array">
<item name="jpg" xsi:type="string">jpg</item>
<item name="jpeg" xsi:type="string">jpeg</item>
<item name="gif" xsi:type="string">gif</item>
<item name="png" xsi:type="string">png</item>
</argument>
</arguments>
</virtualType>
Now you can use the 2 above in the save data processor
<virtualType name="[Entity]SaveImageProcessor" type="Umc\Crud\Ui\SaveDataProcessor\Upload">
<arguments>
<argument name="fileInfo" xsi:type="object">[Entity]ImageInfo</argument>
<argument name="uploader" xsi:type="object">[Entity]ImageUploader</argument>
<argument name="fields" xsi:type="array">
<item name="image" xsi:type="string">image</item>
<!- list here all the entity fields that are image uploads -->
</argument>
</arguments>
</virtualType>
...and in the form data convertor
<virtualType name="EntityUiFormImageModifier" type="Umc\Crud\Ui\Form\DataModifier\Upload">
<arguments>
<argument name="uploader" xsi:type="object">[Entity]ImageUploader</argument>
<argument name="fileInfo" xsi:type="object">[Entity]ImageInfo</argument>
<argument name="fields" xsi:type="array">
<item name="image" xsi:type="string">image</item>
<!- list here all the entity fields that are image uploads -->
</argument>
</arguments>
</virtualType>
For date or date-time fields you need only conversion from form to db.
<virtualType name="[Entity]SaveDateProcessor" type="Umc\Crud\Ui\SaveDataProcessor\Date">
<arguments>
<argument name="fields" xsi:type="array">
<item name="field1" xsi:type="string">field1</item>
<!- list here all the entity fields that are dates -->
</argument>
</arguments>
</virtualType>
Now that you have data processors for all your field types, let's aggregate them into one big data processor
<virtualType name="[Entity]SaveDataProcessor" type="Umc\Crud\Ui\SaveDataProcessor\CompositeProcessor">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="date" xsi:type="object">[Entity]SaveDateProcessor</item><!-- if you have date / date-time fields -->
<item name="multiselect" xsi:type="object">[Entity]SaveMultiselectProcessor</item><!-- if you have multiselects -->
<item name="image" xsi:type="object">[Entity]SaveImageProcessor</item> <!-- if you have uploads -->
<item name="dynamicRows" xsi:type="object">[Entity]SaveDynamicRowsProcessor</item><!-- if you have dynamic rows -->
</argument>
</arguments>
</virtualType>
and into one big processor from db to form
<virtualType name="[Entity]FormDataModifier" type="Umc\Crud\Ui\Form\DataModifier\CompositeDataModifier">
<arguments>
<argument name="modifiers" xsi:type="array">
<!-- add here all form data modifiers -->
<item name="multiselect" xsi:type="object">[Entity]FormMultiselectModifier</item><!-- if you have multiselects -->
<item name="image" xsi:type="object">[Entity]UiFormImageModifier</item><!-- if you have image uploads -->
<item name="dynamicRows" xsi:type="object">[Entity]UiFormDynamicRowsModifier</item><!-- if you have dynamic rows fields -->
</argument>
</arguments>
</virtualType>
namespace [Vendor]\[Module]\Controller\Adminhtml\[Entity];
use Magento\Framework\App\Action\Http[Get|Post]ActionInterface;
class [ControllerType] extends \Umc\Crud\Controller\Adminhtml\[ControllerType] implements Http[Get|Post]ActionInterface
{
public const ADMIN_RESOURCE = 'id of the acl resource in your acl.xml';
}
Create the controller in Controller/Adminhtml/[Entity]/Index
that looks like this:
namespace [Vendor]\[Module]\Controller\Adminhtml\[Entity];
use Magento\Framework\App\Action\HttpGetActionInterface;
class Index extends \Umc\Crud\Controller\Adminhtml\Index implements HttpGetActionInterface
{
public const ADMIN_RESOURCE = 'id of the acl resource in your acl.xml';
}
And configure it in etc/adminhtml/di.xml
<type name="[Vendor]\[Module]\Controller\Adminhtml\[Entity]\Index">
<arguments>
<!-- the name of the virtual type created above -->
<argument name="uiConfig" xsi:type="object">[Entity]UiConfig</argument>
</arguments>
</type>
Just create the controller as instructed above. This has no configuration
Create the controller as instructed above.
Configure it via etc/adminhtml/di.xml
<type name="[Vendor]\[Module]\Controller\Adminhtml\[Entity]\Edit">
<arguments>
<!-- the name of the virtual type created above -->
<argument name="uiConfig" xsi:type="object">[Entity]UiConfig</argument>
<!-- This is a proxy class over the repository class. Don't worry it will be autogenerated you don't need to write it. -->
<argument name="entityUiManager" xsi:type="object">[Vendor]\[Module]\Model\[Entity]UiManager</argument>
</arguments>
</type>
Create controller as instructed above Configure it via etc/adminhtml/di.xml
<type name="[Vendor]\[Module]\Controller\Adminhtml\[Entity]\Delete">
<arguments>
<!-- the name of the virtual type created above -->
<argument name="uiConfig" xsi:type="object">[Entity]UiConfig</argument>
<!-- This is a proxy class over the repository class. Don't worry it will be autogenerated you don't need to write it. -->
<argument name="entityUiManager" xsi:type="object">[Vendor]\[Module]\Model\[Entity]UiManager</argument>
</arguments>
</type>
Create controller as instructed above Configure it via etc/adminhtml/di.xml
<type name="[Vendor]\[Module]\Controller\Adminhtml\[Entity]\MassDelete">
<arguments>
<argument name="uiConfig" xsi:type="object">[Entity]UiConfig</argument>
<!-- This is a proxy class over the repository class. Don't worry it will be autogenerated you don't need to write it. -->
<argument name="entityUiManager" xsi:type="object">[Vendor]\[Module]\Model\[Entity]UiManager</argument>
<!--this class is autogenerated also. it provides the list of entities to be mass deleted-->
<argument name="collectionProvider" xsi:type="object">[Vendor]\[Module]\Model\[Entity]UiCollectionProvider</argument>
</arguments>
</type>
Create controller as instructed above
Configure it via etc/adminhtml/di.xml
<type name="[Vendor]\[Module]\Controller\Adminhtml\[Entity]\InlineEdit">
<arguments>
<argument name="entityUiManager" xsi:type="object">[Vendor]\[Module]\Model\SomethingElseUiManager</argument>
<argument name="dataProcessor" xsi:type="object">[Entity]SaveDataProcessor</argument><!-- virtual type created above with all the data modifiers-->
<!-- in case you don't have any special fields you can use this null processor that does not modify your data-->
<!-- <argument name="dataProcessor" xsi:type="object">Umc\Crud\Ui\SaveDataProcessor\NullProcessor</argument> -->
<argument name="uiConfig" xsi:type="object">[Entity]ElseUiConfig</argument>
</arguments>
</type>
Create controller as instructed above
Configure it via etc/adminhtml/di.xml
<type name="[Vendor][Module]\Controller\Adminhtml\Something\Save">
<arguments>
<!-- this is autogenerated -->
<argument name="entityUiManager" xsi:type="object">[Vendor][Module]\Model\SomethingUiManager</argument>
<argument name="dataProcessor" xsi:type="object">[Entity]SaveDataProcessor</argument><!-- virtual type created above to process all special fields before save-->
<argument name="uiConfig" xsi:type="object">[Entity]UiConfig</argument><!--entity ui config created at step 1 -->
</arguments>
</type>