API page: https://api.drupal.org/api/drupal/core!modules!views!src!ViewsData.php/f...

Enter a descriptive title (above) relating to protected function ViewsData::getData, then describe the problem you have found:

Ummm... So I'm looking at the function bodies for ViewsData::get() and getData().

When they're storing data in the cache they do this:

    $this->cacheSet($this->baseCid, $data);

    return $data;

When they're getting data from the cache, they do this:

 if ($data = $this->cacheGet($this->baseCid)) {
    return $data->data;
  }

This looks wrong to me. Shouldn't it just be return $data? What is this ->data in the return?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

larowlan’s picture

Yeah cache get returns a db row. There's an issue floating about to make it a real object.

jhodgdon’s picture

Title: Do ViewsData::getData()/get() actually work with the cache? » CacheBackendInterface->get() docs missing crucial information
Component: views.module » documentation
Priority: Normal » Major
Issue tags: +Novice

Wow. The cache docs are terrible... the ->get() method doesn't even tell me this, and the D8 section on drupal.org is really lame:
https://drupal.org/node/1884796

Also see
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Cache!CacheBacken...
which really really really needs to say that to get the data you put into the cache back out, you need to get ->data().

I think this is a major oversight in the documentation that really needs to be fixed. Should be a good Novice issue.

What needs to be done:

In the @return section of CacheBackendInterface::get(), document that what is returned is a stdObject database row object, and that your data is in the ->data property of it.

ehegedus’s picture

Assigned: Unassigned » ehegedus
ehegedus’s picture

Status: Active » Needs review
FileSize
1.75 KB

I think the "cache item" naming is more appropriate, as the implementing classes alter (prepare) the returned row, so it won't be a simple database row object most of the time.

\Drupal\Core\Cache\MemoryBackend::prepareItem()
\Drupal\Core\Cache\DatabaseBackend::prepareItem()

jhodgdon’s picture

Status: Needs review » Needs work

This still doesn't tell me that to get back out the data that I placed in the cache, if I save the return value of ->get() in $cache_data, I have to do $cache_data->data. Hopefully that is true for all of the different cache backend classes, because I assume/hope that the user of the cache would not need to know the details of which back end is being used, in order to use the cache (which would completely nullify the idea of having a unified cache interface).

Also, shouldn't all of those other classes' ->get() methods just be using @inheritdoc instead of reproducing the entire ->get() docs?

jhodgdon’s picture

So I looked into this in more depth.

DatabaseBackEnd returns an object with the following properties:
- data - the cached data
- cid, created, expire, serialized, checksum_invalidations, checksum_deletions [database fields]
- tags [array of the tags]

MemoryBackend (and derived classes like MemoryCountBackend) returns an object with the following properties:
cid, data, created, expire, tags

NullBackend always returns FALSE (the others return FALSE if the cache is expired, nonexistent, etc.).

So, I think we should document the return value of the get() methods as either being:
- FALSE if there is no valid cached data
- An object with properties: cid, data, created, expire, tags [put these in a list and document what each one is].

And I also think all of the individual ->get() methods should use @inheritdoc to inherit the interface docs unless they have something specifically different to say. And I don't think they do. In fact, a few of them just say "Overrides ..." instead of even using @inheritdoc.

For details of how to do @inheritdoc, see:
https://drupal.org/node/1354#inheritdoc

ehegedus’s picture

Status: Needs work » Needs review

I searched, but couldn't find the a reference to the idea I read about the useage of dummy like class/interface for some particular return types. By dummy I mean we would not use (e.g. implement, extend) them in "real" cases and the only purpose they have is to store the documentation (instead of in the function/method directly). Do you have any existing procedure for this, or you think it may be an overhead?

jhodgdon’s picture

Status: Needs review » Needs work

I am not sure exactly what you mean in #7.... An interface should fully document the methods on the interface, including what their parameters and return values are. This is not a "dummy", but rather a "contract" that classes agree to follow when they implement the interface. A class that implements the interface can then use @inheritdoc instead of re-documenting the method. See https://drupal.org/node/1354#inheritdoc for details on how to use inheritdoc. Does that answer your question?

