diff --git a/lib/Drupal/profile2/Profile.php b/lib/Drupal/profile2/Profile.php index 8d3a19b..65aae69 100644 --- a/lib/Drupal/profile2/Profile.php +++ b/lib/Drupal/profile2/Profile.php @@ -57,7 +57,7 @@ class Profile extends Entity { public $changed; - public function __construct($values = array()) { + public function __construct(array $values = array(), $entity_type = 'profile2') { if (isset($values['user'])) { $this->setUser($values['user']); unset($values['user']); @@ -70,7 +70,7 @@ class Profile extends Entity { // have that as interim label. $values['label'] = $type->label; } - parent::__construct($values, 'profile2'); + parent::__construct($values, $entity_type); } /** @@ -156,4 +156,3 @@ class Profile extends Entity { } } } - diff --git a/lib/Drupal/profile2/ProfileType.php b/lib/Drupal/profile2/ProfileType.php index 41c7364..a11b761 100644 --- a/lib/Drupal/profile2/ProfileType.php +++ b/lib/Drupal/profile2/ProfileType.php @@ -29,8 +29,8 @@ class ProfileType extends Entity { public $label; public $weight = 0; - public function __construct($values = array()) { - parent::__construct($values, 'profile2_type'); + public function __construct(array $values = array(), $entity_type = 'profile2_type') { + parent::__construct($values, $entity_type); } /** @@ -38,9 +38,12 @@ class ProfileType extends Entity { * * Profile types provided in code are automatically treated as locked, as well * as any fixed profile type. + * + * @todo Remove method or make entity status available. */ public function isLocked() { - return isset($this->status) && empty($this->is_new) && (($this->status & ENTITY_IN_CODE) || ($this->status & ENTITY_FIXED)); + // At the moment there is not status available, so profile type can't be locked. + return false; } /** diff --git a/profile2.admin.inc b/profile2.admin.inc index f31ce59..62294d0 100644 --- a/profile2.admin.inc +++ b/profile2.admin.inc @@ -8,7 +8,11 @@ /** * Generates the profile type editing form. */ -function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { +function profile2_type_form($form, &$form_state, $profile_type = NULL, $op = 'edit') { + if (!isset($profile_type)) { + $profile_type = entity_create('profile2_type', array()); + } + $form_state['profile_type'] = $profile_type; if ($op == 'clone') { $profile_type->label .= ' (cloned)'; @@ -18,7 +22,7 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { $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, @@ -26,7 +30,7 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') { // Machine-readable type name. $form['type'] = array( '#type' => 'machine_name', - '#default_value' => isset($profile_type->type) ? $profile_type->type : '', + '#default_value' => $profile_type->get('type'), '#maxlength' => 32, '#disabled' => $profile_type->isLocked() && $op != 'clone', '#machine_name' => array( @@ -36,11 +40,12 @@ 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.'), ); + $data = unserialize($profile_type->get('data')); $form['data']['#tree'] = TRUE; $form['data']['registration'] = array( '#type' => 'checkbox', '#title' => t('Show during user account registration.'), - '#default_value' => !empty($profile_type->data['registration']), + '#default_value' => $data['registration'], ); $form['actions'] = array('#type' => 'actions'); @@ -66,9 +71,24 @@ 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['profile_type']; + + foreach ($form_state['values'] as $key => $value) { + $a .= $key.' '.$value; + $profile_type->set($key, $value); + } + $profile_type->save(); + + if (!empty($profile_type->original)) { + drupal_set_message(format_string('%label configuration has been updated.', array('%label' => $profile_type->label()))); + } + else { + drupal_set_message(format_string('%label configuration has been created.', array('%label' => $profile_type->label()))); + } + $form_state['redirect'] = 'admin/structure/profiles'; } @@ -76,5 +96,73 @@ 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['profile_type']->type . '/delete'; +} + +/** + * Form constructor to import a ProfileType object. + */ +function profile2_type_import_form($form, &$form_state) { + $form['import'] = array( + '#type' => 'textarea', + '#title' => t('Import'), + '#description' => t('Paste an exported %entity_type here.', array('%entity_type' => $this->entityInfo['label'])), + '#rows' => 20, + ); + $form['overwrite'] = array( + '#title' => t('Overwrite'), + '#type' => 'checkbox', + '#description' => t('If checked, any existing %entity with the same identifier will be replaced by the import.', array('%entity' => $this->entityInfo['label'])), + '#default_value' => FALSE, + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + return $form; +} + +/** + * Form submission handler for profile_type_import_form(). + * + * @todo Fill in import function (see ..) + */ + function profile2_type_import_form_submit($form, &$form_state) { +if ($entity = entity_import($this->entityType, $form_state['values']['import'])) { + // Store the successfully imported entity in $form_state. + $form_state[$this->entityType] = $entity; + if (!$form_state['values']['overwrite']) { + // Check for existing entities with the same identifier. + $id = entity_id($this->entityType, $entity); + $entities = entity_load($this->entityType, array($id)); + if (!empty($entities)) { + $label = entity_label($this->entityType, $entity); + $vars = array('%entity' => $this->entityInfo['label'], '%label' => $label); + form_set_error('import', t('Import of %entity %label failed, a %entity with the same machine name already exists. Check the overwrite option to replace it.', $vars)); + } + } + } + else { + form_set_error('import', t('Import failed.')); + } +} + +/** + * Form constructor to export a ProfileType object. + * + * @param Drupal\profile2\ProfileType $profile_type + * The ProfileType object to export. + * + * @todo Fill in export function (see ..) + */ +function profile2_type_export_form($form, &$form_state, ProfileType $profile_type) { + // generate $export + $form['export'] = array( + '#type' => 'textarea', + '#title' => t('Export'), + '#description' => t('For importing copy the content of the text area and paste it into the import page.'), + '#rows' => 25, + '#default_value' => $export, + ); + return $form; } diff --git a/profile2.install b/profile2.install index 762b1ff..1191479 100644 --- a/profile2.install +++ b/profile2.install @@ -12,6 +12,7 @@ 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', 'label' => t('Main profile'), diff --git a/profile2.module b/profile2.module index b13f6b3..c761086 100644 --- a/profile2.module +++ b/profile2.module @@ -12,18 +12,11 @@ function profile2_entity_info() { $return = array( 'profile2' => array( 'label' => t('Profile'), - 'plural label' => t('Profiles'), - 'description' => t('Profile2 user profiles.'), - 'entity class' => 'Profile', - 'controller class' => 'EntityAPIController', + 'entity class' => 'Drupal\profile2\Profile', + 'controller class' => 'Drupal\node\NodeStorageController', 'base table' => 'profile', + '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', @@ -33,11 +26,13 @@ function profile2_entity_info() { 'bundle keys' => array( 'bundle' => 'type', ), - 'label callback' => 'entity_class_label', - 'uri callback' => 'entity_class_uri', + 'view modes' => array( + 'account' => array( + 'label' => t('User account'), + 'custom settings' => FALSE, + ), + ), 'access callback' => 'profile2_access', - 'module' => 'profile2', - 'metadata controller class' => 'Drupal\profile2\MetadataController', ), ); @@ -67,14 +62,13 @@ function profile2_entity_info() { $return['profile2_type'] = array( 'label' => t('Profile type'), - 'plural label' => t('Profile types'), - 'description' => t('Profiles types of Profile2 user profiles.'), - 'entity class' => 'ProfileType', - 'controller class' => 'EntityAPIControllerExportable', + 'entity class' => 'Drupal\profile2\ProfileType', + 'controller class' => 'Drupal\entity\DatabaseStorageController', 'base table' => 'profile_type', 'fieldable' => FALSE, 'bundle of' => 'profile2', 'exportable' => TRUE, + 'uri callback' => 'profile2_profile_type_uri', 'entity keys' => array( 'id' => 'id', 'name' => 'type', @@ -82,17 +76,172 @@ function profile2_entity_info() { ), '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; } /** + * Entity uri callback. + * + * @param Drupal\profile2\Profile $profile + * A Profile entity. + */ +function profile2_profile_uri(Drupal\profile2\Profile $profile) { + return array( + 'path' => 'admin/structure/profiles', + ); +} + +/** + * Entity uri callback. + * + * @param Drupal\profile2\ProfileType $profile_type + * A ProfileType entity. + */ +function profile2_profile_type_uri(Drupal\profile2\ProfileType $profile_type) { + return array( + 'path' => 'admin/structure/profiles/manage', + ); +} + +/** + * Implements hook_menu. + */ +function profile2_menu() { + $items = array(); + $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' => 'Profile types', + '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/import'] = array( + 'title' => 'Import profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_import_form'), + 'access callback' => TRUE, + '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/fields'] = array( + 'title' => 'Manage profile fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('field_ui_field_overview_form', 'profile2', 4), + 'access callback' => TRUE, + 'file' => 'field_ui.admin.inc', + 'file path' => drupal_get_path('module', 'field_ui'), + 'type' => MENU_LOCAL_ACTION + ); + $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, + 'file' => 'profile2.admin.inc', + ); + $items['admin/structure/profiles/manage/%profile2_type/clone'] = array( + 'title' => 'Clone profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_form', 4, 'clone'), + 'access callback' => TRUE, + 'file' => 'profile2.admin.inc', + ); + $items['admin/structure/profiles/manage/%profile2_type/export'] = array( + 'title' => 'Clone profile type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('profile2_type_export_form', 4), + 'access callback' => TRUE, + 'file' => 'profile2.admin.inc', + ); + + return $items; +} + +/** + * Page callback; Lists available Profile objects. + */ +function profile2_type_list_page() { + $rows = array(); + foreach (entity_load_multiple('profile2_type') as $profile) { + $uri = $profile->uri(); + $row = array(); + $row[] = $profile->label(); + $row[] = '-'; + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('edit'), + '#href' => $uri['path'] . '/' . $profile->type, + '#options' => $uri['options'], + ); + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('manage fields'), + '#href' => $uri['path'] . '/' . $profile->type . '/fields', + '#options' => $uri['options'], + ); + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('manage display'), + '#href' => $uri['path'] . '/' . $profile->type . '/display', + '#options' => $uri['options'], + ); + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('clone'), + '#href' => $uri['path'] . '/' . $profile->type . '/clone', + '#options' => $uri['options'], + ); + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('delete'), + '#href' => $uri['path'] . '/' . $profile->type . '/delete', + '#options' => array_merge($uri['options'], array('query' => drupal_get_destination())), + ); + $row[]['data'] = array( + '#type' => 'link', + '#title' => t('export'), + '#href' => $uri['path'] . '/' . $profile->type . '/export', + '#options' => $uri['options'], + ); + $rows[] = $row; + } + $build = array( + '#theme' => 'table', + '#header' => array('Name', 'Status', array('data' => 'Operations', 'colspan' => 6)), + '#rows' => $rows, + '#empty' => format_string('No profile type defined. Add some', array( + '@add-url' => url('admin/structure/profiles/add'), + )), + ); + return $build; +} + +/** * Menu argument loader; Load a profile type by string. * * @param $type @@ -148,7 +297,14 @@ function profile2_permission() { * 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); + $types = entity_load_multiple('profile2_type', NULL, TRUE); + if (!is_null($type_name)) { + foreach ($types as $key => $type) { + if ($type->get('type') != $type_name) { + unset($types[$key]); + } + } + } return isset($type_name) ? reset($types) : $types; } @@ -307,19 +463,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) {