Posted by sun on August 12, 2012 at 1:03pm
25 followers
| Project: | Profile 2 |
| Version: | 8.x-1.x-dev |
| Component: | Code |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
| Issue tags: | Platform Initiative, Profile in core |
Issue Summary
Goal
- #1668292: Move simplified Profile2 module into core
- Part of the Profile in core effort.
Battle plan
- DONE: Minimal port to D8. (non-functional)
- DONE: Make the current code work with D8's entity system.
- DONE: Comment out or work around advanced (contrib) Entity API module functionality (e.g., metadata, etc)
- DONE: Investigate what code can be removed.
- DONE: Convert profile types into configuration.
- DONE: Implement EntityFormController for Profile and ProfileType.
- DONE: Implement EntityRenderController for Profile.
- DONE: Implement EntityListController for ProfileType.
- DONE: Rework user profile category tabs (@sun). Remove necessity for rebuilding the menu/router.
- DONE: Remove unnecessary helper functions.
- DONE: Implement entity access controller
- Fix and improve pre-existing Profile2 logic/behavior:
- DONE: Move profile2_load_by_user() as custom method into ProfileStorageController. Eliminates the drupal_static().
- DONE: Missing UUID for profiles.
- DONE: Ensure to leverage entity_delete_multiple()'s bulk deletion process wherever multiple profiles are deleted.
- DONE: Remove remaining entity API wrapper functions
- DONE: Migrate default "Main" profile from profile2_install() into config for now.
- Update Profile to EntityNG + Property/Field API. (not ProfileType)
- Figure out what to do with the custom profile access system.
- Vastly improve test coverage.
- Profile (UI) delete confirmation.
- Profile access.
- DONE: Clean up unnecessary and stray contrib Entity API code.
- Apply coding standards, fix coding style, phpDoc, and comments.
- Consistently use $type for ProfileType entity variables. $id for ProfileType IDs, $bundle for Profile bundles.
(Replace all $type_name, $type_id, $profile_type, etc.)
- Consistently use $type for ProfileType entity variables. $id for ProfileType IDs, $bundle for Profile bundles.
- Rename the whole thing from profile2 into profile. :)
- Move default "Main profile" into the standard installation profile.
http://drupalcode.org/project/profile2.git/shortlog/refs/heads/8.x-1.x
Needs architectural review
- Is there any use-case for custom user profile labels? Yes there is, e.g. multiple profiles for the same profile type (invoice/shipment addresses, etc.).
- Consider removing the 'profile2_private' functionality. That looks rather like a custom field access solution instead of something we should provide as a built-in solution.
- Should we use extra fields for injecting the profile form / displaying the profile on the user form / view?
Comments
#1
#2
#3
My first version. I made the following things working:
- profile types listing (admin/structure/profiles; for an unknown reason the title of this page is "Error")
- profile type add form (admin/structure/profiles/add)
- profile type edit form (admin/structure/profiles/manage/$type/edit)
- profile type delete form (admin/structure/manage/$type/delete)
For sure there are some faults, but it's a beginning.
#4
oh. Sorry for missing those classes in profile2.module!
I've committed the basic/minimal change (moving them into the new location), and rebased your patch against latest HEAD.
#5
Sorry, one more follow-up - committed the interdiff changes.
#6
The last submitted patch, profile2.3.patch, failed testing.
#7
Got the following things done:
- Installation (including creation of default "main profile")
- profile type manage fields form (admin/structure/profiles/manage/$type/fields)
- profile type manage display form (admin/structure/profiles/manage/$type/display)
- page title in admin/structure/profiles (see #3)
#8
- Admin registration form works
- User registration form works
- Replaced "user_category" by using fieldsets in profile edit
Got the following message when I try to edit a profile:
I don't get where the revision.timestamp and revision.uid fields were added.
#9
Important: #1668820: Concept, base class, and interface for Configurables (e.g., node types, image styles, vocabularies, views, etc) landed for Drupal core!
This probably has a huge impact here. Essentially, the profile type remains to be an entity type, but simply extending the ConfigurableBase class instead of the Entity class. :)
#10
Discussed this patch with @n3or over Skype -- discussion backlog:
- Make ProfileType extend ConfigurableBase instead of Entity
- Rename ProfileType::$type => $id
- Add ProfileType::$uuid
- Remove ProfileType::isLocked() without replacement.
- Remove profile type import/export forms/functions without replacement.
- Remove ProfileType::__construct() constructor override, fix calling code instead.
- Make Profile::__construct() comply with StorableInterface::__construct():
public function __construct(array $values = array(), $entity_type) {- Use/implement EntityFormController for Profile entity type: #1499596: Introduce a basic entity form controller
+++ b/profile2.module@@ -67,14 +65,13 @@ function profile2_entity_info() {
$return['profile2_type'] = array(
...
+ 'controller class' => 'Drupal\entity\DatabaseStorageController',
Drupal\config\ConfigStorageController
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+ * Implements hook_menu.
Missing ()
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+ $items = array();
Can be removed.
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+ $items['admin/structure/profiles/list'] = array(
+ 'title' => 'Profile types',
Title should be 'List'.
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+ $items['admin/structure/profiles/import'] = array(
...
+ $items['admin/structure/profiles/manage/%profile2_type/clone'] = array(
...
+ $items['admin/structure/profiles/manage/%profile2_type/export'] = array(
Remove entirely.
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+ $items['admin/structure/profiles/manage/%profile2_type/fields'] = array(
+ 'title' => 'Manage profile fields',
Let's compare with taxonomy_menu() + taxonomy_entity_info(), which is the only comparable implementation in Drupal core.
+++ b/profile2.module@@ -82,17 +79,172 @@ function profile2_entity_info() {
+function profile2_type_list_page() {
Let's primarily orient at config_test.module in Drupal core.
However, config_test.module does not implement fields, so we also have to orient at taxonomy vocabulary overview page as well as node type list page. Node types seem to be more appropriate.
+++ b/profile2.module
@@ -165,7 +323,7 @@ function profile2_get_types($type_name = NULL) {
function profile2_load($pid, $reset = FALSE) {
- $profiles = profile2_load_multiple(array($pid), array(), $reset);
+ $profiles = profile2_load_multiple($pid, array(), $reset);
return reset($profiles);
@@ -186,7 +344,13 @@ function profile2_load($pid, $reset = FALSE) {
function profile2_load_multiple($pids = array(), $conditions = array(), $reset = FALSE) {
- return entity_load('profile2', $pids, $conditions, $reset);
+ if (empty($conditions)) {
+ // it doesn't make sense to use pids and conditions,
+ // therefore ignore pids if conditions were set
+ return entity_load_multiple_by_properties('profile2', $conditions);
+ }
+
+ return entity_load_multiple('profile2', $pids, $reset);
}
Note that #1184272: Remove deprecated $conditions support from entity controller just landed, so the signatures of the load* functions need to be changed accordingly.
Furthermore, in #1757586: Remove MODULE_load*() & Co functions in favor of entity_*() functions there's a suggestion to not even implement entity type module specific API functions but use the entity_load() + friends functions directly. We might want to do that in a later step though.
+++ b/profile2.module@@ -361,7 +517,9 @@ function profile2_form_user_profile_form_alter(&$form, &$form_state) {
- if (!empty($profile_type->data['registration'])) {
+ $data = $profile_type->get('data');
+ $data = unserialize($data);
+ if (!empty($data['registration'])) {
Let's turn this into a ProfileType::$registration property.
#11
Tried to implement all changes mentioned by sun. At the moment the EntityFormController is still missing.
There shouldn't any losings in functionality compared with #8.
#12
Fixed incompatibility to current 8.x-1.x. Interdiff is meaningless.
#13
Slightly revised. Any chance to test this before commit? ;)
#14
Did a few functional tests with positive result! Looks great. Thank you sun!
#15
Committed to 8.x-1.x. :)
Next steps:
1) Adjust the tests for the new code. Let's get the testbot working again, so we don't have to test patches manually.
2) Remove/replace profile2_* CRUD functions with entity* functions.
3) Remove profile2*_save() + _delete() with ->save() and ->delete()
#16
Almost all tests will pass. One test will fail because "view/edit own main profile" permission is useless at the moment. We need to implement an alternative to user categories managed by profile2.
#17
+++ b/lib/Drupal/profile2/Tests/Profile2CRUDTestCase.php@@ -103,11 +106,10 @@ class Profile2CRUDTestCase extends WebTestBase {
- $this->assertTrue($new_user->status, t('New account is active after registration.'));
...
+ $this->assertText(t('In the meantime, a welcome message with further instructions has been sent to your e-mail address.'), t('User registered successfully.'));
+ $new_user = user_load_by_name($name);
+ $this->assertFalse((bool) $new_user->status, t('New account is active after registration.'));
assertTrue vs. assertFalse -- massive change in expectations ;)
+++ b/profile2.module@@ -404,7 +404,7 @@ function profile2_type_delete(ProfileType $type) {
- $pids = array_keys(profile2_load_multiple_by_properties(array('type' => $type->type)));
+ $pids = array_keys(profile2_load_multiple_by_properties(array('type' => $type->get('id'))));
Let's always use the ->id() method to retrieve the (configurable) entity ID.
#18
See comment of sun. Additionally added two empty lines killed in patch #16.
#19
YAY! The testbot runs and passes against D8! :)
#20
Removed the fieldsets in user/edit and implemented a "user category" replacement. But at the moment there is no linking from user/edit to user/edit/{$profile_type} (see D7 implementation in the attached screenshot; "main profile" and "permission test" were profile types). Any suggestions how to handle that in D8?
(Every test should pass now.)
#21
Forgot screenshot.. :)
#22
The last submitted patch, drupal8.profile2-port.20.patch, failed testing.
#23
Committed and pushed to 8.x-1.x, with a couple of additional adjustments. :)
Nice to see that this actually works already (tested manually)! :)
#24
Next step would be to port for entity form controllers. :)
@n3or informed me that he most likely won't be able to work on this further in the next few days/weeks.
Any takers?
I'll look into the exposure of profile categories as local tasks on the user account edit page, since that seems to require some menu system voodoo. ;) (right now you need to manually access
user/%uid/edit/mainto get to the respective profile-type edit form)#25
Nice work here.
I think that category subnavigation is a pre-ajax relic. I think the modern way to edit profiles is to view your own and click on stuff and edit inline. See facebook and Google+. I don't think there is much point in separating the profile out to separate pages.
#26
Sun said in #24 that n3or is busy currently. I am taking over until he reports back for duty :).
Nearly done with "Clean up unnecessary code and stray helper functions." and "Implement EntityFormController for Profile and ProfileType.".
Also rebased on the current version of core (some classes were moved recently, etc.).
#27
Talked to @sun earlier today. We are going to push this forward with separate, smaller patches. First of all, this is the form controller patch. It converts both, the profile and the profile type form. However, the profile form simply getting built with fields, we still got most form related code in profile2.module because of the way we are currently conditionally attaching our profiles to the registration form through hook_form_user_register_form_alter().
I hope that we can find a better way of doing that without form alters. E.g. through a multi-step process or something ... The problem is, that by altering the form, the form submission / validation process becomes really fugly. That is why I didn't convert that part yet. If we decide that we want to keep it as is we can rebuild that to use the form methods through entity_form_controller() directly. I think that would be a follow-up patch as well.
Additionally, I added the tabs as shown in the screenshot above. On the user/%user/edit page we now have these tabs (one for each profile).
Some classes in core have been moved too... So I simply added that to this patch as well.
Will post the patch for the next step once this one is commited :).
#28
Removing that ugly strtr(). Dunno why I even added that. :P
#29
The last submitted patch, form-controllers-28.patch, failed testing.
#30
Could we get those final test fails out of the way? As i said in #25, I see subnavigation across profile types as pretty unwanted these days but is fine for the purposes of this patch.
#31
I'm back. Thank you very much fubhy!
I will try to get this patch green.
#32
Concentrated on fixing failing tests!
Locally now all tests passed. Adapted the test case and added the save handler within profile form controller.
#33
+++ b/lib/Drupal/profile2/Profile.php@@ -165,7 +165,6 @@ class Profile extends Entity {
return $content;
The next step here, after completing the form controller conversion should be to do the render controller conversion.
+++ b/lib/Drupal/profile2/ProfileFormController.php@@ -0,0 +1,43 @@
+ if (!user_access('administer profiles')) {
+ unset($element['delete']);
+ }
Why am I not allowed to delete my own profile as a user?
I just see that the original code didn't allow for this either, so this should probably be adjusted/fixed in a follow-up patch; laters.
+++ b/lib/Drupal/profile2/ProfileFormController.php@@ -0,0 +1,43 @@
+ drupal_set_message(t('Your profile has been saved.'));
This message should dynamically adjust to the current user; i.e., whether you are editing your own profile, or whether you are a site administrator editing another user profile.
+++ b/lib/Drupal/profile2/ProfileFormController.php@@ -0,0 +1,43 @@
+ // Rebuild the menu tree.
+ menu_router_rebuild();
For regular profiles, this shouldn't be needed.
+++ b/lib/Drupal/profile2/ProfileTypeFormController.php@@ -0,0 +1,76 @@
+ 'source' => array('label'),
No longer needed, HEAD defaults to 'label' now.
+++ b/lib/Drupal/profile2/ProfileTypeFormController.php@@ -0,0 +1,76 @@
+ $profile_type->save();
...
+ drupal_set_message(t('%label configuration has been saved.', array('%label' => $profile_type->label())));
::save() returns $status, let's differentiate between created and updated in the message.
In general, see #1798944: Convert config_test entity forms to EntityFormController for a prime/master example config entity conversion.
+++ b/lib/Drupal/profile2/ProfileTypeFormController.php@@ -0,0 +1,76 @@
+ // Rebuild the menu tree.
+ menu_router_rebuild();
...
+ // Rebuild the menu tree.
+ menu_router_rebuild();
Let's add a @todo right above these to remove them. (That will be my job.)
+++ b/lib/Drupal/profile2/Tests/Profile2CRUDTestCase.php
@@ -121,7 +121,7 @@ class Profile2CRUDTestCase extends WebTestBase {
- $this->drupalGet('user/' . $user1->uid . '/edit/main');
+ $this->drupalGet('user/' . $user1->uid . '/edit/profile/main');
+++ b/profile2.module
@@ -133,14 +137,25 @@ function profile2_menu() {
+ $items["user/%user/edit/profile/$id"] = array(
I don't see why the additional /profile/ part in the path is necessary. Let's revert this.
+++ b/profile2.module@@ -106,18 +112,16 @@ function profile2_menu() {
$items['admin/structure/profiles/manage/%profile2_type'] = array(
'title' => 'Edit profile type',
...
+ 'page callback' => 'entity_get_form',
+ 'page arguments' => array(4),
We need a page callback here to set an appropriate page title with drupal_set_title().
+++ b/profile2.module@@ -440,6 +455,8 @@ function profile2_user_view($account, $view_mode, $langcode) {
+ * @todo Let's try to find a better solution for this and everything related.
This @todo doesn't make too much sense to me. Let's remove it and discuss what can or needs to be improved on-issue instead.
#34
Fixed everything mentioned in sun's comment. (Except the first two suggestions, they aren't related to this patch.)
#35
Thanks! Committed and pushed with a couple of minor adjustments.
Next step: EntityRenderController.
(Updated issue summary accordingly; also started to collect issues from patch reviews there for later clean-up; but let's continue with the straight porting first.)
#36
First version of EntityRenderController implementation.
#37
Removed profile2_view.
#38
Yay, thanks! Committed and pushed.
Next step: EntityListController for ProfileType config entity.
#39
Clarifying issue title.
#40
Attached patch removes the need for rebuilding the menu router, taking the same approach as in
#1067408: Themes need an installation status
But of course, having to workaround a dozen of quirks of the menu system and hook_menu_local_tasks_alter() in core to achieve it.
(That said, I'll probably take over those workarounds for that core patch...)
Tests pass for me locally (but test coverage is extremely limited anyway, so I manually tested this extensively on top). Will commit in a bit, unless anyone raises objections.
#41
Committed and pushed #40. Back to #38:
Next step: EntityListController for ProfileType config entity.
@n3or mentioned he wants to do that tomorrow.
If anyone wants to work on improving test coverage or some other dedicated task, please do so (and let us know before/when you do)! :)
#42
First version of EntityListController.
#43
#44
- Removed unused code
- Made field_ui operations conditional
#45
Thanks! Committed and pushed with minor adjustments.
The only noteworthy one: EntityListController uses capitalized operation labels now (i.e., "Edit" vs. "edit"), whereas the Field UI links were still lowercase.
This was the last precisely defined atomic step, so unless someone has another one that isn't mentioned/listed in the summary yet, we're basically in "random fix + clean-up + improve test coverage mode" now.
#46
+++ b/lib/Drupal/profile2/ProfileTypeListController.phpundefined@@ -0,0 +1,42 @@
+ 'href' => $uri['path'] . '/fields',
should use _field_ui_bundle_admin_path() instead of $entity->uri()
+++ b/lib/Drupal/profile2/ProfileTypeListController.phpundefined@@ -0,0 +1,42 @@
+ 'href' => $uri['path'] . '/display',
same here.
Furthermore we need to rebuild the entity info after adding a new profile type. Otherwise _field_ui_bundle_admin_path() fails.
#47
_field_ui_bundle_admin_path() is marked as a private function, so it would be inappropriate to call it if you are not Field UI module.
None of the administrative entity listing pages in Drupal core do that either; e.g.:
node_overview_types()
#48
Also, we have to provide a storage controller until we have a proper bundle api as proposed in #1782460: Allow to reference another entity type to define an entity type's bundles to inform the Field API of our bundles.
Tried to address.
#49
You are right. I am not really sure WHY it is a private function though. It's simply a helper/wrapper for convenience.
#50
Whoops, copy&paste fail.
I am leaving the _field_ui_admin_path() stuff in. Re-store the previous code if you want. I am going to file an issue to remove that underscore prefix from that function. It doesn't make any sense imo.
#51
Nice work! Profile editing has come along since profile.module. Specifically, look at the lovely edit in place experience that google+ and facebook offer. Thats what I would love to see from profile2.
Would be great if someone could install edit module with profile2 and make a list of todos in order to get a Google+ like experience.
#52
One big todo is right now Edit module's hard-coded to only work with nodes. We have expanding that to all entities as a post-feature freeze task, but of course if someone wanted to get to it sooner, we'd love it. :)
#53
Thanks - I wondered why this seemed to work, so I've complemented that with a CRUD UI test for profile types. The new storage controller indeed fixes a range of bugs.
This is a very interesting part for Configurables in D8 in general. The Field (UI) integration ought to be possible much easier for fieldable entities whose bundles are managed by Configurables. I'll think about the required Config\Entity improvements.
Lastly, there's a final assertion in the new test, which fails. Something is broken in D8 HEAD, because I can perfectly reproduce that failure manually, but the entire field configuration data is stored and updated correctly. We probably need to file a (major) bug against core for that.
Will commit this in a minute. (Managing the patch flow in this issue now that we're beyond atomic steps isn't trivial, so I'll do my best to ensure a fast-path patch-to-commit flow. Keep 'em coming. :))
#54
Btw, I hope we'll be able to eliminate profile2.api.php entirely, as I filed this against core:
#1824184: Remove and replace entity type specific API hook documentation with generic entity API hook documentation
#55
+++ b/lib/Drupal/profile2/ProfileTypeStorageController.phpundefined@@ -0,0 +1,47 @@
+ if (module_exists('field')) {
Common... What do we do with profiles without fields? :D
Fields should be a dependency for profiles. no?
I didn't look at which assertion you mean but I already filed a bug report for a field ui bug in HEAD: #1824180: Undefined variable $admin_path in Field UI module
I think we should start to work on #1782460: Allow to reference another entity type to define an entity type's bundles.
I also opened an issue for that private field ui function: #1824244: Tests for: Turn _field_ui_bundle_admin_path() into a public function (field_ui_bundle_admin_path())
#56
You're right. Quickly reverted and replaced that with a proper field module dependency in the .info file prior to commit.
#57
Next up: Further clean up for stray contrib Entity API code and cleanup of the Profile2 class (uri, url, path, etc.)
#58
Let's also switch to EntityNG and NG controllers as soon as possible.
#59
I don't think we are missing that hook, or are we? It's just invoked _before_ the normal delete hook is invoked to reassign attached data if required. In our case that is not needed. We just want to delete the profiles.
However, I think that we should use hook_user_predelete() instead of hook_user_delete() because we should be deleting attached data prior to deleting the 'host' object. This is also the way that taxonomy terms are being deleted on vocabulary deletion. And it makes sense too because if we use hook_user_delete() In the deletion hooks for the profiles we would not be able to load the account anymore because it would be gone already.
#60
Seems related to the latest patch. Adding that now.
#61
Thanks! Committed with minimal adjustments. (Coding standards say that there should be a blank line before the closing brace of a class.)
#62
Interesting. I always thought that it was the other way round. Thanks! Updated my IDE to reflect that in the coding style configuration.
Patch: Removed profile2_load_by_user(). After all it's simply a wrapper for entity_load_by_properties() and caching is handled in the storage controllers anyways.
#63
+++ b/lib/Drupal/profile2/ProfileTypeFormController.php@@ -66,4 +66,5 @@ class ProfileTypeFormController extends EntityFormController {
+ ¶
You might need to adjust your IDE a little more ;)
Anyway, that is looking great and even better. However, before we do this, we want to heavily improve the test coverage for Profile CRUD operations. I'm working on that.
#64
Also removing the other entity_load wrappers.
#65
Added Profile CRUD test coverage. Will commit this in a second and send the latest patch for re-testing.
#66
I am currently working on finishing the form controllers and allowing deletions by users.
#67
Okay ignore that last patch, lol.
This one (re-?)adds the delete functionality for profiles and also cleans up the Profile entity class a bit. As well as some other things. It also removes the static caching for example in favor of a simple wrapper for entity_load_multiple_by_properties(). We still need that wrapper to output the results keyed by profile bundle. profile2_type_load() can't be removed either because of the menu callbacks and the exists callback for the machine name field.
#68
Reverted removal of profile2_load_by_user() in #62 and committed that.
I'm not sure whether we really want to remove it. It appears to be a helpful helper function. If we really want to remove it, that would have to be merged into #64.
On #64, I think we should keep profile2_type_load() as-is for now. #type machine_name should and will most likely be improved to allow to specify a callable for the 'exists' callback definition anyway in HEAD. (We should create a core issue for that.)
#69
Wow, what's up with my IDE now? Weird :)
#70
The last submitted patch, 1726822-68.patch, failed testing.
#71
Re-roll
#72
Accidentally overwrote your version of profile2_load_by_user(). Sorry, doing to many things at once.
#73
So sorry for the noise. :/
This patch is now actually the right one. Sorry!
#74
+++ b/lib/Drupal/profile2/Profile.php
@@ -29,13 +29,6 @@ class Profile extends Entity {
- public $label;
@@ -56,92 +49,45 @@ class Profile extends Entity {
+ public function label($langcode = NULL) {
+ return $this->type()->label();
}
I think this makes sense for the default implementation.
However, do we really want to remove the $label property entirely (if so, we'd also have to remove the schema column)?
What if there is a legit use-case in contrib for user-customizable profile titles/labels?
+++ b/lib/Drupal/profile2/Profile.php@@ -56,92 +49,45 @@ class Profile extends Entity {
public function user() {
...
- public function setUser($account) {
You removed setUser() already, and I wonder whether we really need the [get]user() method... do we?
+++ b/lib/Drupal/profile2/Profile.php@@ -56,92 +49,45 @@ class Profile extends Entity {
public function type() {
btw, type() is a really confusing name. Can we rename this custom method to getProfileType()?
+++ b/lib/Drupal/profile2/ProfileFormController.php
@@ -20,10 +20,6 @@ class ProfileFormController extends EntityFormController {
- if (!user_access('administer profiles')) {
- unset($element['delete']);
- }
@@ -40,6 +36,17 @@ class ProfileFormController extends EntityFormController {
+ $form_state['redirect'] = array($uri['path'], $uri['options']);
...
+ public function delete(array $form, array &$form_state) {
+++ b/profile2.pages.inc
@@ -0,0 +1,28 @@
+function profile2_delete_confirm_form($form, $form_state, Profile $profile) {
Let's back out those redirect/delete changes for now and focus on the Profile class clean-ups first.
+++ b/profile2.module@@ -80,22 +80,15 @@ function profile2_entity_info() {
- * @param Drupal\profile2\Profile $profile
...
function profile2_profile_uri(Profile $profile) {
...
- * @param Drupal\profile2\ProfileType $profile_type
...
function profile2_profile_type_uri(ProfileType $profile_type) {
I'm not sure why you removed the phpDoc, but they should obviously stay.
+++ b/profile2.module@@ -80,22 +80,15 @@ function profile2_entity_info() {
+ $uri = user_uri(entity_load('user', $profile->uid));
This need to call into EntityInterface::uri().
+++ b/profile2.module
@@ -278,7 +275,7 @@ function profile2_permission() {
- foreach (profile2_get_types() as $type) {
+ foreach (entity_load_multiple('profile2_type') as $type) {
@@ -299,16 +296,6 @@ function profile2_permission() {
-function profile2_get_types() {
Let's back out this removal for now, and potentially merge it into the similar changes that were in #64.
#75
I am not a big fan of implementing features for which we can't even outline a use-case yet. So I would suggest to keep it simple for now and also remove the label property, yes.
#64 was a fail :). I will create a separate patch for just that if you want.
Yeah I wasn't sure what to write there. None of the other core entity uri callbacks have anything in their docblocks.
Okay, separate patch too then.
Attached patch should be the plain cleanup.
#76
This is the plain profile2_get_types() removal on top of the previous patch in #75.
#77
And this is the plain delete form patch on top of the patch in #76.
#78
The last submitted patch, 1726822-77.patch, failed testing.
#79
I think the removal of Profile::$label needs some more discussion. It would be great to learn from Profile2 maintainers and their experience on that topic.
Reverted off-topic changes from #74 and will commit this if it comes back green.
#80
#76: 1726822-76.patch queued for re-testing.
#81
Committed #79 and #76.
Updated the issue summary with a list of architectural discussion topics. @fago / @joachim, any feedback on those?
#82
Any objections to #77 except that it doesn't apply anymore?
Just a minor nitpick btw.:
return reset($profiles) ?: FALSE;(from profile2_load_by_user()) is redundant. reset() returns FALSE for empty arrays anyways.#83
Remarks on #77:
+++ b/profile2.module@@ -161,6 +161,16 @@ function profile2_menu() {
+ 'load arguments' => array('%map', 'edit'),
...
+ 'access callback' => 'profile2_profile_edit_access',
s/edit/delete/g
+++ b/profile2.pages.inc@@ -0,0 +1,28 @@
+function profile2_delete_confirm_form($form, $form_state, Profile $profile) {
+ $form_state['profile'] = $profile;
Entity delete confirmation form constructors are expected to always add a form #type value using the entity property name of the entity ID as key; i.e.:
$form['pid'] = array('#type'...'#value'...That is, as long as the delete confirmation form is not handled by the entity form controller (which is not supported by core yet).
+++ b/profile2.pages.inc@@ -0,0 +1,28 @@
+ $confirm_question = t('Are you sure you want to delete profile %label?', array('%label' => $profile->label()));
...
+ drupal_set_message(t('Deleted %label.', array('%label' => $form_state['profile']->label())));
I don't think the confirmation question nor the confirmation message will work out with real values. Needs manual testing and wordsmithing.
+++ b/profile2.pages.inc@@ -0,0 +1,28 @@
+ $uri = entity_load('user', $form_state['profile']->uid)->uri();
...
+ $form_state['redirect'] = $uri['path'];
Let's group these lines and also add a comment to explain what is being done and why.
#84
I couldn't find that consistency in core and rather found something even more ugly (using #type => 'hidden', #value = $id), etc.
I really prefer the $form_state solution... So I left it as is for now.
Added @todos for the messages. We can fine-tune that later.
Added 'delete' permissions for now. We should kill profile2_access() once the basic Entity Access API has been committed.
#1696660: Add an entity access API for single entity access
#85
Oh, that was not the full patch
#86
In case that doesn't make sense... Would it maybe make sense to move the profile types configuration from /admin/structure/.. to /admin/people/...? User roles are there too.
#87
Committed #85, plus the attached follow-up patch for it.
Btw, there are no tests for the profile delete functionality.
#88
Attached patch adds UUIDs to Profile.
#89
Added a single test assertion for the uuid property and committed #88.
#90
This patch moves the Overview to /admin/people/profiles ... I believe it makes more sense to have it there.
#91
The last submitted patch, 1726822-90.patch, failed testing.
#92
Will do the Entity plugin conversion now.
#93
#94
Attaching a diff with lesser minimum similarity index, just to confirm that #93 just moves files around and updates phpDoc.
Committed and pushed #93.
#95
Same as #90, but re-rolled, and only minimal adjustments.
#96
Committed and pushed #95.
#97
Converted default configuration into configuration.
#98
#97: config-default.97.patch queued for re-testing.
#99
Sorry, but one question: With what better the Profile2, than the user entity bundles and fields?
#100
+++ b/config/profile2.type.main.ymlundefined@@ -0,0 +1,6 @@
+# @todo Are profile types the responsibility of installation profiles?
Yes, let's simply delete this part. It's a installation profile thing.
#101
But yeah... Let's leave it there for now. We can easily move it over to the installation profile (standard) once we are ready for getting this in.
#102
@sun are you still pro D8 inclusion? If so, considering that most of my other issues are blocked currently I would like to focus on this again. Would that be a good investment in time?
#103
Absolutely. That said, I'm actually not sure whether this is bound to Dec 1st feature freeze, since we need to upgrade former Profile module data somewhere for D8, and this effort delivers the solution for that (and has been listed by @Dries as one of the major feature efforts). But then again, you never know... So probably better to get this done — that said, I actually think we're pretty close :)
#104
All right... Let's fix the remaining todo's then. I am also adding a few todos:
Attached patch improves multiple entity deletion.
#105
The last submitted patch, entity_delete_multiple.patch, failed testing.
#106
Right.. profile2_load_by_user() returns the profile type as array key and DatabaseStorageController works with the array keys for deleting multiple entities. A bit fragile if you ask me (should maybe work with array_map()) to retrieve the entity id's instead of just going array_keys()...
#107
Adding access controller. This patch will sadly fail because of drupal_anonymous_user still returning a stdClass object instead of a user entity...
@see:
#1825332: Introduce an AccountInterface / UserInterface interface for use in \Drupal\Core namespaces and #1634280: drupal_anonymous_user() should return a User entity
#108
The last submitted patch, access-controller.patch, failed testing.
#109
The last submitted patch, access-controller.patch, failed testing.
#110
Great!
+++ b/lib/Drupal/profile2/ProfileAccessController.php@@ -0,0 +1,127 @@
+ protected function access(EntityInterface $profile, $operation, User $account = NULL) {
Can't we simply remove the User type-hints for now to get around the
drupal_anonymous_user()problem?+++ b/lib/Drupal/profile2/ProfileAccessController.php@@ -0,0 +1,127 @@
+ if (!isset($account)) {
+ $account = $GLOBALS['user'];
+ }
I think we need a
user_load($GLOBALS['user']->uid)here - the global $user object is not a real user entity.+++ b/lib/Drupal/profile2/ProfileAccessController.php@@ -0,0 +1,127 @@
+ $cid = $account->uid . ':' . $operation . ':' . $profile->id();
+ if (isset($this->accessCache[$cid])) {
+ return $this->accessCache[$cid];
+ }
I don't really understand why we're concatenating these — the cache is an array, so let's just make them multi-dimensional array keys?
+++ b/profile2.module@@ -503,57 +489,29 @@ function profile2_form_submit_cleanup(&$form, &$form_state) {
+function profile2_access($op, Profile $profile, User $account = NULL) {
+ return $profile->access($op, $account);
}
Isn't this obsolete?
+++ b/profile2.module@@ -503,57 +489,29 @@ function profile2_form_submit_cleanup(&$form, &$form_state) {
/**
* Implements hook_profile2_access().
*/
...
+function profile2_profile2_access($op, Profile $profile, User $account) {
...
+ if (user_access("$op any $profile->type profile", $account)) {
+ return TRUE;
+ }
+
+ if (isset($profile->uid) && $profile->uid == $account->uid && user_access("$op own $profile->type profile", $account)) {
+ return TRUE;
}
Shouldn't we move this into the access controller? A modular/extensible entity access system rather seems like a topic that core should figure out in a generic way, no?
#111
Sadly no... Not yet at least. We need it for the menu system. In the next patch I will convert our routes to the new routing system and provide proper menu system access checks. Once we have that we can remove it.
I agree, but let's keep it until we have it!
Yes, good idea. It's sadly the same problem as the one with anonymous users.
Sadly no, they are in the interface :/.
We gotta fix that here: #1825332: Introduce an AccountInterface / UserInterface interface for use in \Drupal\Core namespaces
Sure, why not :)
#112
This should pass. Again, good idea with the user_load().
#113
Ultra minor tuning for the entity_delete_multiple patch.
#114
Okay, or we just go with the array keys as pointed out by @sun :)
#115
Removing stray functions, files and properties and cleaning up documentation (also in api.php).
#116
Reverted removal of ProfileType::$uuid and $weight.
#117
Alrighty. AFAICS, the only remaining tasks are:
- Tests: The CRUD tests should be possible to use DrupalUnitTestBase. There are also @todos.
- profile2.tpl.php: Needs to be moved into ./templates + HTML5-ified.
- profile2.install: Still installs default "main" profile type. Based on earlier discussion, it looks like we simply want to delete that and leave the configuration to installation profiles.
#118
Attached patch eliminates the default "main" profile and adjusts tests.
#119
Deprecating profile2_load_by_user() (we don't like entity_* wrappers).
Tests are getting a bit more ugly with that. Could use a base test class with a helper function.
#120
Reverting the $type_id/$type_name/$type etc. changes. Follow-up cleanup material.
#121
The last submitted patch, profile2_load_by_user.patch, failed testing.
#122
#123
The last submitted patch, profile2_load_by_user.patch, failed testing.
#124
Sorry for the noise!
#125
Attached patch makes the template work (was unused) and updates it for HTML5 and stuff.
#126
We should extend ConfigEntityListController and not EntityListController for ProfileType
#127
Attached patch should address all issues that have been raised in #1668292-35: Move simplified Profile2 module into core (and some additional issues I encountered while stepping through the code and comparing it with other modules in core).
#128
The last submitted patch, profile2.cleanup.127.patch, failed testing.
#129
tl:dr; green patch => RTBC by monday evening latest
I already read through this patch once and I plan to do that again, and to try it out in all possible use-cases. I might (or might not) find some minor stuff in the code, but going by my first pass I highly doubt I will find anything substantial to complain about. I might only get to all that by Monday evening, but in case there was a green patch by that time for me to RTBC, it would be an honor. :-) Awesome work, you guys! Truely impressive.
#130
So I just gave this a spin. The profile type management works beautifully but I did catch some weird errors. What I did was check out 8.x-1.x of profile2 and then apply this patch on top of it.
At this point I'm assuming I did something wrong, either way, there's not much more to test due to this. :-/
Some feature-y things I noticed during the test that would be really cool.
#131
Here's that patch I was talking about. It's not a full re-roll, only an interdiff-patch, so as not to conflict with anything else going on in the background.
#132
Yeah we talked about that already and this is what we started for that: #1855402: Add generic weighting (tabledrag) support for config entities (ConfigEntityListController)
#133
Working on this.
The new load arguments revealed a bug in the menu system: #1863502: _menu_load_objects() does not pass already loaded arguments to subsequent argument loaders
#134
Re #132: I knew there was an issue for this! I had searched for ConfigEntity which apparently no one has typed in that issue. :-)
Re #133: Right, that makes total sense. (What doesn't make sense to me is that my PHP didn't complain about the type-hinting violation while the testbot did...) I hope to be able to update the tests over there and write some new ones Wednesday-ish unless you/someone beat(s) me to it.
#135
Fixed a couple of things.
Obviously, this patch won't pass without aforementioned core bug being fixed. Unless that core patch will land quickly, we should consider to go back to using %map in the menu argument loader.
#136
The last submitted patch, profile2.cleanup.134.patch, failed testing.
#137
Alright, now including temporary stop-gap fix.
#138
The ProfileAccessController currently relies on the profile id being available. For createAccess checks that's not really the case (because it doesn't have an id yet). Is it ok to simply cache on 'NULL' in that case? Do we want to cache based on the profile type instead and go with $profile->bundle() as the cache identifier?
#139
Adjusted access controller to conditionally use $profile->id() for existing profiles and $profile->bundle() for non-existing/new profiles.
#140
Nice! RTBC when this comes back green!
#141
Thanks - committed :)
One more final tweak — the $form structure of injected profile fields in the user registration form looks unnecessarily complex to me.
Attached patch performs a straightforward simplification.
#142
The last submitted patch, profile2.form-alter.141.patch, failed testing.
#143
The proposed changes to the form structure look nice. I can tell that you distaste constructed array keys. :)
#144
Fixed the test failures — and split that test method out into a new, dedicated ProfileAttachTest.
One of my goals was to eliminate the ProfileEditTest entirely before core inclusion... I'm not exactly sure what functionality is still asserted in there that isn't covered by new tests already.
#145
Cool. Maybe it's time for another patch over at the core issue.
#146
Thanks - committed.
Attached patch eliminates ProfileEditTest. And fixes a yet unnoticed fatal error upon deleting a profile. ;)
The CRUD parts of ProfileEditTest seem to be fully covered by the other existing tests already, so I removed that test method entirely.
#147
The last submitted patch, profile2.access-test.146.patch, failed testing.
#148
#146: profile2.access-test.146.patch queued for re-testing.
#149
I guess I am guilty as charged for that fatal :/. The patch looks good again. Let's roll another core patch.
#150
Alrighty. :)
#151
Chasing HEAD.
#152
The last submitted patch, profile2.head_.151.patch, failed testing.
#153
#154
The last submitted patch, profile2.head_.153.patch, failed testing.
#155
Jesus.
#156
The last submitted patch, profile2.head_.155.patch, failed testing.
#157
Wow... #1852966: Rework entity display settings around EntityDisplay config entity introduced a DX that is a PITA.
#158
Finally. Committed.
#159
Final clean-ups:
Only attach profiles for the account view.
Fixed phpDoc namespace references.
Clarified comments about create/update access being folded into edit access.
Clarified code/comment relationship for $pid determination in ProfileAccessController::access().
Clarified $access === TRUE condition in ProfileAccessController::access().
Use local variables $id and $label in hook_entity_info().
#160
The last submitted patch, profile2-8.x-1.x.patch, failed testing.
#161
@fubhy figured fit fout. :)
#162
The last submitted patch, profile2-8.x-1.x.patch, failed testing.
#163
Updated for new Field UI permissions.
#164
#165
#166
#167
The last submitted patch, profile2.patch, failed testing.
#168
#169
#170
Updated for latest changes in HEAD.
#171
Accounting for most feedback items from @webchick in http://drupal.org/node/1668292#comment-7081990
#172
Now including additional "Save and manage fields" submit button on the profile type creation form.
#173
#174
Bumping the thread. Where do we stand here?
#175
What can we do to move this forward?