This is an issue derived from the meta issue #1770720: [META] Gradual changes to Field UI and #1786198: Make consistent regions in code for fields UI overview screens.

The changes abstract common behavior into base functionality for the manage fields and manage display screens.
It will also include some very minor changes which add consistency between the two screens.

Form UI functions

Basically this is a straight forward copy from the old form functions into a subclass of Drupal/field_ui/OverviewBase. There are no major changes inside the form api code.
Two alter hooks that were added in core later on (during re-roll) were added here too. For the rest everything is the same. The real refactoring to make it consistent will be done in #1786198: Make consistent regions in code for fields UI overview screens.
The list of changes:

  • previous drupal_get_form from router item is changed to a page callback that load the forms from a class method.
  • $view_mode became $this->view_mode
  • $bundle became $this->bundle
  • $entity_type became $this->entity_type
  • regions are defined in the Overview object
  • Added hook_field_formatter_settings_form_alter
  • Added hook_field_formatter_settings_summary_alter
  • validate and submit handlers are addressed through OOP methods (and added inside the form function)

Follow-ups

  • Moving the variables to $form_state['key'] instead of $form['#key'] is a follow up
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Stalski’s picture

The patch which includes the nid.

Status: Needs review » Needs work

The last submitted patch, drupal_field_ui_1792600.patch, failed testing.

Stalski’s picture

Status: Needs work » Needs review

Rerolled and some stuff was just uncommented, not removed.

Stalski’s picture

the patch :/

Status: Needs review » Needs work

The last submitted patch, drupal_field_ui_1792600_3.patch, failed testing.

swentel’s picture

Status: Needs work » Needs review
FileSize
48.59 KB

Let's see what the bot says now.

swentel’s picture

FileSize
94.21 KB

Oh my, took the patch wrong

Status: Needs review » Needs work

The last submitted patch, 1792600-7.patch, failed testing.

swentel’s picture

Status: Needs work » Needs review
FileSize
1.85 KB
95.31 KB

Fix last remaining tests.

Stalski’s picture

Status: Needs review » Reviewed & tested by the community

Nice job swentel. Tested it and all keeps working without any visual change. Tests pass

swentel’s picture

Status: Reviewed & tested by the community » Needs work

Hmm no, #1303412: 'Manage display' : Cannot drag in or out of 'Hidden' got in, so this needs to be removed from the patch.

Stalski’s picture

Yeah, just saw that, which is a good thing. I'l reroll the patch now

Stalski’s picture

Status: Needs work » Needs review
FileSize
96.11 KB

- reroll
- Additional change adding the invocation of drupal_alter so implementations of hook_field_formatter_settings_form_alter and hook_field_formatter_summary_form_alter work

All tests work.

Stalski’s picture

Doing some cleanups and rectifying documentation against http://drupal.org/node/1354#classes

Stalski’s picture

FileSize
95.29 KB

- Added and changed documentation suggested by the Doxygen and comment formatting conventions.
- Changed some lines suggested by swentel (too long comments, capitalized words to lowercase, added (optional) )

Stalski’s picture

FileSize
95.29 KB

2 other modificiations in commenting to make things more clear.

fubhy’s picture

All I could find were some code-style and readability issues. The concept and the code look fine in general.

