Pimcore 5: Is there a way to control allowed hierarchy of data objects? - pimcore

Assume if have the following structure of pimcore 5 data objects:
Products (folder)
Category A (custom class 'category')
Category AB (Custom class 'category')
Product A (Custom class 'product')
...
Category B (custom class 'category')
Product B (Custom class 'product')
Settings (folder)
...
By default the admin can add any class anywhere in the data objects area of pimcore, so in theory he can add a product under the the folder 'Settings', or a category under a product, but i want to prevent this, so he only can add 'category' in the products folder or another 'category', and so he only can add 'product' within a 'category' parent.
Is there a way to configure such a 'allowed child classes' system for the pimcore 5 data objects?
EDIT
With 'a way to configure' i do not necessary mean some solution provided by the admin interface, a solution requiring php coding is fine too.

The easiest way would be to use Custom Views (https://pimcore.com/docs/5.0.x/Objects/Object_Classes/Class_Settings/Custom_Views.html). Unfortunately, this would require separate panels for Settings and Products folder.
If you want this behaviour in single Objects panel, you'd have to code in PHP and in ExtJS. You'll need to override pimcore.object.tree.onTreeNodeContextmenu
method in web/pimcore/static6/js/pimcore/object/tree.js.

Related

Split Model declaration among several app in Django

I am working and building my website with Django and I am facing this logical issue.
My project is made by several app.
I would like to declare in each one of these a "piece" of a bigger model that will be represented in one single table-
Example:
model Person
model DetailsPerson
As each single app specifies a specific part of the person, my idea was to decentralize the declaration of DetailsPerson model so that they figure in one single table but each app enlarge the fields the app needs to work.
Is this possible?
EDIT 25/11/2021: here is a graphical representation of how I would like my models be working like
I would like to declaire, "to detail" the table Person adding in various app the fields the app itself introduce. In this way I can have a single table with various fields, introduced time by time as I create new apps into my project.
Is this possible? My aim is to keep only one table.
I tried with Nechoj's first solution but declairing Person(models.Model) and then in another app PsysicalModel(Person) adding field_1 and field_2 and then makemigrations and migrate doesn't fill my table with field_1 and field_2 but leaves the table with only id_person, birthdate and city.
Class Inheritance
You can use class inheritance, like
class Person(models.Model):
(fields)
# in other file, import this class an inherit
class PersonWithDetails(Person):
(add. fields)
EDIT: According to the docs on multitable inheritance this will create an additional table for PersonWithDetails that holds the additional fields. However, to the user it appears as if all data is stored in a single table. For example, filterand update queries work as expected:
PersonWithDetails.objects.filter(<some criteria>)
will return instances that contain all fields (both from Person and PersonWithDetails) as if all fields where stored in a single table PersonWithDetails. Furthermore, it is possible to select all persons irrespective of their details:
Person.objects.all()
will return all Person instances, including those that have been created as PersonWithDetails. If you have a Person instance p at hand, then you can check whether a special attribute is present and then know, whether this instance is also a PersonWithDetails:
if p.personwithdetails is not None:
p.personwithdetails.field_1
This example show how to acces fields of the PersinWithDetails if the instance at hand is Person.
OneToOneField
Another option is to use one-to-one relations.
class Person(models.Model):
(fields)
# in other file, import this class and do
class DetailsPerson(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE)
(additional fields)
In case of adding details to a Person class, I would prefer the second option.
ForeignKey
And if you want to have several different Detail classes to one Person, use ForeignKey:
class DetailsPerson1(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
(additional fields)
class DetailsPerson2(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
(additional fields)

Dividing an inline form into columns based on model field value in django admin

I'm setting up an an admin page that handles the storage of data of a product, in this case it is shoes which most of you might realize usually comes in pairs of left and right. The shoes have a differing number of fields and that's why i've implemented an eav system where the forms for the shoes are contained in an inline.
All i would like to do now is to group the forms in the inline in two columns depending on the value of the field shoe_side (can be 'L' or 'R' for left and right)
This is regarding the change view since the system is set up so that it creates all the neccessary fields depending on another model we can call a product recipe.
I did this in javascript with templates before in a similar situation but that was without the inline fields so it's not applicable. I think if I could just group the fields of the two columns into two formsets I could edit the template to get the needed layout but I don't know if one can create formsets based on a field in the model, I haven't really grasped the concept of formsets.
# The inline model
class Component(models.Model):
part_name=models.ForeignKey(PartRecipe)
shoe_side=models.CharField(choices=[('L', "Left"),('R', "Right")
product_id = ForeignKey(ProductModel)
....
# The 'parent' model
class ProductModel(models.Model):
product = ForeignKey(Productrecipe)
....
# a lot of not relevant fields
# The admin classes
class ComponentInline(admin.StackedInline):
template = 'admin/componentinline/stacked.html'
model = Component
class ProductAdmin(admin.ModelAdmin):
...
inlines = [ComponentInline,]

Change object identifier in hybris backoffice

I wanted to add an extension in backoffice, so that it is possible for non-programming people to add new objects (of defined types) to the database.
I've almost done it:
I defined two items: offer and tile (their relation is one to many)
What i achieved is there is a possibility to add a new offer in the backoffice.
When you add it, and click to edit, you can also add a tile to this offer - either form drop-down list (if any tiles exist) or create a new tile, which will automatically be added to its table and realted to edited offer.
However, the representation of the drop-down list is unacceptable, see below:
screenshot from backoffice
as you can see, the identifier of an existing tile (within []) is its PK - which clearly is not a good identifier. I would like to inject there instead a value form one of tile's other attributes (which also is unique) so that someone could easily identify which tile to add.
Where is the mechanism responsible for it? How to override it. I tried to override toString method in the tile class, unfortunately to no avail
You need to customize the backoffice-config.xml for your custom Model. For your Tile model, you can use something like:
<context merge-by="type" type="Tile" component="base">
<y:base xmlns:y="http://www.hybris.com/cockpit/config/hybris">
<y:labels>
<y:label>nameOfTile</y:label>
</y:labels>
</y:base>
</context>

Field not allowing loupe. gvnix 2.0.0.M1

We have two child classes: Child1,Child2 that inherits from the same a class ParentClass, and only the class ParentClass.
We have a class A that contains a field parentList of type set field. This parentList is a list of ParentClass instances Ids
private Set parentList = new HashSet();
What we really want to achieve, is to select multiple values from either Child1 and Child2, and assign them to the parentList set field in class A, using Loupe.
When we try to execute the loupe command over the parentList field of class A, we get the following error:
Field 'parentList' could not implement Loupe Field.
What are the restrictions on the fields to use Loupe?
Is what we want to achieve, possible?
This UI component is designed to handle relations between JPA Entities of type many-to-one in the many side of relation (field must be annotated with #ManyToOne).
Currently gvNIX doesn't include any component which handle #*ToMany relations the way you required. The most similar is the use of master-detail datatables (see web mvc datatables details add command). An example of this could be: master Vets and details Visits (selecting a Vet related Visits will be shown in details list).
The component you need can be done but you must create it by hand.
Good luck!

How to create cascading dropdownLists in orchard

I'm trying to create a dependency between fields in orchard.
I need to create cascading dropdownList in Orchard.
e.g : Country and State (for each Country a couple of states must be displayed not all the content).
How can I do that with Orchard.
I think, that you need make a choice from two options:
Create content type for Country and other content type for State (or may be one content type for Country and State). Then use Container and Containable part to create hierarchy (May be you should also use List module). Then override your field editor (you can use any field type, but i suggest you to use content picker field).
Use Taxonomy Module to create country-state hierarchy. Then use Taxonomy Field and override editor for it.

Resources