|Version 1 (modified by benoitg, 7 years ago)|
Author: Benoit Grégoire,
Feel free to contribute and/or format better
User profile design
The profiling will be implemented as a list of allowable field defined by the network, that can be filled in by the user.
Initial design is from by Benoit Grégoire. François Proulx will likely do most of the implementation.
Why such a complicated framework, and not a few basic, commonly used fields?
Originally I was hoping to build a profile system with a core set of generic, semantically interoperable data elements (including links to services), that could be extended with network specified, non interoperable elements. I was hoping to start with the core set, which could have been implemented quickly before solving the much more complicated and delicate problem of supporting totally generic profile elements (and being able to actually do stuff with them).
It is by now absolutely obvious that we can't agree on a set of simple fields applicable to all wireless groups. Even within groups, reaching a consensus seems very difficult. So the entire generic system will have to go in at once, and there won't be any core elements (which is ultimately a good thing.
Data model (only new tables shown)
Basically a list of data fields (one for each network) that the user can fill. Represented by the NetworkProfileField? class, which inherits from the abstract ProfileField? class. Used by network administrators to define available fields in user profile.
- field_id guuid PRIMARY KEY --
- network_id -- Only one network per profile_field
- display_label content_id -- The field's label for the display interface of the profile. Content id, as it must be localizable, and may well actually be an image
- admin_label content_id -- The field's label for the user's edit interface.
- content_filter filter_id -- A filter to list the specific content types allowable to be entered as value by the user for this profile field. The UI code for this should live in the ContentTypeFilter? class (the class works, is used elsewhere, but there is no UI for it yet). See the section on ContentTypeFilter?
- order -- The order in which the field appears in the provile.
- semantic_id text -- Not user visible. This field has two purposes:
- Eventually used to allow export in microformats and XML representation of profiles in microformats or XML formats. For example, for the user's avatar the semantic_id value should be "foaf:nick"
- Some semantic_id values will have special meaning to wifidog. For example if an element with foaf:img exists in the profile, it will be used to display the user's custom avatar in the on-line user list. The admin interface to define network profile fields must list all the semantic_id with special wifidog meaning.
The user frofile, used to link the user table with user_profile_fields. Represented by the Profile class. Technically, we could directly link the user table in user_profile_fields, but that would be undesirable. The profile table is used instead for two reasons:
- To allow adding a user agreement before creating his profile (once user agreement support is complete
- To allow the easy storage of non data elements, such as an invisible mode, wether other users can send the user messages, etc.
- To one day allow user's to have one profile for each network, if so desired.
- user_id user_id -- The user's id
- is_invisible boolean -- If the user wishes to be in anonymous mode.
- creation_date timestamp
- network_field_id network_profile_field_id ON DELETE CASCADE ON UPDATE CASCADE
- field_id guuid PRIMARY KEY
- content_id content_id -- The actual link to the data
- last_modified timestamp -- This will probably not be implemented at first, as it requires having the setters and processAdminUI for every content type return if data was actually modified. This is not actually difficult, and is essential if we want to measure how users actually use and update their profile.
The ContentTypeFilter? class already exists and is used in several parts of the content manager. Basically, it will call an array of function calls statically on each candidate ContentType?, each with their own array of parameters. Several function in the Content class and it's child have been defined for this purpose. While it's extremely flexible and works very well, currently, the only way to define a filter is from the code (see the documentation in the ContentTypeFilter? constructor). We imperatively need a UI for this as well as a data representation, which will be difficult (hierarchical structure) but not impossible. Difficulties include:
- Listing the available filter functions (difficulty is compounded by the fact that not all of them are defined in the Content class. Forcing them all to be defined in the Content class with a common prefix could be considered, and would simplify this greatly.
- Handling the case where an existing filter is invalidated by the disappearance of a filter function in the code, and deleting the field from the filter cleanly.
- UI for typing in the callback function parameters in a way that can be parsed by PHP without using eval().
- Profile edit interface for end user is implemented in Profile::getAdminAdminUI() and called from User::getAdminUI().
- Profile fields admin interface for network administrator is called from Network::getAdminUI().
- When deleting a field from the network, ask the administrator to confirm if any user have data in the field (list how many user's data you'll wipe out)
Possible profile reports
- Profile usage (% of users with a profile)
- Field usage (% of users with a profile that filled the field)