diff --git a/lib/Drupal/profile2/Profile.php b/lib/Drupal/profile2/Profile.php index bc8d6c9..8f361ab 100644 --- a/lib/Drupal/profile2/Profile.php +++ b/lib/Drupal/profile2/Profile.php @@ -29,13 +29,6 @@ class Profile extends Entity { public $type; /** - * The profile label. - * - * @var string - */ - public $label; - - /** * The user id of the profile owner. * * @var integer @@ -56,92 +49,45 @@ class Profile extends Entity { */ public $changed; - public function __construct(array $values = array(), $entity_type) { - if (isset($values['user'])) { - $this->setUser($values['user']); - unset($values['user']); - } - if (isset($values['type']) && is_object($values['type'])) { - $values['type'] = $values['type']->type; - } - if (!isset($values['label']) && isset($values['type']) && $type = profile2_type_load($values['type'])) { - // Initialize the label with the type label, so newly created profiles - // have that as interim label. - $values['label'] = $type->label; - } - parent::__construct($values, $entity_type); - } - /** * Returns the user owning this profile. + * + * @return Drupal\user\User + * The user owning this profile. */ public function user() { return user_load($this->uid); } /** - * Sets a new user owning this profile. + * Returns the associated profile type. * - * @param $account - * The user account object or the user account id (uid). - */ - public function setUser($account) { - $this->uid = is_object($account) ? $account->uid : $account; - } - - /** - * Gets the associated profile type object. - * - * @return ProfileType + * @return Drupal\profile2\ProfileType + * The associated profile type object. */ public function type() { return profile2_type_load($this->type); } /** - * Overwrites EntityInterface::id(). + * Overrides Drupal\Core\Entity\Entity::id(). */ public function id() { return isset($this->pid) ? $this->pid : NULL; } /** - * Overwrites EntityInterface::bundle(). + * Overrides Drupal\Core\Entity\Entity::bundle(). */ public function bundle() { return $this->type; } /** - * Returns the full url() for the profile. - */ - public function url() { - $uri = $this->uri(); - return url($uri['path'], $uri); - } - - /** - * Returns the drupal path to this profile. + * Overrides Drupal\Core\Entity\Entity::label(). */ - public function path() { - $uri = $this->uri(); - return $uri['path']; - } - - public function defaultUri() { - return array( - 'path' => 'user/' . $this->uid, - 'options' => array('fragment' => 'profile-' . $this->type), - ); - } - - public function defaultLabel() { - if (module_exists('profile2_i18n')) { - // Run the label through i18n_string() using the profile2_type label - // context, so the default label (= the type's label) gets translated. - return entity_i18n_string('profile2:profile2_type:' . $this->type . ':label', $this->label); - } - return $this->label; + public function label($langcode = NULL) { + return $this->type()->label(); } } diff --git a/lib/Drupal/profile2/ProfileFormController.php b/lib/Drupal/profile2/ProfileFormController.php index dd765be..5e7dd36 100644 --- a/lib/Drupal/profile2/ProfileFormController.php +++ b/lib/Drupal/profile2/ProfileFormController.php @@ -20,10 +20,6 @@ class ProfileFormController extends EntityFormController { protected function actionsElement(array $form, array &$form_state) { $element = parent::actionsElement($form, $form_state); - if (!user_access('administer profiles')) { - unset($element['delete']); - } - return $element; } @@ -40,6 +36,17 @@ class ProfileFormController extends EntityFormController { else { drupal_set_message(t("%name's profile has been updated.", array('%name' => user_format_name(user_load($profile->uid))))); } + + $uri = $profile->uri(); + $form_state['redirect'] = array($uri['path'], $uri['options']); + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::delete(). + */ + public function delete(array $form, array &$form_state) { + $profile = $this->getEntity($form_state); + $form_state['redirect'] = 'user/' . $profile->uid . '/edit/' . $profile->bundle() . '/delete'; } } diff --git a/lib/Drupal/profile2/ProfileStorageController.php b/lib/Drupal/profile2/ProfileStorageController.php index bd6ef46..808986e 100644 --- a/lib/Drupal/profile2/ProfileStorageController.php +++ b/lib/Drupal/profile2/ProfileStorageController.php @@ -37,30 +37,4 @@ class ProfileStorageController extends DatabaseStorageController { $entity->changed = REQUEST_TIME; } - /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::postSave(). - */ - protected function postSave(EntityInterface $entity, $update) { - parent::postSave($entity, $update); - - // Update the static cache from profile2_load_by_user(). - $cache = &drupal_static('profile2_load_by_user', array()); - unset($cache[$entity->uid]); - - if ($update) { - unset($cache[$entity->original->uid]); - } - } - - /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::postSave(). - */ - protected function postDelete($entities) { - // Update the static cache from profile2_load_by_user(). - $cache = &drupal_static('profile2_load_by_user', array()); - foreach ($entities as $entity) { - unset($cache[$entity->uid]); - } - } - } diff --git a/lib/Drupal/profile2/ProfileTypeFormController.php b/lib/Drupal/profile2/ProfileTypeFormController.php index ef5cd3e..951d180 100644 --- a/lib/Drupal/profile2/ProfileTypeFormController.php +++ b/lib/Drupal/profile2/ProfileTypeFormController.php @@ -66,4 +66,5 @@ class ProfileTypeFormController extends EntityFormController { $type = $this->getEntity($form_state); $form_state['redirect'] = 'admin/structure/profiles/manage/' . $type->id() . '/delete'; } + } diff --git a/lib/Drupal/profile2/Tests/ProfileCRUDTest.php b/lib/Drupal/profile2/Tests/ProfileCRUDTest.php index bf29da1..1894b77 100644 --- a/lib/Drupal/profile2/Tests/ProfileCRUDTest.php +++ b/lib/Drupal/profile2/Tests/ProfileCRUDTest.php @@ -46,7 +46,7 @@ class ProfileCRUDTest extends WebTestBase { )); $this->assertIdentical($profile->id(), NULL); $this->assertIdentical($profile->type, $expected['type']); - $this->assertIdentical($profile->label, $types[0]->label()); + $this->assertIdentical($profile->label(), $types[0]->label()); $this->assertIdentical($profile->uid, $this->user1->id()); $this->assertIdentical($profile->created, REQUEST_TIME); $this->assertIdentical($profile->changed, NULL); diff --git a/lib/Drupal/profile2/Tests/ProfileEditTest.php b/lib/Drupal/profile2/Tests/ProfileEditTest.php index 1ca5d8c..741e187 100644 --- a/lib/Drupal/profile2/Tests/ProfileEditTest.php +++ b/lib/Drupal/profile2/Tests/ProfileEditTest.php @@ -78,10 +78,6 @@ class ProfileEditTest extends WebTestBase { $this->assertEqual($profiles['test']->label(), 'label', 'Created and loaded profile 1.'); $this->assertEqual($profiles['test2']->label(), 'label2', 'Created and loaded profile 2.'); - // Test looking up from static cache works also. - $profiles = profile2_load_by_user($user1); - $this->assertEqual($profiles['test']->label, 'label', 'Looked up profiles again.'); - $loaded = entity_load('profile2', $profile->pid); $this->assertEqual($loaded->pid, $profile->pid, 'Loaded profile unrelated to a user.'); diff --git a/profile2.admin.inc b/profile2.admin.inc index 6cf7111..2614947 100644 --- a/profile2.admin.inc +++ b/profile2.admin.inc @@ -28,7 +28,18 @@ function profile2_type_add() { * A form array as expected by drupal_render(). */ function profile2_type_edit(ProfileType $type) { - drupal_set_title(t('Edit %label profile type', array('%label' => $type->label)), PASS_THROUGH); + drupal_set_title(t('Edit %label profile type', array('%label' => $type->label())), PASS_THROUGH); + return entity_get_form($type); +} + +/** + * Page callback: Presents the form for creating a profile type. + * + * @return array + * A form array as expected by drupal_render(). + */ +function profile2_type_delete() { + $type = entity_create('profile2_type', array()); return entity_get_form($type); } diff --git a/profile2.module b/profile2.module index 7799374..34e942f 100644 --- a/profile2.module +++ b/profile2.module @@ -80,22 +80,15 @@ function profile2_entity_info() { /** * Entity URI callback for profiles. - * - * @param Drupal\profile2\Profile $profile - * A Profile entity. */ function profile2_profile_uri(Profile $profile) { - // @todo Call into user_uri() to ensure consistent URIs? - return array( - 'path' => 'user/' . $profile->uid, - ); + $uri = user_uri(entity_load('user', $profile->uid)); + $uri['options']['fragment'] = 'profile-' . $profile->bundle(); + return $uri; } /** * Entity URI callback for profile types. - * - * @param Drupal\profile2\ProfileType $profile_type - * A profile type entity. */ function profile2_profile_type_uri(ProfileType $profile_type) { return array( @@ -162,6 +155,16 @@ function profile2_menu() { 'page arguments' => array(3), 'type' => MENU_LOCAL_TASK, ); + $items['user/%user/edit/%profile2_menu/delete'] = array( + 'load arguments' => array('%map', 'edit'), + 'title' => 'Delete profile', + 'access callback' => 'profile2_profile_edit_access', + 'access arguments' => array(3), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_delete_confirm_form', 3), + 'type' => MENU_CALLBACK, + 'file' => 'profile2.pages.inc', + ); return $items; } @@ -214,7 +217,7 @@ function profile2_menu_local_tasks_alter(&$data, $router_item, $root_path) { } } // Expand the dynamic %profile_menu argument into a tab for each type. - $types = profile2_get_types(); + $types = entity_load_multiple('profile2_type'); foreach ($types as $type) { // If the current page is the active tab registered in hook_menu(), then // the menu router item with the dynamic argument will be exposed already. @@ -251,16 +254,23 @@ function profile2_type_list_page() { } /** - * Menu argument loader; Load a profile type by string. - * - * @param string $id - * The machine-readable name of a profile type to load. - * - * @return Drupal\profile2\ProfileType|false - * A profile type array or FALSE if $type does not exist. + * Menu callback for loading a profile type. */ -function profile2_type_load($id) { - return entity_load('profile2_type', $id); +function profile2_type_load($type) { + return entity_load('profile2_type', $type); +} + +function profile2_load_by_user(User $user, $type = NULL) { + if (empty($type)) { + $profiles = entity_load_multiple_by_properties('profile2', array('uid' => $user->get('uid'))); + $output = array(); + foreach ($profiles as $profile) { + $output[$profile->bundle()] = $profile; + } + return $output; + } + $results = entity_load_multiple_by_properties('profile2', array('uid' => $user->uid, 'type' => $type)); + return reset($results); } /** @@ -278,7 +288,7 @@ function profile2_permission() { ), ); // Generate per profile type permissions. - foreach (profile2_get_types() as $type) { + foreach (entity_load_multiple('profile2_type') as $type) { $type_name = $type->id(); $permissions += array( "edit own $type_name profile" => array( @@ -299,59 +309,6 @@ function profile2_permission() { } /** - * Gets an array of all profile types, keyed by the machine name. - * - * @return array - * An array of profile type objects. - */ -function profile2_get_types() { - return entity_load_multiple('profile2_type'); -} - -/** - * Fetch profiles by account. - * - * @param $account - * The user account to load profiles for, or its uid. - * @param $type_name - * To load a single profile, pass the type name of the profile to load. - * @return - * Either a single profile or an array of profiles keyed by profile type. - * - * @see profile2_profile2_delete() - * @see Profile::save() - */ -function profile2_load_by_user($account, $type_name = NULL) { - // Use a separate query to determine all profile ids per user and cache them. - // That way we can look up profiles by id and benefit from the static cache - // of the entity loader. - $cache = &drupal_static(__FUNCTION__, array()); - $uid = is_object($account) ? $account->uid : $account; - - if (!isset($cache[$uid])) { - if (empty($type_name)) { - $profiles = entity_load_multiple_by_properties('profile2', array('uid' => $uid)); - // Cache ids for further lookups. - $cache[$uid] = array(); - foreach ($profiles as $pid => $profile) { - $cache[$uid][$profile->type] = $pid; - } - return $profiles ? array_combine(array_keys($cache[$uid]), $profiles) : array(); - } - $cache[$uid] = db_select('profile', 'p') - ->fields('p', array('type', 'pid')) - ->condition('uid', $uid) - ->execute() - ->fetchAllKeyed(); - } - if (isset($type_name)) { - return isset($cache[$uid][$type_name]) ? entity_load('profile2', $cache[$uid][$type_name]) : FALSE; - } - // Return an array containing profiles keyed by profile type. - return $cache[$uid] ? array_combine(array_keys($cache[$uid]), entity_load_multiple('profile2', $cache[$uid])) : $cache[$uid]; -} - -/** * Implements hook_user_predelete(). */ function profile2_user_predelete($account) { @@ -363,14 +320,14 @@ function profile2_user_predelete($account) { /** * Implements hook_user_view(). */ -function profile2_user_view($account, $view_mode, $langcode) { - foreach (profile2_get_types() as $id => $type) { +function profile2_user_view(User $account, $view_mode, $langcode) { + foreach (entity_load_multiple('profile2_type') as $id => $type) { if ($type->userView && $profile = profile2_load_by_user($account, $id)) { if (profile2_access('view', $profile)) { $account->content['profile_' . $id] = array( '#type' => 'user_profile_category', - '#title' => $profile->label, - '#prefix' => '', + '#title' => $profile->label(), + '#prefix' => '', ); entity_render_controller('profile2')->buildContent(array($profile), 'account'); $account->content['profile_' . $id]['view'] = $profile->content; @@ -383,7 +340,7 @@ function profile2_user_view($account, $view_mode, $langcode) { * Implements hook_form_FORM_ID_alter() for the registration form. */ function profile2_form_user_register_form_alter(&$form, &$form_state) { - foreach (profile2_get_types() as $id => $type) { + foreach (entity_load_multiple('profile2_type') as $id => $type) { if ($type->get('registration')) { if (empty($form_state['profiles'][$id])) { $form_state['profiles'][$id] = entity_create('profile2', array('type' => $id)); @@ -649,13 +606,3 @@ function profile2_field_access($op, $field, $entity_type, $profile = NULL, $acco } } } - -/** - * Entity metadata callback to load profiles for the given user account. - */ -function profile2_user_get_properties($account, array $options, $name) { - // Remove the leading 'profile_' from the property name to get the type name. - $profile = profile2_load_by_user($account, substr($name, 8)); - return $profile ? $profile : NULL; -} - diff --git a/profile2.pages.inc b/profile2.pages.inc new file mode 100644 index 0000000..1ebff1c --- /dev/null +++ b/profile2.pages.inc @@ -0,0 +1,28 @@ + $profile->label())); + $uri = $profile->uri(); + return confirm_form($form, $confirm_question, $uri['path']); +} + +/** + * Submit handler for deleting a profile. + */ +function profile2_delete_confirm_form_submit(array $form, array &$form_state) { + $uri = $form_state['profile']->user()->uri(); + $form_state['profile']->delete(); + drupal_set_message(t('Deleted %label.', array('%label' => $form_state['profile']->label()))); + $form_state['redirect'] = $uri['path']; +}