Sulu CMF - CRUD Filtered Multi-Item-Selection for association entities - reactjs

I have three entities:
class DataSet {
string $name;
Collection $points; // List<DataPoint>
Collection $groups; // List<DataGroup>
}
class DataGroup {
string $name;
Collection $assignedPoints; // List<DataGroupPoint>
}
class DataPoint {
string $name;
Collection $assignedGroups; // List<DataGroupPoint>
}
class DataGroupPoint {
DataGroup $group;
DataPoint $point;
int $data;
}
I extended the Admin UI to perform CRUD operations on the DataSet entity, as per docs. By looking at the ContactBundle Javascript extension, I was able to add CRUD operations for DataPoint entities within the DataSet form by registering a CardCollection - works fine.
Now, I want to perform CRUD operations on associated DataGroup entities of the DataSet as well - for that I want to put a MultiItemSelection component into the DataGroup overlay form in order to add, edit or remove DataGroupPoints.
For a DataGroupPoint entity, both the DataGroup and the DataPoint are supposed to belong to the same DataSet (which in turn is being edited in the overall form).
How can I provide all matching DataPoint entities to the MultiItemSelection?

As far as I understand your question, you are looking for a custom data_point_selection content type.
To achieve this I can recommend you to take a look at the Sulu Workshop, especially assignment 11. In this assignment a single_location_selection is implemented. This is a selection for the custom entity location.
Another great example for a custom selection or single_selection is the example pull request of the sulu demo.
As a side note, the implementation of the ContactBundle is very specific for this case. Therefore the extendability and usability of the used components like CardCollection is not the best. For a better developer experience I would recommend you to stick to the documented content types in the docs. Unless you really need these specific components.

Related

Template and model reuse in Wagtail

I am building a fairly basic Wagtail site and have run into an issue regarding the reuse of models and templates.
Say my site has two kinds of entries:
blog posts and
events.
Both pages look the same and share many model fields (e.g., author, category, intro, etc.). However, there are some model fields that only make sense for the event entry type (e.g., event_date, event_venue).
What would be the ideal way of creating templates and models for this use-case without repeating myself in the code?
Right now, both blog and event entries use the same HTML template and the same model. However, when the user creates a blog post in the Wagtail admin, he or she has to "ignore" the event-specific fields (which may become even more in the future).
Do I have to create two separate template files and two separate models despite both blogs and events being 95% the same code? What would be the correct way to solve this in Wagtail?
If you want to maintain it the way it is, contained within one model and template, you could create separate model admins for each pseudo-type (Blogs and Events), and override the queryset function to make each separate modeladmin only show the ones you're looking for, and then edit the panels that are shown on create/edit/delete.
class EventAdmin(ModelAdmin):
...
panels = [
FieldPanel('your_field'),
...
]
def get_queryset(self, request):
qs = super().get_queryset(request)
events = qs.filter(your_field__isnull=False)
return events
More information at https://docs.wagtail.io/en/stable/reference/contrib/modeladmin/index.html

CakePHP 3 Entity Confusion

Here is the issue I am facing all the time since I started to learn CakePHP 3
What is this concept of entity a real world example would help alot.
public function add()
{
// why do we have to create new entity / what is the role of entity here.
$comment = $this->Comments->newEntity();
if ($this->request->is('post','put')) {
// why do we have to use this line after posting / what is the role of this line.
$comment = $this->Comments->patchEntity($comment,$this->request->data);
if ($this->Comments->save($comment)) {
$this->Flash->success('comment submitted successfully.');
} else {
$this->Flash->error('Sorry, comment could not be updated.');
}
}
return $this->redirect($this->referer());
}
Let me open the book for you:
While Table Objects represent and provide access to a collection of
objects, entities represent individual rows or domain objects in your
application. Entities contain persistent properties and methods to
manipulate and access the data they contain.
-
why do we have to create new entity / what is the role of entity here.
Almost everything, if not all, in Cake3 works with entities, what an entity is is explained above. You need to create a new entity so that the FormHelper can work with it, AFAIR it can still work with an array if configured to do so as well but the entity should be used.
The reason entities exist is to abstract the data. Some people think entities are the representation of a DB row - that's wrong. As the book says, they can be a row but don't have to represent a row because the 3.0 ORM can work with other resources as well. In theory you can have a CSV data source that returns an entity per line.
I suggest you to read the entity code in the CakePHP core to get a deeper understanding of what else entities provide, just saying they're "just" a set of properties is to short thought.
why do we have to use this line after posting / what is the role of this line.
The post data is merged into the previously created entity, that's it. Use the API if you have basic questions like that. See the API entry for patchEntity().
In simple word, Entity is a set of one record of table and their relational table, on that you can perform operation without touch of database and encapsulate property of entity (fields of table) as you want.
Advantages of Entity.
Modifying result sets outside of the database (for formatting or otherwise)
Needing to represent both the table and row in the same class.
Data validation was a fucking nightmare.
Inconsistent API in terms of both how we handled things internally as well as what (and how) we returned stuff.
Other random stuff as you want.
You can do run-time modification of result sets. Just add a method to your entity to return results in the way you want. This also means you can use composition for managing entities (yaya traits)
Validation is beautiful. We can validate data before it gets into an object and then validate the object state in a separate step.
It is easier for developers to understand what they are dealing with. You either have an object or an array of objects. An object can be linked to data which can also include other objects, but you no longer have to guess at what the array key will be, nor whether its nested funkily.
We can iterate on the interface for tables and entities separately. We couldn't easily change internals for the old Model class because of the implications on both, whereas now we can (in theory) change one without mucking about in the other.
It looks prettier simple.
Try this:
if ($this->request->is('post','put')) {
$data = $this->request->getData();
$comment = $this->Comments->newEntity();
$comment = $this->Comments->patchEntity($comment, $data);
$status = $this->Comments->save($comment);
if ($status) {
$this->Flash->success('comment submitted successfully.');
} else {
$this->Flash->error('Sorry, comment could not be updated.');
}
}
return $this->redirect($this->referer());
}
My advice is never use Post and Put in the same function. Just for good pratice. Put works fine when you make a update using id like a parameter.