(As a side note, please do not change the status of an issue to "needs review" unless you have a new patch that needs reviewing. There's a link explaining what the priority/status values mean, under the priority/status fields. Thanks!)

ehegedus’s picture

The @inheritdoc part is clear.

Okay, so I meant something like defining a new dummy class, which we are not inteded to instantiate (abstract then?). In our case it would have only some properties (the database fields) with documentation, then the CacheBackendInterface::get() would return this data type instead of specifying any additional detail.

abstract class DummyCacheItem {
  /**
   * The data cached using the ->set() method
   * 
   * @var mixed
   */
  $data;

  ...
}

Then the ->get() method would contain only

* ...
* @return DummyCacheItem
* ...

My question is where should this class definition reside?
It worths the effort? Like it's a benefit to extend it in another dummy class and add there additional property documentation (e.g. additional properties added within a prepareItem() method) then return it instead of the parent data type?

I meant this whole thing as a generic question as this solution may apply in other parts also and I'm just wondering if it would clarify the return data type structure or not?

P.S.
Ideas and patches couldn't be mixed in the issue? :-\

Needs Review ["CNR"]
...
Note that if a patch is not required in order to complete the idea described in the issue, then it is the idea itself that needs review.

jhodgdon’s picture

No. I don't think so.... not here, anyway. This "Major" issue is about the documentation missing crucial information about what the code is actually currently doing. If you would like to propose different ideas about how the Cache API should work, please open a new issue (not in the Documentation component) to discuss (and in that case, you can set the status to "needs review" to discuss ideas -- but on this issue, which already had a patch that was marked "needs work", please do not use "needs review" unless you are adding a new patch. People subscribed to the issue will notice already if you ask a question.)

So. On this issue, all we want to do is document the return value of the get() methods as either being:
- FALSE if there is no valid cached data
- An object with properties: cid, data, created, expire, tags [put these in a list and document what each one is].

This should be done on the interface, because all implementations of this interface need to have the same return value structure. And all methods that override ->get() on other classes should also be changed to use @inheritdoc.

Thanks!

ehegedus’s picture

Status: Needs work » Needs review
FileSize
4.94 KB

Thank you for the guidance!

eojthebrave’s picture

Status: Needs review » Needs work

Path applies cleanly for me. And the content looks correct and reads easily. Thanks!

+   *     represents a node, both the node ID and the author's user ID might be
+   *     passed in as tags.
+   *     For example array('node' => array(123), 'user' => array(92)).
    *
    * @see \Drupal\Core\Cache\CacheBackendInterface::getMultiple()

Super nit-picky, but I think we shouldn't break the last 2 lines like you've done here. But instead, continue the 2nd to last line with ". For example ..." and break on "array ...". As is the formatting just seems off. Thoughts?

ehegedus’s picture

Or maybe...?

+   *     represents a node, both the node ID and the author's user ID might be
+   *     passed in as tags. For example
+   *     @code
+   *     array('node' => array(123), 'user' => array(92)).
+   *     @endcode
     *
     * @see \Drupal\Core\Cache\CacheBackendInterface::getMultiple()
jhodgdon’s picture

Yes to #13. Actually, given the context, I'd suggest this:

   *     trigger cache invalidation when updated. For example, if a cached item
   *     represents a node, both the node ID and the author's user ID might be
   *     passed in as tags:
   *     @code
   *     array('node' => array(123), 'user' => array(92))
   *     @endcode

Other nitpicks:

a)

+   *   FALSE if there is no valid cache data; Otherwise a cache item object with

Otherwise should not be capitalized.

b)

+   *       after this time, i.e. it will not be returned unless $allow_invalid

The (sigh) correct punctuation for "i.e." would be: "... time; i.e., it will...". Or better yet, use the words "that is", because 90% of people don't understand the distinction between i.e. and e.g. and will be confused by this anyway. (The words "that is" need to be punctuated the same way.)

c)

+   *     trigger cache invalidation when updated. For example if a cached item

Comma after "For example".

d) Shouldn't DatabaseBackend::get() and MemoryBackend::get() also just use @inheritdoc? Otherwise we need the full docs about the return value in those methods, or a link to the interface method for full docs.

ehegedus’s picture

Status: Needs work » Needs review
FileSize
8.73 KB

In fact, I copied most of the docs from other methods, so the provided info stays consistent.
Corrected the set method's documentation too and added the @inheritdoc tags. I bet at d) you meant getMultiple(), but the same is true for other methods also (e.g., delete(), deleteMultiple()), which also need update, but in another issue?

jhodgdon’s picture

Status: Needs review » Needs work

OK, let's see if we can sort this out... And please in the future do not put the "do not test" suffix on patches. At a minimum, it sorts out whether the patch applies, and also makes sure there were no inadvertent PHP syntax problems.

So, back to basics.

a) We have CacheBackendInterface, and these extending classes:
BackendChain
DatabaseBackend
MemoryBackend
MemoryCounterBackend
NullBackend

b) The interface has two methods, get() and getMultiple(), which both refer to "cache item objects", and both of them need to either define what that means, or refer to the other method where it's defined, in their @return section. That's the main subject of this issue, although it originally only applied to get() -- I think we should fix getMultiple() too now that you point it out.

c) This patch adds documentation to get(). I suggest rather than repeating the docs in getMultiple(), we should instead make the @return for getMultiple say something like "An array of cache item objects indexed by cache ID; see CacheBackendInterface::get() for documentation of these objects."

d) I am also thinking that in the tags section of the get() return value documentation, instead of fully explaining tags, we should just say "The tags array that was passed into CacheBackendInterface::set()", since that method already documents what the tags are. And I think the change in this patch to the $tags param in set() is good too, plus the other cleanups to the interface docs.

e) So now on to the classes. I think that it is fine if this patch expands in scope slightly to replace existing docs in class methods with @inheritdoc, for these methods, on all of the classes:

get, getMultiple, set, delete, deleteMultiple, deleteTags, deleteAll, invalidate, invalidateMultiple, invalidateTags, invalidateAll, garbageCollection, isEmpty

Thanks!

ehegedus’s picture

I was really busy in the past week. I try to do a re-roll today/tomorrow.

larowlan’s picture

jhodgdon’s picture

RE #18, do you think we should postpone this issue on that one? Is it likely to get done?

subhojit777’s picture

Issue summary: View changes
cilefen’s picture

Issue tags: -Novice

Removing the "Novice" tag because the direction is unclear at the moment.

ehegedus’s picture

Assigned: ehegedus » Unassigned

Saying hi from DrupalCon Barcelona, also leaving this task unassigned as the doc issues are not for me.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

catch’s picture

Priority: Major » Normal
Status: Needs work » Postponed
Issue tags: +Bug Smash Initiative

Postponing on #1748022: Make cache()->get() return a classed CacheItem object, if we can make the return a value object, we have a better spot to document everything.

The patch as it currently stands documents all the properties of the cache object as returned from the database cache, but nothing enforces this. $cached->data has to be there since everything accesses that and you'll get fatal errors if it's not. But the rest aren't guaranteed to be there at all, so it could be more misleading than the current minimal docs.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.