Based on discussions at #1308152: Add stream wrappers to access .json files in extensions with comment #1308152-167: Add stream wrappers to access .json files in extensions by @fietserwin, reproduced below. There is need to rework the streamwrapper API for D8 to achieve more consistency and optimizations of implementation.

Regarding the state of the API for our stream wrappers
Having reviewed this code now for the 3rd time in a short period, I mentioned I kept jumping from method to method, following call chains and going round in circles. To me, this is a sign that something structural is wrong with what we are doing here. Think of:
- Is the inheritance tree logical?
- What methods are there and what methods would I expect?
- where are the methods implemented and overridden and is this logical?
- Is method naming logical and consistent?

So back to the tasks and responsibilities of a stream wrapper:
implement PHPStreamWrapperInterface so it is accessible via and reacts like standard PHP file functions. This is done by LocalStream and LocalReadonlyStream. All subclasses of these are only there to define different parts of the local file system.

However, besides this main task, there are some Drupal specific functionality to be provided. Or, what public methods would I expect (besides the stream wrapper functions):

Stream wrapper as a file wrapper:
realpath(): I doubt that this will be used a lot (directly), but it doesn't hurt to have it public.
dirname(): This is even more doubtful, but it could be used to create another file in the same directory, though we could simply use dirname($wrapper->realpath()) for that.

Stream wrapper as an externally accessible resource:
getExternalUrl(): this is of course where these stream wrappers shine and provide additional value above just being a stream wrapper.
As all these stream wrappers are expected to operate within the hierarchical local file system, the only difference is the starting point they define within that local file system and the url that corresponds to that starting point. Given this, what (protected) methods would I expect?

Stream wrapper as a file wrapper:
getDirectoryPath(): the starting point within the local file system that this stream wrapper covers. I don't think this name is logical and would like to suggest to rename it to something like getStreamDirectory() or getBaseDirectory(), or getBasePath(). (The latter following a method in Symfony\Component\HttpFoundation\Request.) Note: there is a todo about the naming of this method, but the issue it refers to is long closed.
getTarget(): the relative path within the sub file system that this stream wrapper covers. I think that this name can also be better, but looking at file_uri_target(), I can understand the name. Perhaps something like getRelativePath() would be better given that for system streams the first part of the target is also part of what defines the base directory(, or getPathInfo() to follow Symfony\Component\HttpFoundation\Request again).

Stream wrapper as an externally accessible resource:
and at the url level, getStreamUrl(): the (base) url that this stream wrapper covers.
getTargetUrl(): given that we are working within a hierarchical file system, this will be equal to getTarget(), except perhaps replacing \ with /. The same suggestion here as to the name of this method: getRelativeUrl() would be better.
and for the system stream wrappers, getOwner(): returns the first part after the scheme (module or theme name) used for:
getOwnerDirectory(): returns the directory where the owner (module, theme or profile) is located.

Comments

almaudoh’s picture

Title: Review and Redefine the Drupal StreamWrappers API including error handling » Review and Redefine the Drupal 8 StreamWrapper API including error handling
Issue summary: View changes

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.

jibran’s picture

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

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

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now 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.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now 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.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.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.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). 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.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now 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.

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

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

guypaddock’s picture

+1 The Stream Wrapper API is a mess.

Stream wrappers simultaneously behave as both open file resources (i.e. an open "stream") and the high-level interface about the protocol for that type of file resource (i.e. what should be a factory for opening a new stream). Because the same type of classes are being used for 2-3 different concerns, the naming of these objects is inconsistent. Core names most of these objects "streams" (LocalStream, TemporaryStream, PrivateStream, PublicStream) while calling them "stream wrappers" while other areas of core and contrib both call and name them "stream wrappers" (HttpStreamWrapper, DummyStreamWrapper, etc).

Callers have to keep track of what methods they can and cannot call on the stream wrapper depending upon the state of the wrapper, and the same wrapper can't be used for more than one file even though some methods on the wrapper expose information about the protocol and wrapper itself and can be called without the wrapper even having a stream open.

guypaddock’s picture

Issue summary: View changes

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.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.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.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.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now 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.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now 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: 10.1.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, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.