Problem/Motivation

The member variables of Flag::types and Flag::entity_type are currently public. There are no accessors for either variable. This breaks the isolation that is supposed to be provided by FlagInterface.

Proposed resolution

Change Flag::types and Flag::entity_type to protected. Create an getter and setter in FlagInterface.

Remaining tasks

Create patch.

User interface changes

None.

API changes

The target variables will only be accessable via accessor methods.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

socketwench’s picture

Status: Active » Needs review
FileSize
5.79 KB

Turns out there's already a getFlaggableEntityType(), so now there's a getFlaggableBundle() too.

Status: Needs review » Needs work

The last submitted patch, 1: 2446311.1.protectFlagVars.patch, failed testing.

joachim’s picture

+++ b/src/FlagInterface.php
@@ -56,6 +56,14 @@ interface FlagInterface extends ConfigEntityInterface, EntityWithPluginCollectio
+   * @return array|null

Shouldn't this always be returning an array, possibly empty? It's certainly better DX to not have to is_array() what you get back from this.

socketwench’s picture

Yes, that would make more sense now that I'm awake enough to comprehend it... >_<

socketwench’s picture

Status: Needs work » Needs review
FileSize
5.79 KB

Status: Needs review » Needs work

The last submitted patch, 5: 2446311.5.protectFlagVars.patch, failed testing.

socketwench’s picture

Status: Needs work » Needs review
FileSize
5.79 KB

Status: Needs review » Needs work

The last submitted patch, 7: 2446311.6.protectFlagVars.patch, failed testing.

martin107’s picture

Status: Needs work » Needs review

I am retesting, locally it works for me...

martin107’s picture

Status: Needs review » Reviewed & tested by the community

This makes sense to me.

As for the "Do we return an empty array or null" thing

That opens up a schism between developers that is never going to be settled.

Me: I put the tea in before the milk ... any thing else is just crazy :)

Pragmatically this should go in as locking down the interface is the more important concern.

