Issues

ZF-8749: Add tag/method mapping, feed and item levels, in Zend_Feed_Reader

Description

Creating an interface library between Zend_Feed_Reader (ZFR) and the in-house CMS which handles user configuration for outputting feeds in HTML (multiple feeds per page), I need to allow users to specify element names in the configuration file which should be extracted from feed and item levels for use in the output.

It would be preferable to let them choose from the generic getter method names created for ZFR (without the "get", for example "Authors" maps to "getAuthors()"), but this could be brittle if over time there are deletions/additions/renamings among feed and item level getter methods, within the ZFR classes. Besides, not all getters with "get" in their names map to XML elements; for instance "getDom" retrieves DOM stuff, not directly an element value/s.

As I love the generic getters that extract same elements across feed namespaces, I'd like guaranteed generic element names for cross-XML spec elements mapped to getter method names to be created in the feed object, perhaps as a property/ies that can be inspected and iterated. That way, ZFR getter methods could dynamically be called based on a list of generic element names set in the configuration.

The value of this to ZF is that ZFR presents an unretractable list of generic element names that can be added to but not subtracted from as an API feature, while allowing fluidity in how methods are structured within the ZFR classes. It might be a generalizable principle across other ZF components, as well, as it would increase backward-compatibility with ZF-based code should specs or code change.

In my opinion, Zend_Feed_Reader is a quantum leap forward -- just the right balance of versatility -- thank you!

Comments

Hi Stephen,

{quote}It would be preferable to let them choose from the generic getter method names created for ZFR (without the "get", for example "Authors" maps to "getAuthors()"), but this could be brittle if over time there are deletions/additions/renamings among feed and item level getter methods, within the ZFR classes. Besides, not all getters with "get" in their names map to XML elements; for instance "getDom" retrieves DOM stuff, not directly an element value/s.{quote}

The method names will remain static at least up to Zend Framework 2.0 (most likely beyond) - this is guaranteed to prevent backwards compatibility breaks. It is likely there will be some change with ZF 1.10, specifically addressing collections. For example, at present the method getLink() returns a link to the HTML resource (i.e. of the feed or entry). It will still do that by default, but may also accept optional parameters to collect a specific atom:link (based on relation and mimetype). Even here, with changes, the original method name and behaviour will remain unchanged. Also, with ZF 1.10, we now have close to 100% coverage of the RSS/Atom spec - meaning there are no additions to make other than for namespaced extensions.

{quote}As I love the generic getters that extract same elements across feed namespaces, I'd like guaranteed generic element names for cross-XML spec elements mapped to getter method names to be created in the feed object, perhaps as a property/ies that can be inspected and iterated. That way, ZFR getter methods could dynamically be called based on a list of generic element names set in the configuration.{quote}

Just so I understand you, you're suggesting a map of sort? Showing which element names map to which getter? The main problem here is that is no 1-1 relationship. For example, with RSS 2.0, getContent() could return a) content:encoded, b) description or even c) atom:content. What might be possible is a reverse lookup map. For example, looking up "content:encoded" would return "content" or "getContent" as the relevant getter. The reverse lookup would most likely return "content" (without the get, and first letter lowercased), the reason being this is the internal representating data key and the upcoming ArrayAccess make it available using something like $feed[0]['content']. Array like access has been a popular request over IRC.

It be worthwhile adding a short use case - just so I can see what kind of interface you're aiming for (and in case I got it wrong ;)).

{quote}In my opinion, Zend_Feed_Reader is a quantum leap forward - just the right balance of versatility - thank you!{quote}

While the base API is fairly fixed, we are still fine-tuning some of the access methods (arrays are popular), synchronising method names and parameters with Writer, and generally making it as intuitive as possible. Lots of work, but it's been fun to work on ;). Glad you're liking the near-end result!

Hi Brady,

bq. you're suggesting a map of sort? Showing which element names map to which getter? The main problem here is that is no 1-1 relationship. For example, with RSS 2.0, getContent() could return a) content:encoded, b) description or even c) atom:content. What might be possible is a reverse lookup map. For example, looking up "content:encoded" would return "content" or "getContent" as the relevant getter. The reverse lookup would most likely return "content" (without the get, and first letter lowercased), the reason being this is the internal representating data key and the upcoming ArrayAccess make it available using something like $feed[0]['content'].

1) This is probably a case of your (good) ideas outperforming my suggestion, which is very simplistic. Also, your statement about the guaranteed unchanging method names helps.

Still, I simply wanted to ask users to naively list in configuration which elements they want from feed and newsitem levels, using your method names for elements but without the prefix "get". For example, they could specify from the list {Authors, Content, DateCreated, DateModified, Description, Enclosure, Id, Links, Permalink, Title, CommentCount, CommentLink, CommentFeedLink, Categories, Source} one or more generic element names to fetch best-guess feed level values. Each of those list names would allow me simply to get the specified element by prepending "get" and calling the method by the name thus formed. My suggestion is to store a map of name => method like those in the list in the Feed level class so that my code knows how naively to request those generically named elements, without risking method name changes; that way the code could shift method names so long as the map was updated.

ZFR's valuable best-guess logarithm in your 3 content cases, for example, would be considered trustworthy enough, if they simply configured "Content" as the newsitem element they wanted, no matter that the feed is RSS, with the understanding that what they really want may not be in the feed.

I thought it would be simple to automate this by capturing PHP's get_class_methods('ZFR classname') together with string matching without the "get" prefix to validate which elements should be fetched, until I noticed that the ZFR Feed and Entry classes have other non-element mapping getter method names which would break that approach. Still, that idea would seem to suggest a simplified interface for consuming feeds by offering simplified configuration choices from those found in the feed instance. That interface should be created by someone responsible for the ZF code with a knowledge of its official guarantees.

2) I would love the reverse lookup map you suggest using generic tag names, however you'd like to implement them, as per your getContent() example, which is a different feature. This would allow users to be very specific about what they wanted in the output, by specifying namespace:tag:attribute/subelement versus letting ZFR guess, but would really require expert knowledge about feed XML specs to configure output, versus the "naive" approach I described above.

3) I am really looking forward to the array-like access!