+++ b/core/modules/field_ui/field_ui.admin.incundefined
@@ -299,429 +301,16 @@ function theme_field_ui_table($variables) {
+  $fieldOverview = new FieldUIFieldOverview($entity_type, $bundle);

Normally, we are using non-camel-case variables.

+++ b/core/modules/field_ui/field_ui.admin.incundefined
@@ -896,377 +339,18 @@ function field_ui_field_overview_form_submit($form, &$form_state) {
+  $displayOverview = new FieldUIDisplayOverview($entity_type, $bundle, $view_mode);

Same.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.phpundefined
@@ -0,0 +1,480 @@
+   * Implements Drupal\field_ui\FieldUIOverviewInterface::getRegions()

Missing "."... Should be "Implements Drupal\field_ui\FieldUIOverviewInterface::getRegions()." Same for all the following method docblocks.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.phpundefined
@@ -0,0 +1,480 @@
+

Empty line for no reason.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.phpundefined
@@ -0,0 +1,480 @@
+    // field_group), the 'format type' selects can trigger a series of changes in

Exceeds 80 characters.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.phpundefined
@@ -0,0 +1,480 @@
+      // Retrieve the stored instance settings to merge with the incoming values.

Exceeds 80 charaters.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIFieldOverview.phpundefined
@@ -0,0 +1,625 @@
+        // Place the 'translatable' property as an explicit value so that contrib

Exceeds 80 characters.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.phpundefined
@@ -0,0 +1,74 @@
+   *   (optional) The view mode for the entity which takes a string or "default".

Exceeds 80 characters.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.phpundefined
@@ -0,0 +1,80 @@
+   *   (optional) The view mode for the entity which takes a string or "default".

Exceeds 80 characters.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.phpundefined
@@ -0,0 +1,74 @@
+   * Implements Drupal\field_ui\FieldUIOverviewInterface::__construct()

Missing "." after Implements ... (Here and everywhere else too).

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.phpundefined
@@ -0,0 +1,74 @@
+   *   (optional) The view mode for the entity which takes a string or "default".

Comment too long :)

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.phpundefined
@@ -0,0 +1,80 @@
+   *   An renderable array.

"A renderable array"

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.phpundefined
@@ -0,0 +1,80 @@
+   *   (optional) The view mode for the entity which takes a string or "default".

Here too!

nils.destoop’s picture

Reviewed this, and everything seems ok. I think this can go to rtbc after the comments from fubhy are applied.

Stalski’s picture

FileSize
95.32 KB

Changes according to feedback from fubhy.

andypost’s picture

Patch size mostly caused by moving a big form code within files. I've done a manual testing - it works!
I think it RTBC

+++ b/core/modules/field_ui/field_ui.js
@@ -326,7 +326,9 @@ Drupal.fieldUIDisplayOverview.field.prototype = {
     var currentValue = this.$formatSelect.val();
     var value;
-    if (region === 'visible') {
+    // @TODO Check if this couldn't just be like
+    // if (region !== 'hidden') {
+    if (region === 'content') {
       if (currentValue === 'hidden') {

Better to use !== hidden (I've tested this change manually). If there could be more regions name... maybe this js could be re-used!

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.php
@@ -0,0 +1,75 @@
+  public function getRegionOptions() {
+    $options = array();
+    foreach ($this->getRegions() as $region => $data) {
+      $options[$region] = $data['title'];
+    }
+    return $options;

Patch allows to use a different region-set but there's a lot of hard-coded references to 'content' and 'hidden'. Maybe better to always have this "key-regions" by default?

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIFieldOverview.php
@@ -0,0 +1,623 @@
+  /**
+   * Validates the 're-use existing field' row of
+   * FieldUIFieldOverview::validateAddExisting().
+   *
+   * @see Drupal\field_ui\FieldUIOverviewInterface::validate()
+   */
+  private function validateAddExisting($form, &$form_state) {

This should be one-line, but let's leave it for follow-up with clean-up

Stalski’s picture

@andypost: thx for the in depth review.

1) !== hidden was a suggestion. Dunno if that's for this patch. It might be postponed to #1786198: Make consistent regions in code for fields UI overview screens where consistency and expandability is the topic.
2) content and hidden are still hardcoded in this patch. It might be "detected" in #1786198: Make consistent regions in code for fields UI overview screens to actually make it less hardcoded.
3) the two line comment was just changed into 2 lines since it exceeded the 80 chars. Is this not needed in this case?

nils.destoop’s picture

Status: Needs review » Reviewed & tested by the community

Reviewed and approved :)

Stalski’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
95.32 KB

Reroll against new head

Stalski’s picture

Status: Needs review » Reviewed & tested by the community

Sorry, did not mean to change the status. Patch was the same I just saw.

yched’s picture

Status: Reviewed & tested by the community » Needs work

Great work !
So as I said earlier, I generally +1 on the principle. I have a couple remarks on the implementation though - nothing serious.

- Aside from the code reorganisation, it's difficult to see the changes within the code that gets moved around (e.g. the actual content of FieldUIDisplayOverview::form() vs the former field_ui_display_overview_form()). Are there any, and if so, can you summarize them ?

- We don't need the FieldUI prefix in the class names. The namespace is specific enough.

- Too bad we still need to keep field_ui_display_overview_multistep_js() in the .module file
Have you checked whether field_ui_display_overview_multistep_submit() could work as a class method, though ?

+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -299,429 +301,16 @@ function theme_field_ui_table($variables) {
-function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle) {

field_ui_field_overview_form() and field_ui_display_overview_form() are not form callbacks anymore but regular page callbacks, that happen to return a rendered form. They should thus be renamed, to e.g. field_ui_field_overview(), field_ui_display_overview(), and their phpdoc be adjusted. See the phpdoc of entity_get_form() for an example.

When renaming, beware of code comments that still refer to the old form callbacks ("Form submission handler for buttons in field_ui_display_overview_form()", Handles multistep buttons in field_ui_display_overview_form()", "This function is used as a #region_callback in field_ui_field_overview_form()")

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.php
@@ -0,0 +1,480 @@
+   * Get the regions needed to create the overview form.

Not needed - 'implements' or 'overrides' is enough. Same applies to the other methods, unless there is something really specific to that given implementation you want to emphasize

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.php
@@ -0,0 +1,480 @@
+  /**
+   * Implements Drupal\field_ui\FieldUIOverviewInterface::form().
+   *
+   * Create a renderable form.
+   */
+  public function form($form, &$form_state) {

Lacks type hinting in the signature (core type hints 'array' for arrays and class name for objects) and a proper docblock with @param and @return statements - same applies to other methods.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.php
@@ -0,0 +1,480 @@
+    // Add the validate and submit behavior.
+    $form['#validate'] = array(array($this, 'validate'));
+    $form['#submit'] = array(array($this, 'submit'));

Minor, but looks like this could be moved to FieldUIOverviewBase::form() ?

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIDisplayOverview.php
@@ -0,0 +1,480 @@
+    $form += array(
+      '#entity_type' => $this->entity_type,
+      '#bundle' => $this->bundle,
+      '#view_mode' => $this->view_mode,
+      '#fields' => array_keys($instances),
+      '#extra' => array_keys($extra_fields),
+    );

Let's move those to $form_state (probbly best in a followup)

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIFieldOverview.php
@@ -0,0 +1,623 @@
+        'message' => t('No unused fields.'),

Not clear to me when this message would appear, but the wording seems weird.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIFieldOverview.php
@@ -0,0 +1,623 @@
+  private function validateAddNew($form, &$form_state) {

Private methods are frowned upon, needlessly restrictive - 'protected' is sufficient. Same applies to validateAddExisting()

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.php
@@ -0,0 +1,75 @@
+  protected $entity_type = '';
+  protected $bundle = '';
+  protected $view_mode = '';
+  protected $adminPath = NULL;

The properties should have a phpdoc block with a sentence and a @var statement.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.php
@@ -0,0 +1,75 @@
+   * Get all regions as options.

Should be 3rd person : "Gets" - I didn't closely check the rest of the methods on this aspect.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.php
@@ -0,0 +1,75 @@
+    if (!isset($this->adminPath)) {
+      $this->adminPath = _field_ui_bundle_admin_path($this->entity_type, $this->bundle);
+    }

"statically" caching seems overkill. I'm not sure we need a property for that, just proxy to the function.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewBase.php
@@ -0,0 +1,75 @@
+  public function validate($form, &$form_state) {
+    // Nothing to do.
+  }

Seems not too consistent to define an empty validate() here and not an empty submit().
I get that FieldUIDisplayOverview has no validation, but I'd rather see none in the Base and have both subclasses add explicit methods (explixitely empty for FieldUIDisplayOverview)

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.php
@@ -0,0 +1,81 @@
+ * Defines a common interface for field overview UI's.

Language - "for Field UI overview pages" ?

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.php
@@ -0,0 +1,81 @@
+interface FieldUIOverviewInterface {

No strong opinion here, but I don't really get why we need an interface. A base class, yes, but an interface ? Do we expect to have generic code that works on whatever FieldUIOverviewInterface object ?

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.php
@@ -0,0 +1,81 @@
+  public function __construct($entity_type, $bundle, $view_mode = 'default');

We usually try to leave _construct() method out of interfaces. Different child classes might need different construction logic / params.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUIOverviewInterface.php
@@ -0,0 +1,81 @@
+  public function getRegions();
+}

Misses an empty line after the last method - same applies to the actual class files

29 days to next Drupal core point release.

Stalski’s picture

Status: Needs work » Needs review
FileSize
147.75 KB

thx a lot yched! I will refactor this today and rerolled it.

Form UI functions

There is nothing that changed inside the form api code. I did add two alter hooks that were added in core later on (during re-roll). For the rest everything is the same. The real refactoring to make it consistent will be done in #1786198: Make consistent regions in code for fields UI overview screens. So the only things that changed summarized:

  • $view_mode became $this->view_mode
  • $bundle became $this->bundle
  • $entity_type became $this->entity_type
  • regions are defined in the Overview object
  • Added hook_field_formatter_settings_form_alter
  • Added hook_field_formatter_settings_summary_alter
  • validate and submit handlers are addressed through OOP methods (and added inside the form function)

Refactoring

  • Removed FieldUI prefix in the class name
  • I had already checked "field_ui_display_overview_multistep_js" function. Currently ajax can't deal with object methods as callback. I created an issue to cover this: see #1802072: Ajax callbacks should be callbacks defined as function or class method. That refactoring can be done after that patch is green and accepted.
  • Renamed field_ui_field_overview_form() and field_ui_display_overview_form() + added comments according the phpdoc of entity_get_form
  • Rechecked and changed comments (E.g. @see) so they refer to the new methods instead of functions
  • Removed unnecessary comments with redundant descriptions
  • Added type hinting and proper docblock (I did just remove some of them as I've seen examples in core where @params and @return is not repeated in the implementing or overriding method. I changed it because it seems better imo.
  • Moved the submit and validate registration of the form to OverviewBase.
  • "no unused fields" to "no fields". This message is not visible in core but it might by some contrib, that does not need to do dirty hacks to override this default message.
  • Changed private methods to protected
  • Added @var phpdoc on members of OverviewBase
  • checked and changed all the start words of docs in 3rd person
  • Totally agree on the empty validate() function. Changed this so subclasses need to explicitly implement them
  • Moved construct to the base class only. It's still an abstract base class though.
  • Added empty lines after the last method

Did not change

  • The statically cache on adminPath I would rather keep. It's just the opposite, isn't that faster then rereading the whole "field_info_bundles" and "entity_get_info" all the time? In fact, before it was a variable used in the complete form api code. So I tried to just do the same thing as before, which is a property.
  • No strong opinion here, but I don't really get why we need an interface. A base class, yes, but an interface ? Do we expect to have generic code that works on whatever FieldUIOverviewInterface object ?

    Well, that's in fact especially for the getRegions method. Should the interface be removed?

Follow-ups

  • Moving the variables to $form_state['key'] instead of $form['#key'] is indeed for a follow up

Status: Needs review » Needs work

The last submitted patch, 1792600-26.patch, failed testing.

yched’s picture

Thanks for the changes, @Stalski - not easy for me to review code now, so I'll leave it to others to drive this home.

re: adminPath()

In fact, before it was a variable used in the complete form api code. So I tried to just do the same thing as before, which is a property.

Yeah. Well then, why don't we just populate it in the construct and be done with it ?

re: interface :

that's in fact especially for the getRegions method.

Then maybe just put getRegions() in the base class as an abstract method and ditch the interface ?

Stalski’s picture

Status: Needs work » Needs review
FileSize
97.88 KB

- Yeah, just loading it in the construct is better actually. Changed that
- Ditched the interface and changed all comments like "overrides" and "implements" and the interface descriptions are moved to the base class.

Also fixed the errors for the previous patch:
- typecasting problem
- view mode was not passed along anymore, fixed that as well

Stalski’s picture

#29: 1792600-29.patch queued for re-testing.

swentel’s picture

This looks good to me. The question is, should we wait for #1802072: Ajax callbacks should be callbacks defined as function or class method to get in first, or go ahead ? Could be done in a follow up of course. If anyone else can review the last one and think it's good, rtbc it.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

@Stalski please update issue summary from your last comments, and I think it's ready.

Actually there's big changes depends on this issue so let's get this commited and focus on
#1770720: [META] Gradual changes to Field UI
#1786198: Make consistent regions in code for fields UI overview screens

tim.plunkett’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/field_ui/field_ui.admin.incundefined
@@ -290,438 +292,32 @@ function theme_field_ui_table($variables) {
+  $field_overview = new FieldOverview($entity_type, $bundle);

@@ -743,532 +339,38 @@ function _field_ui_field_name_exists($value) {
+  $display_overview = new DisplayOverview($entity_type, $bundle, $view_mode);

If these are hardcoded, they cannot be subclassed.

Stalski’s picture

Why is this needed? Form altering is what people did in D7 and they still can do that.

Follow ups will refactor this even more, and one of the things could be to make it extensible as well. The point is you could run your own callbacks from the menu hook, creating your own Overview implementation in a field_ui contrib module for instance.

So my vote goes to postponing this to a follow up as extra feature. Besides most examples who will implement the field_ui will not be able to use extensions. One way would be the decorator way. (field_group, DS, ...)

Stalski’s picture

Status: Needs review » Reviewed & tested by the community

Thought about this some more. Just setting this back to RTBC since this patch intends to get in soon without adding new functionality. That's the main reason why this issue was created from #1770720: [META] Gradual changes to Field UI and #1786198: Make consistent regions in code for fields UI overview screens

tim.plunkett’s picture

Thanks, I feel better already :)
+1 for RTBC

Stalski’s picture

Now that #1802072: Ajax callbacks should be callbacks defined as function or class method is in, I wil take this even futher as yched suggested and take the multistep js for configurations to the FieldsOverview object, or should this be in a follow-up and leave this RTBC? If so, then we will take this further refactoring in #1786198: Make consistent regions in code for fields UI overview screens.

thoughts?

fubhy’s picture

Assigned: Stalski » fubhy

Doesn't apply anymore anyways. Doing a re-roll!

fubhy’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
102.2 KB
97.68 KB

Something went wrong when #1802072: Ajax callbacks should be callbacks defined as function or class method should've been commited/pushed. Anyways. I re-rolled this one (didn't apply anymore). And created two patches for now (one, that incorporates the Ajax method callback patch for testing and one that doesn't [which is going to fail]).

fubhy’s picture

Whoops, accidentally I killed the changes to operations introduced by #1480854: Convert operation links to '#type' => 'operations'. Re-adding those in this patch and also removing a few lines of stale (unused vars) code that I found while doing so.

fubhy’s picture

FileSize
97.38 KB

Too impatient.

fubhy’s picture

So the fact that the patch in #41 passes the tests maybe proofs that we need more field ui tests. It shouldn't pass considering that it uses the new ajax OO method callback from #1802072: Ajax callbacks should be callbacks defined as function or class method which hasn't been pushed yet.

andypost’s picture

+++ b/core/modules/field_ui/field_ui.admin.incundefined
@@ -290,437 +292,33 @@ function theme_field_ui_table($variables) {
 /**
- * Form constructor for the 'Manage fields' form of a bundle.
- *
+ * Returns the built and processed 'Manage fields' form of a bundle.
  * The resulting form allows fields and pseudo-fields to be re-ordered.

@@ -742,532 +340,38 @@ function _field_ui_field_name_exists($value) {
 /**
- * Validates the 're-use existing field' row of field_ui_field_overview_form().
+ * Returns the built and processed 'Manage display' form of a bundle.
+ * The resulting form allows fields and pseudo-fields to be re-ordered.

+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.phpundefined
@@ -0,0 +1,642 @@
+  /**
+   * Validates the 're-use existing field' row of
+   * FieldOverview::validateAddExisting().
+   *

Please format this as one-line summary according http://drupal.org/node/1354#functions

fubhy’s picture

FileSize
101.33 KB

Another re-roll due to the recently pushed field formatter plugin-ification patch. Also incorporates the changes suggested by @andypost. The #ajax method callback patch is in now as well and also incorporated in this re-roll.

Let this be the last re-roll please :).

Stalski’s picture

Status: Needs review » Reviewed & tested by the community

Thx fubhy. It looks good imo.

catch’s picture

Status: Reviewed & tested by the community » Fixed

OK this has been RTBC for a while and was just stuck in re-roll hell.

I reviewed the patch, and while I'm not entirely comforable with the form callback as class model one-offs we're introducing for entities, it's probably as close as we can get for re-using that code in Drupal 8, so committed/pushed to 8.x. Hopefully this will unblock some more work.

fubhy’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

now it's RTBC, we can add the actual work done here