{"action":"created","issue":{"url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/810","labels_url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/810/labels{/name}","comments_url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/810/comments","events_url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/810/events","html_url":"https://github.com/backdrop/backdrop-issues/issues/810","id":60948099,"number":810,"title":"user_modules_uninstalled calls hook_permissions after module's schema is deleted","user":{"login":"jromine","id":350497,"avatar_url":"https://avatars.githubusercontent.com/u/350497?v=3","gravatar_id":"","url":"https://api.github.com/users/jromine","html_url":"https://github.com/jromine","followers_url":"https://api.github.com/users/jromine/followers","following_url":"https://api.github.com/users/jromine/following{/other_user}","gists_url":"https://api.github.com/users/jromine/gists{/gist_id}","starred_url":"https://api.github.com/users/jromine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jromine/subscriptions","organizations_url":"https://api.github.com/users/jromine/orgs","repos_url":"https://api.github.com/users/jromine/repos","events_url":"https://api.github.com/users/jromine/events{/privacy}","received_events_url":"https://api.github.com/users/jromine/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-03-13T00:47:11Z","updated_at":"2015-03-13T02:01:12Z","closed_at":null,"body":"When uninstalling a module, `backdrop_uninstall_modules()` iterates through the list of modules to uninstall, and invokes `hook_uninstall()` on each, followed by `backdrop_uninstall_schema()` and some other tasks. Afterwards, `hook_modules_uninstalled()` is called to allow other modules to react.\r\n\r\n`user_modules_uninstalled()` wants to remove any permissions that the newly-uninstalled modules may have provided, so it calls `hook_permissions()` on the now uninstalled modules. I think this call is out-of-order, and it's causing a problem with flag module (port in progress) as described below.\r\n\r\nflag module provides a permission of 'flag flagname' and 'unflag flagname', for each flag that is created. However, to respond to `hook_permissions()` it needs to query the database for its list of implemented flags. This isn't possible once `backdrop_uninstall_schema()` is run.\r\n\r\nDrupal 7 doesn't have this issue since `user_modules_uninstalled()` doesn't invoke `hook_permissions()`.  I think user module should not call `hook_permissions()` on modules that are no longer installed.  Perhaps a new pre-uninstall hook needs to be added for use cases like the one user module is trying to implement."},"comment":{"url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/comments/78745883","html_url":"https://github.com/backdrop/backdrop-issues/issues/810#issuecomment-78745883","issue_url":"https://api.github.com/repos/backdrop/backdrop-issues/issues/810","id":78745883,"user":{"login":"jromine","id":350497,"avatar_url":"https://avatars.githubusercontent.com/u/350497?v=3","gravatar_id":"","url":"https://api.github.com/users/jromine","html_url":"https://github.com/jromine","followers_url":"https://api.github.com/users/jromine/followers","following_url":"https://api.github.com/users/jromine/following{/other_user}","gists_url":"https://api.github.com/users/jromine/gists{/gist_id}","starred_url":"https://api.github.com/users/jromine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jromine/subscriptions","organizations_url":"https://api.github.com/users/jromine/orgs","repos_url":"https://api.github.com/users/jromine/repos","events_url":"https://api.github.com/users/jromine/events{/privacy}","received_events_url":"https://api.github.com/users/jromine/received_events","type":"User","site_admin":false},"created_at":"2015-03-13T02:01:12Z","updated_at":"2015-03-13T02:01:12Z","body":"D7 just deletes rows from the role_permissions table, based on the role_permissions.module value.  Backdrop stores the permissions with the roles, and it doesn't know which module initially provided each permission.\r\n\r\nOffhand, a few strategies for fixing this:\r\n- change the order of operations so hook_modules_uninstalled() is called earlier\r\n- add a new earlier pre-uninstall hook (like hook_entity_predelete) that user module can use\r\n- make user module track the permissions/modules together so it can remove permissions later without help.\r\n"}}