cakephp: abstract classes, factory, return objects

I would need an idea or two how I would do this in cakephp (using latest version)
I am building a web based game where you will be able to collect Items
Without a framework I would have an abstract base item class that every item would extend to
And when displaying for example a inventory i would factory all items the user currently have and then return a object for each item.
classes...
BaseItem
WeaponItem
HealingItem
etc..
How would I do this in cakephp? Would I go for a model for each item class ... and how would i factor to get the object? ...
Assuming you're using a database as the data store, presumably you will use a single table for all items the player can collect? If so, you probably want a single Model class.
It's possible to have an inheritance hierarchy for models in CakePHP if you want. But you can often achieve sharing of Model logic using a Behaviour.

Can the Salesforce multi-select picklist be used for arbitrary data and not just sObjects?

I think I might be missing something, but I can't see how to use the built in multi-select picklist control for anything but sObject fields.
I'm talking about the control which features 2 list objects marked "Available" and "Selected" with arrows inbetween to moving items between the lists. This control is an easier and more discoverable way for a user to select several items then the selectList control, which needs Shift and Ctrl to select multiple items.
Page with pictured example
With a selectList I don't need a specific sObject - I can store the users selection in one off my controllers members, and I can even create a method to provide a list of valid values - this method could be hard coded, dynamically calculated or even use a query to lookup some live data.
Is there a way to use the fancy picklist control, only without any reference to a specific sObject, just a list of string values?
Unfortunately, the only way to use any of the standard field types, e.g., dates or multi-select picklists, is to have the field be backed by an SObject.
For me, when it becomes necessary to use these kinds of fields on a Visualforce page, I will create an Object specifically for the purpose of providing a back-end for the fields. In the Apex Controller, simply instantiate your Object (no need to supply any values) and reference that object's fields on the page.
While this may seem a little inefficient from the configuration side, it has a number of added benefits such as using the default UI (automatically subject to any improvements made by SFDC) and utilizing any built in validation.
If you are dead-set on not having the field be backed by an SObject, there might be some jquery multi-select options available. I've seen a lot around but haven't really tested any.
in your class:
public List<SelectOption> getStoryItems()
{
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('SAM','Sam I Am'));
options.add(new SelectOption('GEORGE','George of the Jungle'));
options.add(new SelectOption('DORA','Dora the Explorer'));
return options;
}
String[] stories= new String[]{};
public String[] getStories()
{
return stories;
}
public void setStories(String[] stories)
{
this.stories= stories;
}
in your page:
<apex:selectList value="{!stories}" multiselect="true">
<apex:selectOptions value="{!getStoryItems}"/>
</apex:selectList>
The results will be comma delimited, if you don't want multiple select, just set multiselect to false

DRY unique objects in Django

I want to ensure an object is unique, and to throw an error when a user tries to save it (e.g. via the admin) if not? By unique, I mean that some of the object's attributes might hold the same values as those of other objects, but they can't ALL be identical to another object's values.
If I'm not mistaken, I can do this like so:
class Animal(models.Model):
common_name = models.CharField(max_length=150)
latin_name = models.CharField(max_length=150)
class Meta:
unique_together = ("common_name", "latin_name")
But then each time I refactor the model (e.g. to add a new field, or to change the name of an existing field), I also have to edit the list of fields in the parenthesis assigned to unique_together. With a simple model, that's OK, but with a substantial one, it becomes a real hassle during refactoring.
How can I avoid having to repeat typing out the list of field names in the unique_together parenthesis? Is there some way to pass the list of the model's fields to a variable and to assign that variable to unique_together instead?
Refactoring models is a rather expensive thing to do:
You will need to change all code using your models since field names correspond to object properties
You will have to change your database manually since Django cannot do this for you (at least the version I used the last time when I worked with Django couldn't)
Therefore I think updating the list of unique field names in the model meta class is the least issue you should worry about.
EDIT: If you really want to do this and all of your fields must be "unique together", then the guy at freenode is right and you'll have to write a custom metaclass. This is quite complicated and errorprone, plus it might render your code incompatible to future releases of Django.
Django's ORM "magic" is controlled by the metaclass ModelBase (django.db.models.base.ModelBase) of the generic base class Model. This class is responsible to take your class definition with all fields and Meta information and construct the class you will be using in your code later.
Here is a recipe on how you could achieve your goal:
Subclass ModelBase to use your own metaclass.
Override the method __new__(cls, name, bases, dict)
Inspect dict to gather the Meta member (dict["Meta"]) as well as all field members
Set meta.unique_together based on the names of the fields you gathered.
Call the super implementation (ModelBase.__new__)
Use the custom metaclass for all your unique models using the magic member __metaclass__ = MyMetaclass (or derive an abstract base class extending Model and overriding the metaclass)

Resources