Berdir’s picture

  1. +++ b/flag.module
    @@ -376,7 +376,7 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) {
           ->condition('nid', array_keys($entity_ids), 'IN')
    -      ->condition('type', $flag->types, 'IN')
    +      ->condition('type', $flag->getFlaggableBundles(), 'IN')
           ->execute();
    

    No worse than before, but this will fail if no bundles are checked, it will generate and invalid query or throw an exception, I'm not quite sure what.

    Then again, I think I've seen a issue somewhere that multiple access check is currently dead code anyway..

    With a method, what you *could* do is check for empty and then return all bundles of that entity type...

  2. +++ b/src/Form/FlagFormBase.php
    @@ -138,7 +138,7 @@ abstract class FlagFormBase extends EntityForm {
           '#options' => $entity_bundles,
    -      '#default_value' => $flag->types,
    +      '#default_value' => $flag->getFlaggableBundles(),
    

    Then you somehow need to check for that here, however, e.g. with a separate method that returns true/false.

martin107’s picture

Status: Reviewed & tested by the community » Needs review
Related issues: +#2469579: Refine handling of FlaggableBundles.
FileSize
5.85 KB
421 bytes

As you say no worse than before....

My proposal, for now, is a sticking plaster - I have just copied the warning that the Flag:type annotation provided into the FlagInterface return type where in the new scheme of things I would expect to see it.

   /**
    * Return the bundles of the flaggable that may be flagged.
    *
    * @return array
    *  An array containing the flaggable bundles.
+ *  A empty array to indicate all types apply.
    */
   public function getFlaggableBundles(); 

Step 2 file another issue to add the new FlagInterface methods to cover the concerns that you raise.

N-people will have N different ways of dealing with this ..and naming things is hard so I will start the ball rolling...

 /**
   *
   * @reutrn bool
   * TRUE If s this flag applies to all types.
   * FALSE if the flag applied to specific set of bundles.
   *
   * @see FlagInterface::getFlaggableBundles()
   */
  FlagInterface::appliesToAllTypes() 

I think this could be used to fix all cases.

socketwench’s picture

Then again, I think I've seen a issue somewhere that multiple access check is currently dead code anyway..

Yep. FlagService doesn't currently depend on ModuleHandlerInterface, so we're not even calling any hooks yet. More on that here: https://www.drupal.org/node/2467915#comment-9813823

+++ b/flag.module
@@ -127,9 +127,9 @@ function flag_entity_extra_field_info() {
+    foreach ($flag->getFlaggableBundles() as $bundle_name) {

If getFlaggAbleBundles() returns an empty array here, we won't get any extra psudofields.

socketwench’s picture

FileSize
580 bytes
joachim’s picture

  1. +++ b/flag.module
    @@ -127,9 +127,14 @@ function flag_entity_extra_field_info() {
    +    $flaggable_bundles = $flag->getFlaggableBundles();
    +    if (empty($flaggable_bundles)) {
    +      $flaggable_bundles = entity_get_bundles($flag->getFlaggableEntityType());
    +    }
    
    +++ b/src/Entity/Flag.php
    @@ -281,6 +281,13 @@ class Flag extends ConfigEntityBundleBase implements FlagInterface {
    +    return $this->types;
    

    Follow-up 1: consider ways to improve the DX for the 'applies to all' case. My preference would to hide the implementation, so the getFlaggableBundles() method internally handles giving you all the bundles if the stored value is empty. I do have a sneaking suspicion though that this could cause problems in some cases...

  2. +++ b/src/Entity/Flag.php
    @@ -96,7 +96,7 @@ class Flag extends ConfigEntityBundleBase implements FlagInterface {
    -  public $types = [];
    +  protected $types = [];
    

    Follow-up 2: let's change this confusing 'types' to 'bundles' or something like that. I thought I'd filed an issue ages ago about renaming various properties of the Flag entity, but I can only find #2457059: Rationalize fields fid and type on flagging entity .

Patch looks good to me: +1 to #14 and I'll commit if we're all happy with that.

joachim’s picture

Assigned: Unassigned » joachim
Status: Needs review » Needs work
  /**
   * Return the bundles of the flaggable that may be flagged.
   *
   * @return array
   *  An array containing the flaggable bundles.
   *  A empty array to indicate all types apply.
   */
  public function getFlaggableBundles();

On second thoughts, I think this needs to be done differently here, rather than in a follow-up. If this method were called getTypes(), then I would expect it to return the $flag->types property verbatim. However, getFlaggableBundles() I would expect to literally all the bundles that apply -- and do the legwork of converting an empty $types array into an array of all the entity type's bundles.

Working on this now.

joachim’s picture

Assigned: joachim » Unassigned
Status: Needs work » Needs review
FileSize
8 KB
6.44 KB

Status: Needs review » Needs work

The last submitted patch, 18: 2446311-18.flag_.protected-entity-types.patch, failed testing.

joachim’s picture

Assigned: Unassigned » joachim

> However, getFlaggableBundles() I would expect to literally all the bundles that apply -- and do the legwork of converting an empty $types array into an array of all the entity type's bundles

Duh, except as this patch stands, #2409835: [regression] subtypes option should not be required: leaving empty means it appliest to all isn't in yet. So that's immaterial, and adding that second method belongs in the other issue.

joachim’s picture

Status: Needs work » Needs review
FileSize
5.81 KB

Updated patch.

The difference between this and #14 is just a change in the method name getFlaggableEntityType() to getFlaggableEntityTypeId().

Status: Needs review » Needs work

The last submitted patch, 21: 2446311-21.flag_.protected-entity-types.patch, failed testing.

joachim’s picture

Oops. Our service tests were still accessing $types directly.

Status: Needs review » Needs work

The last submitted patch, 23: 2446311-23.flag_.protected-entity-types.patch, failed testing.

joachim’s picture

Wow. Everything's failing.

simplexml_import_dom(): Invalid Nodetype to importsimplexml_import_dom(Object) Drupal\simpletest\WebTestBase->parse() Drupal\simpletest\WebTestBase->drupalPostForm('admin/structure/flags/add', Array, 'Continue') Drupal\flag\Tests\FlagConfirmFormTest->doCreateFlag() Drupal\flag\Tests\FlagConfirmFormTest->testCreateConfirmFlag() Drupal\simpletest\TestBase->run(Array) simpletest_script_run_one_test('3', 'Drupal\flag\Tests\FlagConfirmFormTest') 

Has something changed in core in the last 12 hours maybe?

joachim’s picture

Status: Needs work » Needs review

Huh now it's passing. And the test result page doesn't say what timezone it's showing times in, so I don't know when that happened.

martin107’s picture

I have noticed lots of seemingly random test fails while working on other flag issues over say a period of about 2 weeks....
Lots has changed in Drupal core over that time ... and in particular the last few days as the sprints from DrrupalCon LA wind down.

Is you suspicion that is a design instability with flag, or maybe a test infrastructure thing?

joachim’s picture

I think it was a test infrastructure thing. The test report said it was failing, EVERYWHERE, all tests, with a message that seemed to be to do with the test's internal browser. And when I checked again an hour or so later, it was all green...

I'll maybe send it for a retest now, to be sure.

socketwench’s picture

Status: Needs review » Reviewed & tested by the community
joachim’s picture

Status: Reviewed & tested by the community » Fixed

Committed. Thanks everyone!

  • joachim committed 010e187 on 8.x-4.x authored by socketwench
    Issue #2446311 by socketwench, joachim, martin107: Changed Flag::types...

Status: Fixed » Closed (fixed)

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