diff --git a/lib/Drupal/profile2/Profile.php b/lib/Drupal/profile2/Profile.php index 449968a..4b661e3 100644 --- a/lib/Drupal/profile2/Profile.php +++ b/lib/Drupal/profile2/Profile.php @@ -69,7 +69,7 @@ class Profile extends Entity { // have that as interim label. $values['label'] = $type->label; } - parent::__construct($values, 'profile2'); + parent::__construct($values, $entity_type); } /** @@ -99,6 +99,20 @@ class Profile extends Entity { } /** + * Overwrites EntityInterface::id(). + */ + public function id() { + return isset($this->pid) ? $this->pid : NULL; + } + + /** + * Overwrites EntityInterface::bundle(). + */ + public function bundle() { + return $this->type; + } + + /** * Returns the full url() for the profile. */ public function url() { @@ -155,4 +169,3 @@ class Profile extends Entity { } } } - diff --git a/lib/Drupal/profile2/ProfileType.php b/lib/Drupal/profile2/ProfileType.php index 44acd39..c8fd5b5 100644 --- a/lib/Drupal/profile2/ProfileType.php +++ b/lib/Drupal/profile2/ProfileType.php @@ -7,47 +7,33 @@ namespace Drupal\profile2; -use Drupal\entity\Entity; +use Drupal\config\ConfigurableBase; /** * Use a separate class for profile types so we can specify some defaults * modules may alter. */ -class ProfileType extends Entity { +class ProfileType extends ConfigurableBase { + public $uuid; + public $id; + public $label; /** - * Whether the profile type appears in the user categories. + * Whether profile type is shown during registration. + * + * @var boolean */ - public $userCategory = TRUE; + public $registration = array(); /** * Whether the profile is displayed on the user account page. */ public $userView = TRUE; - public $type; - public $label; - public $weight = 0; - - /** - * Returns whether the profile type is locked, thus may not be deleted or renamed. - * - * Profile types provided in code are automatically treated as locked, as well - * as any fixed profile type. - */ - public function isLocked() { - return isset($this->status) && empty($this->is_new) && (($this->status & ENTITY_IN_CODE) || ($this->status & ENTITY_FIXED)); - } - /** - * Overridden, to introduce the method for old entity API versions (BC). - * - * @todo Remove once we bump the required entity API version. + * Implements Drupal\Core\Configurable\ConfigurableInterface::getConfigPrefix(). */ - public function getTranslation($property, $langcode = NULL) { - if (module_exists('profile2_i18n')) { - return parent::getTranslation($property, $langcode); - } - return $this->$property; + public static function getConfigPrefix() { + return 'profile2.type'; } } diff --git a/profile2.admin.inc b/profile2.admin.inc index f31ce59..f8ad1cc 100644 --- a/profile2.admin.inc +++ b/profile2.admin.inc @@ -5,30 +5,38 @@ * Profile type editing UI. */ +use Drupal\profile2\ProfileType; + /** * Generates the profile type editing form. */ -function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { - - if ($op == 'clone') { - $profile_type->label .= ' (cloned)'; - $profile_type->type = ''; +function profile2_type_form($form, &$form_state, $profile_type = NULL, $op = 'edit') { + // During initial form build, add the entity to the form state for use + // during form building and processing. During a rebuild, use what is in the + // form state. + if (!isset($form_state['profile2_type'])) { + if (!isset($profile_type)) { + $profile_type = entity_create('profile2_type', array('registration' => false)); + } + $form_state['profile2_type'] = $profile_type; + } + else { + $profile_type = $form_state['profile2_type']; } $form['label'] = array( '#title' => t('Label'), '#type' => 'textfield', - '#default_value' => $profile_type->label, + '#default_value' => $profile_type->label(), '#description' => t('The human-readable name of this profile type.'), '#required' => TRUE, '#size' => 30, ); // Machine-readable type name. - $form['type'] = array( + $form['id'] = array( '#type' => 'machine_name', - '#default_value' => isset($profile_type->type) ? $profile_type->type : '', + '#default_value' => $profile_type->get('id'), '#maxlength' => 32, - '#disabled' => $profile_type->isLocked() && $op != 'clone', '#machine_name' => array( 'exists' => 'profile2_get_types', 'source' => array('label'), @@ -36,11 +44,10 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { '#description' => t('A unique machine-readable name for this profile type. It must only contain lowercase letters, numbers, and underscores.'), ); - $form['data']['#tree'] = TRUE; - $form['data']['registration'] = array( + $form['registration'] = array( '#type' => 'checkbox', '#title' => t('Show during user account registration.'), - '#default_value' => !empty($profile_type->data['registration']), + '#default_value' => $profile_type->get('registration'), ); $form['actions'] = array('#type' => 'actions'); @@ -50,7 +57,7 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { '#weight' => 40, ); - if (!$profile_type->isLocked() && $op != 'add' && $op != 'clone') { + if ($op != 'add') { $form['actions']['delete'] = array( '#type' => 'submit', '#value' => t('Delete profile type'), @@ -66,9 +73,41 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { * Form API submit callback for the type form. */ function profile2_type_form_submit(&$form, &$form_state) { - $profile_type = entity_ui_form_submit_build_entity($form, $form_state); - // Save and go back. + form_state_values_clean($form_state); + + $profile_type = $form_state['profile2_type']; + entity_form_submit_build_entity('profile2_type', $profile_type, $form, $form_state); + $profile_type->save(); + + drupal_set_message(format_string('%label configuration has been saved.', array('%label' => $profile_type->label()))); + + $form_state['redirect'] = 'admin/structure/profiles'; +} + +/** + * Form constructor to delete a ProfileType object. + * + * @param Drupal\profile2\ProfileType $profile_type + * The ProfileType object to delete. + */ +function profile2_type_delete_form($form, &$form_state, ProfileType $profile_type) { + $form_state['profile2_type'] = $profile_type; + + $form['id'] = array('#type' => 'value', '#value' => $profile_type->id()); + return confirm_form($form, + format_string('Are you sure you want to delete %label', array('%label' => $profile_type->label())), + 'admin/structure/profiles', + NULL, + 'Delete' + ); +} + +/** + * Form submission handler for profile_type_delete_form(). + */ +function profile2_type_delete_form_submit($form, &$form_state) { + $form_state['profile2_type']->delete(); $form_state['redirect'] = 'admin/structure/profiles'; } @@ -76,5 +115,5 @@ function profile2_type_form_submit(&$form, &$form_state) { * Form API submit callback for the delete button. */ function profile2_type_form_submit_delete(&$form, &$form_state) { - $form_state['redirect'] = 'admin/structure/profiles/manage/' . $form_state['profile2_type']->type . '/delete'; + $form_state['redirect'] = 'admin/structure/profiles/manage/' . $form_state['profile2_type']->get('id') . '/delete'; } diff --git a/profile2.install b/profile2.install index 762b1ff..58c0288 100644 --- a/profile2.install +++ b/profile2.install @@ -12,11 +12,12 @@ function profile2_install() { // Add an initial profile type, but only if installed manually. In case the // module is installed via an installation profile, skip that. if (!drupal_installation_attempted()) { + entity_info_cache_clear(); $type = entity_create('profile2_type', array( - 'type' => 'main', + 'id' => 'main', 'label' => t('Main profile'), 'weight' => 0, - 'data' => array('registration' => TRUE, 'use_page' => TRUE), + 'registration' => TRUE, )); $type->save(); user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('edit own main profile', 'view own main profile')); @@ -83,63 +84,6 @@ function profile2_schema() { ), 'primary key' => array('pid'), ); - - $schema['profile_type'] = array( - 'description' => 'Stores information about all defined profile types.', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique profile type ID.', - ), - 'type' => array( - 'description' => 'The machine-readable name of this profile type.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - ), - 'label' => array( - 'description' => 'The human-readable name of this profile type.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'weight' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'size' => 'tiny', - 'description' => 'The weight of this profile type in relation to others.', - ), - 'data' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - 'serialize' => TRUE, - 'description' => 'A serialized array of additional data related to this profile type.', - ), - 'status' => array( - 'type' => 'int', - 'not null' => TRUE, - // Set the default to ENTITY_CUSTOM without using the constant as it is - // not safe to use it at this point. - 'default' => 0x01, - 'size' => 'tiny', - 'description' => 'The exportable status of the entity.', - ), - 'module' => array( - 'description' => 'The name of the providing module if the entity has been defined in code.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'type' => array('type'), - ), - ); return $schema; } diff --git a/profile2.module b/profile2.module index de49a0e..77e3856 100644 --- a/profile2.module +++ b/profile2.module @@ -17,14 +17,8 @@ function profile2_entity_info() { 'label' => t('Profile'), 'entity class' => 'Drupal\profile2\Profile', 'base table' => 'profile', - 'uri callback' => 'profile2_uri', + 'uri callback' => 'profile2_profile_uri', 'fieldable' => TRUE, - 'view modes' => array( - 'account' => array( - 'label' => t('User account'), - 'custom settings' => FALSE, - ), - ), 'entity keys' => array( 'id' => 'pid', 'bundle' => 'type', @@ -32,28 +26,28 @@ function profile2_entity_info() { ), 'bundles' => array(), 'bundle keys' => array( - 'bundle' => 'type', + 'bundle' => 'id', + ), + 'view modes' => array( + 'account' => array( + 'label' => t('User account'), + 'custom settings' => FALSE, + ), ), - 'label callback' => 'entity_class_label', - 'uri callback' => 'entity_class_uri', 'access callback' => 'profile2_access', - 'module' => 'profile2', - 'metadata controller class' => 'Drupal\profile2\MetadataController', ), ); // Add bundle info but bypass entity_load() as we cannot use it here. - $types = db_select('profile_type', 'p') - ->fields('p') - ->execute() - ->fetchAllAssoc('type'); - - foreach ($types as $type => $info) { - $return['profile2']['bundles'][$type] = array( - 'label' => $info->label, + $config_names = config_get_storage_names_with_prefix('profile2.type.'); + foreach ($config_names as $config_name) { + $config = config($config_name); + + $return['profile2']['bundles'][$config->get('id')] = array( + 'label' => $config->get('label'), 'admin' => array( 'path' => 'admin/structure/profiles/manage/%profile2_type', - 'real path' => 'admin/structure/profiles/manage/' . $type, + 'real path' => 'admin/structure/profiles/manage/' . $config->get('id'), 'bundle argument' => 4, 'access arguments' => array('administer profiles'), ), @@ -69,23 +63,17 @@ function profile2_entity_info() { $return['profile2_type'] = array( 'label' => t('Profile type'), 'entity class' => 'Drupal\profile2\ProfileType', - 'base table' => 'profile_type', + 'controller class' => 'Drupal\config\ConfigStorageController', 'fieldable' => FALSE, 'bundle of' => 'profile2', - 'exportable' => TRUE, - 'uri callback' => 'profile2_type_uri', + 'config prefix' => 'profile2.type', + 'uri callback' => 'profile2_profile_type_uri', 'entity keys' => array( 'id' => 'id', - 'name' => 'type', 'label' => 'label', ), 'access callback' => 'profile2_type_access', 'module' => 'profile2', - // Enable the entity API's admin UI. - 'admin ui' => array( - 'path' => 'admin/structure/profiles', - 'controller class' => 'Drupal\profile2\TypeUIController', - ), ); return $return; @@ -97,7 +85,7 @@ function profile2_entity_info() { * @param Drupal\profile2\Profile $profile * A Profile entity. */ -function profile2_uri(Profile $profile) { +function profile2_profile_uri(Profile $profile) { return array( 'path' => 'admin/structure/profiles', ); @@ -109,13 +97,97 @@ function profile2_uri(Profile $profile) { * @param Drupal\profile2\ProfileType $profile_type * A ProfileType entity. */ -function profile2_type_uri(ProfileType $profile) { +function profile2_profile_type_uri(ProfileType $profile_type) { return array( 'path' => 'admin/structure/profiles/manage', ); } /** + * Implements hook_menu(). + */ +function profile2_menu() { + $items['admin/structure/profiles'] = array( + 'title' => 'Profile types', + 'description' => 'Manage profiles, including fields.', + 'page callback' => 'profile2_type_list_page', + 'access callback' => TRUE, + ); + $items['admin/structure/profiles/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/structure/profiles/add'] = array( + 'title' => 'Add profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_form'), + 'access callback' => TRUE, + 'type' => MENU_LOCAL_ACTION, + 'file' => 'profile2.admin.inc', + ); + $items['admin/structure/profiles/manage/%profile2_type'] = array( + 'title' => 'Edit profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_form', 4), + 'access callback' => TRUE, + 'file' => 'profile2.admin.inc', + ); + $items['admin/structure/profiles/manage/%profile2_type/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/structure/profiles/manage/%profile2_type/delete'] = array( + 'title' => 'Delete profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_delete_form', 4), + 'access callback' => TRUE, + 'type' => MENU_LOCAL_ACTION, + 'file' => 'profile2.admin.inc', + ); + + return $items; +} + +/** + * Page callback; Lists available Profile objects. + */ +function profile2_type_list_page() { + $field_ui = module_exists('field_ui'); + $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => $field_ui ? '4' : '2')); + $rows = array(); + foreach (entity_load_multiple('profile2_type') as $profile_type) { + $row = array($profile_type->label().' ' . t('(Machine name: @type)', array('@type' => $profile_type->get('id'))) . ''); + + // Set the edit column. + $row[] = array('data' => l(t('edit'), 'admin/structure/profiles/manage/' . $profile_type->get('id'))); + + if ($field_ui) { + // Manage fields. + $row[] = array('data' => l(t('manage fields'), 'admin/structure/profiles/manage/' . $profile_type->get('id') . '/fields')); + + // Display fields. + $row[] = array('data' => l(t('manage display'), 'admin/structure/profiles/manage/' . $profile_type->get('id') . '/display')); + } + + // Set the delete column. + $row[] = array('data' => l(t('delete'), 'admin/structure/profiles/manage/' . $profile_type->get('id') . '/delete')); + + $rows[] = $row; + } + + $build = array( + '#theme' => 'table', + '#header' => $header, + '#rows' => $rows, + '#empty' => t('No profile types available. Add profile type.', array('@link' => url('admin/structure/profiles/add'))), + ); + + return $build; +} + +/** * Menu argument loader; Load a profile type by string. * * @param $type @@ -134,7 +206,7 @@ function profile2_permission() { $permissions = array( 'administer profile types' => array( 'title' => t('Administer profile types'), - 'description' => t('Create and delete fields on user profiles, and set their permissions.'), + 'description' => t('Create and delete fields on user profiles and set their permissions.'), ), 'administer profiles' => array( 'title' => t('Administer profiles'), @@ -143,19 +215,19 @@ function profile2_permission() { ); // Generate per profile type permissions. foreach (profile2_get_types() as $type) { - $type_name = check_plain($type->type); + $type_name = check_plain($type->get('id')); $permissions += array( "edit own $type_name profile" => array( - 'title' => t('%type_name: Edit own profile', array('%type_name' => $type->getTranslation('label'))), + 'title' => t('%type_name: Edit own profile', array('%type_name' => $type->get('label'))), ), "edit any $type_name profile" => array( - 'title' => t('%type_name: Edit any profile', array('%type_name' => $type->getTranslation('label'))), + 'title' => t('%type_name: Edit any profile', array('%type_name' => $type->get('label'))), ), "view own $type_name profile" => array( - 'title' => t('%type_name: View own profile', array('%type_name' => $type->getTranslation('label'))), + 'title' => t('%type_name: View own profile', array('%type_name' => $type->get('label'))), ), "view any $type_name profile" => array( - 'title' => t('%type_name: View any profile', array('%type_name' => $type->getTranslation('label'))), + 'title' => t('%type_name: View any profile', array('%type_name' => $type->get('label'))), ), ); } @@ -163,16 +235,21 @@ function profile2_permission() { } /** - * Gets an array of all profile types, keyed by the type name. + * Gets an array of all profile types, keyed by the machine name. * - * @param $type_name - * If set, the type with the given name is returned. + * @param $type_id + * If set, the type with the given machine name is returned. * @return ProfileType[] * Depending whether $type isset, an array of profile types or a single one. */ -function profile2_get_types($type_name = NULL) { - $types = entity_load_multiple_by_name('profile2_type', isset($type_name) ? array($type_name) : FALSE); - return isset($type_name) ? reset($types) : $types; +function profile2_get_types($type_id = NULL) { + $types = entity_load_multiple('profile2_type', NULL, TRUE); + foreach ($types as $id => $type) { + if (!is_null($type_id) && $type->get('id') != $type_id) { + unset($types[$id]); + } + } + return isset($type_id) ? reset($types) : $types; } /** @@ -188,28 +265,38 @@ function profile2_get_types($type_name = NULL) { * @see profile2_load_multiple() */ function profile2_load($pid, $reset = FALSE) { - $profiles = profile2_load_multiple(array($pid), array(), $reset); + $profiles = profile2_load_multiple(array($pid), $reset); return reset($profiles); } /** - * Load multiple profiles based on certain conditions. + * Load multiple profiles based on profile IDs. * * @param $pids * An array of profile IDs. - * @param $conditions - * An array of conditions to match against the {profile} table. * @param $reset * A boolean indicating that the internal cache should be reset. * @return * An array of profile objects, indexed by pid. * - * @see entity_load() - * @see profile2_load() - * @see profile2_load_by_user() + * @see entity_load_multiple() */ -function profile2_load_multiple($pids = array(), $conditions = array(), $reset = FALSE) { - return entity_load('profile2', $pids, $conditions, $reset); +function profile2_load_multiple($pids = array(), $reset = FALSE) { + return entity_load_multiple('profile2', $pids, $reset); +} + +/** + * Load multiple profiles based on certain conditions. + * + * @param $properties + * An array of properties to match against the {profile} table. + * @return + * An array of profile objects + * + * @see entity_load_multiple_by_properties() + */ +function profile2_load_multiple_by_properties($properties = array()) { + return entity_load_multiple_by_properties('profile2', $properties); } /** @@ -235,7 +322,7 @@ function profile2_load_by_user($account, $type_name = NULL) { if (!isset($cache[$uid])) { if (empty($type_name)) { - $profiles = profile2_load_multiple(FALSE, array('uid' => $uid)); + $profiles = profile2_load_multiple_by_properties(array('uid' => $uid)); // Cache ids for further lookups. $cache[$uid] = array(); foreach ($profiles as $pid => $profile) { @@ -295,7 +382,7 @@ function profile2_user_delete($account) { * Create a new profile object. */ function profile2_create(array $values) { - return new Profile($values); + return new Profile($values, 'profile2'); } /** @@ -330,19 +417,6 @@ function profile2_type_delete(ProfileType $type) { } /** -* Implements hook_profile2_type_delete() -*/ -function profile2_profile2_type_delete(ProfileType $type) { - // Delete all profiles of this type but only if this is not a revert. - if (!$type->hasStatus(ENTITY_IN_CODE)) { - $pids = array_keys(profile2_load_multiple(FALSE, array('type' => $type->type))); - if ($pids) { - profile2_delete_multiple($pids); - } - } -} - -/** * Implements hook_user_view(). */ function profile2_user_view($account, $view_mode, $langcode) { @@ -367,16 +441,21 @@ function profile2_user_view($account, $view_mode, $langcode) { * @see profile2_form_submit_handler */ function profile2_form_user_profile_form_alter(&$form, &$form_state) { - if (($type = profile2_get_types($form['#user_category'])) && $type->userCategory) { - if (empty($form_state['profiles'])) { - $profile = profile2_load_by_user($form['#user'], $form['#user_category']); - if (empty($profile)) { - $profile = profile2_create(array('type' => $form['#user_category'], 'uid' => $form['#user']->uid)); - } - $form_state['profiles'][$profile->type] = $profile; + // #user_category no longer exists, use fieldsets instead + foreach (profile2_get_types() as $type_name => $profile_type) { + $profile = profile2_load_by_user($form_state['entity'], $type_name); + if (empty($profile)) { + $profile = profile2_create(array('type' => $type_name, 'uid' => $form_state['entity']->uid)); } + $form_state['profiles'][$profile->type] = $profile; profile2_attach_form($form, $form_state); + // Wrap each profile form in a fieldset. + $form['profile_' . $type_name] += array( + '#type' => 'fieldset', + '#title' => check_plain($profile_type->get('label')), + ); } + return; } /** @@ -384,7 +463,7 @@ function profile2_form_user_profile_form_alter(&$form, &$form_state) { */ function profile2_form_user_register_form_alter(&$form, &$form_state) { foreach (profile2_get_types() as $type_name => $profile_type) { - if (!empty($profile_type->data['registration'])) { + if ($profile_type->get('registration')) { if (empty($form_state['profiles'][$type_name])) { $form_state['profiles'][$type_name] = profile2_create(array('type' => $type_name)); } @@ -392,7 +471,7 @@ function profile2_form_user_register_form_alter(&$form, &$form_state) { // Wrap each profile form in a fieldset. $form['profile_' . $type_name] += array( '#type' => 'fieldset', - '#title' => check_plain($profile_type->getTranslation('label')), + '#title' => check_plain($profile_type->get('label')), ); } } @@ -417,12 +496,13 @@ function profile2_form_user_register_form_alter(&$form, &$form_state) { */ function profile2_attach_form(&$form, &$form_state) { foreach ($form_state['profiles'] as $type => $profile) { - $form['profile_' . $profile->type]['#tree'] = TRUE; - $form['profile_' . $profile->type]['#parents'] = array('profile_' . $profile->type); - field_attach_form('profile2', $profile, $form['profile_' . $profile->type], $form_state); + $form['profile_' . $profile->get('type')]['#tree'] = TRUE; + $form['profile_' . $profile->get('type')]['#parents'] = array('profile_' . $profile->get('type')); - if (count(field_info_instances('profile2', $profile->type)) == 0) { - $form['profile_' . $profile->type]['message'] = array( + field_attach_form('profile2', $profile, $form['profile_' . $profile->get('type')], $form_state); + + if (count(field_info_instances('profile2', $profile->get('type'))) == 0) { + $form['profile_' . $profile->get('type')]['message'] = array( '#access' => user_access('administer profile types'), '#markup' => t('No fields have been associated with this profile type. Go to the Profile types page to add some fields.', array('!url' => url('admin/structure/profiles'))), ); @@ -438,7 +518,7 @@ function profile2_attach_form(&$form, &$form_state) { } } $form['#validate'][] = 'profile2_form_validate_handler'; - $form['#submit'][] = 'profile2_form_submit_handler'; + $form_state['submit_handlers'][] = 'profile2_form_submit_handler'; } /** @@ -448,13 +528,15 @@ function profile2_attach_form(&$form, &$form_state) { */ function profile2_form_validate_handler(&$form, &$form_state) { foreach ($form_state['profiles'] as $type => $profile) { - if (isset($form_state['values']['profile_' . $profile->type])) { + if (isset($form_state['values']['profile_' . $profile->get('id')])) { // @see entity_form_field_validate() - $pseudo_entity = (object) $form_state['values']['profile_' . $profile->type]; - $pseudo_entity->type = $type; - field_attach_form_validate('profile2', $pseudo_entity, $form['profile_' . $profile->type], $form_state); + $pseudo_entity = new Profile(array_merge($form_state['values']['profile_' . $profile->get('id')], array('type' => $type))); + field_attach_form_validate('profile2', $pseudo_entity, $form['profile_' . $profile->get('id')], $form_state); } } + + // @todo Looking for a better solution; this one looks like a ugly hack + $form_state['submit_handlers'][] = 'profile2_form_submit_handler'; } /** @@ -506,36 +588,6 @@ function profile2_form_submit_cleanup(&$form, &$form_state) { } /** - * Implements hook_user_categories(). - */ -function profile2_user_categories() { - $data = array(); - foreach (profile2_get_types() as $type => $info) { - if ($info->userCategory) { - $data[] = array( - 'name' => $type, - 'title' => $info->getTranslation('label'), - // Add an offset so a weight of 0 appears right of the account category. - 'weight' => $info->weight + 3, - 'access callback' => 'profile2_category_access', - 'access arguments' => array(1, $type) - ); - } - } - return $data; -} - -/** - * Menu item access callback - check if a user has access to a profile category. - */ -function profile2_category_access($account, $type_name) { - // As there might be no profile yet, create a new object for being able to run - // a proper access check. - $profile = profile2_create(array('type' => $type_name, 'uid' => $account->uid)); - return ($account->uid > 0 && $profile->type()->userCategory && profile2_access('edit', $profile)); -} - -/** * Determines whether the given user has access to a profile. * * @param $op