reverted:
--- b/lib/Drupal/profile2/Profile.php
+++ /dev/null
@@ -1,158 +0,0 @@
-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_get_types($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, 'profile2');
- }
-
- /**
- * Returns the user owning this profile.
- */
- public function user() {
- return user_load($this->uid);
- }
-
- /**
- * Sets a new user owning this profile.
- *
- * @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
- */
- public function type() {
- return profile2_get_types($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.
- */
- 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 buildContent($view_mode = 'full', $langcode = NULL) {
- $content = array();
- // Assume newly create objects are still empty.
- if (!empty($this->is_new)) {
- $content['empty']['#markup'] = '' . t('There is no profile data yet.') . '';
- }
- return entity_get_controller($this->entityType)->buildContent($this, $view_mode, $langcode, $content);
- }
-
- public function save() {
- // Care about setting created and changed values. But do not automatically
- // set a created values for already existing profiles.
- if (empty($this->created) && (!empty($this->is_new) || !$this->pid)) {
- $this->created = REQUEST_TIME;
- }
- $this->changed = REQUEST_TIME;
-
- parent::save();
- // Update the static cache from profile2_load_by_user().
- $cache = &drupal_static('profile2_load_by_user', array());
- if (isset($cache[$this->uid])) {
- $cache[$this->uid][$this->type] = $this->pid;
- }
- }
-}
reverted:
--- b/lib/Drupal/profile2/ProfileType.php
+++ /dev/null
@@ -1,60 +0,0 @@
-$property;
- }
-}
diff -u b/profile2.admin.inc b/profile2.admin.inc
--- b/profile2.admin.inc
+++ b/profile2.admin.inc
@@ -102,25 +102,67 @@
/**
- * Form constructor to delete a ProfileType object.
- *
- * @param Drupal\profile2\ProfileType $profile_type
- * The ProfileType object to delete.
+ * Form constructor to import a ProfileType object.
*/
-function profile2_type_delete_form($form, &$form_state, ProfileType $profile_type) {
- $form_state['profile_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'
+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 submission handler for profile_type_delete_form().
+ * 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_delete_form_submit($form, &$form_state) {
- $form_state['profile_type']->delete();
- $form_state['redirect'] = 'admin/structure/profiles';
+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 -u b/profile2.module b/profile2.module
--- b/profile2.module
+++ b/profile2.module
@@ -22,10 +22,10 @@
'bundle' => 'type',
'label' => 'label',
),
+ 'bundles' => array(),
'bundle keys' => array(
'bundle' => 'type',
),
- 'bundles' => array(),
'view modes' => array(
'account' => array(
'label' => t('User account'),
@@ -36,6 +36,24 @@
),
);
+ // 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,
+ 'admin' => array(
+ 'path' => 'admin/structure/profiles/manage/%profile2_type',
+ 'real path' => 'admin/structure/profiles/manage/' . $type,
+ 'bundle argument' => 4,
+ 'access arguments' => array('administer profiles'),
+ ),
+ );
+ }
+
// Support entity cache module.
if (module_exists('entitycache')) {
$return['profile2']['field cache'] = FALSE;
@@ -69,7 +87,7 @@
* @param Drupal\profile2\Profile $profile
* A Profile entity.
*/
-function profile2_profile_uri(Profile $profile) {
+function profile2_profile_uri(Drupal\profile2\Profile $profile) {
return array(
'path' => 'admin/structure/profiles',
);
@@ -81,7 +99,7 @@
* @param Drupal\profile2\ProfileType $profile_type
* A ProfileType entity.
*/
-function profile2_profile_type_uri(ProfileType $profile) {
+function profile2_profile_type_uri(Drupal\profile2\ProfileType $profile_type) {
return array(
'path' => 'admin/structure/profiles/manage',
);
@@ -94,6 +112,7 @@
$items = array();
$items['admin/structure/profiles'] = array(
'title' => 'Profile types',
+ 'description' => 'Manage profiles, including fields.',
'page callback' => 'profile2_type_list_page',
'access callback' => TRUE,
);
@@ -108,6 +127,14 @@
'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',
@@ -121,13 +148,21 @@
'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',
- 'type' => MENU_LOCAL_ACTION
);
$items['admin/structure/profiles/manage/%profile2_type/clone'] = array(
'title' => 'Clone profile type',
@@ -136,6 +171,13 @@
'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;
}
@@ -145,7 +187,7 @@
*/
function profile2_type_list_page() {
$rows = array();
- foreach (entity_load_multiple('profile2_type', FALSE) as $profile) {
+ foreach (entity_load_multiple('profile2_type') as $profile) {
$uri = $profile->uri();
$row = array();
$row[] = $profile->label();
@@ -255,10 +297,12 @@
* Depending whether $type isset, an array of profile types or a single one.
*/
function profile2_get_types($type_name = NULL) {
- $types = entity_load_multiple('profile2_type');
- foreach ($types as $key => $type) {
- if ($type->get('type') != $type_name) {
- unset($types[$key]);
+ $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;
@@ -686,6 +730,201 @@
}
/**
+ * The class used for profile entities.
+ */
+class Profile extends Entity {
+
+ /**
+ * The profile id.
+ *
+ * @var integer
+ */
+ public $pid;
+
+ /**
+ * The name of the profile type.
+ *
+ * @var string
+ */
+ public $type;
+
+ /**
+ * The profile label.
+ *
+ * @var string
+ */
+ public $label;
+
+ /**
+ * The user id of the profile owner.
+ *
+ * @var integer
+ */
+ public $uid;
+
+ /**
+ * The Unix timestamp when the profile was created.
+ *
+ * @var integer
+ */
+ public $created;
+
+ /**
+ * The Unix timestamp when the profile was most recently saved.
+ *
+ * @var integer
+ */
+ public $changed;
+
+
+ public function __construct($values = array()) {
+ 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_get_types($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, 'profile2');
+ }
+
+ /**
+ * Returns the user owning this profile.
+ */
+ public function user() {
+ return user_load($this->uid);
+ }
+
+ /**
+ * Sets a new user owning this profile.
+ *
+ * @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
+ */
+ public function type() {
+ return profile2_get_types($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.
+ */
+ 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 buildContent($view_mode = 'full', $langcode = NULL) {
+ $content = array();
+ // Assume newly create objects are still empty.
+ if (!empty($this->is_new)) {
+ $content['empty']['#markup'] = '' . t('There is no profile data yet.') . '';
+ }
+ return entity_get_controller($this->entityType)->buildContent($this, $view_mode, $langcode, $content);
+ }
+
+ public function save() {
+ // Care about setting created and changed values. But do not automatically
+ // set a created values for already existing profiles.
+ if (empty($this->created) && (!empty($this->is_new) || !$this->pid)) {
+ $this->created = REQUEST_TIME;
+ }
+ $this->changed = REQUEST_TIME;
+
+ parent::save();
+ // Update the static cache from profile2_load_by_user().
+ $cache = &drupal_static('profile2_load_by_user', array());
+ if (isset($cache[$this->uid])) {
+ $cache[$this->uid][$this->type] = $this->pid;
+ }
+ }
+}
+
+/**
+ * Use a separate class for profile types so we can specify some defaults
+ * modules may alter.
+ */
+class ProfileType extends Entity {
+
+ /**
+ * Whether the profile type appears in the user categories.
+ */
+ public $userCategory = TRUE;
+
+ /**
+ * Whether the profile is displayed on the user account page.
+ */
+ public $userView = TRUE;
+
+ public $type;
+ public $label;
+ public $weight = 0;
+
+ public function __construct($values = array()) {
+ parent::__construct($values, 'profile2_type');
+ }
+
+ /**
+ * 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.
+ */
+ public function getTranslation($property, $langcode = NULL) {
+ if (module_exists('profile2_i18n')) {
+ return parent::getTranslation($property, $langcode);
+ }
+ return $this->$property;
+ }
+}
+
+/**
* View a profile.
*
* @see Profile::view()
only in patch2:
unchanged:
--- 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 {
}
}
}
-
only in patch2:
unchanged:
--- 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;
}
/**
only in patch2:
unchanged:
--- 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'),