Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Reduce number of dependencies prior to v3 #46

Closed
weierophinney opened this issue Nov 25, 2015 · 63 comments
Closed

Reduce number of dependencies prior to v3 #46

weierophinney opened this issue Nov 25, 2015 · 63 comments

Comments

@weierophinney
Copy link
Member

We would like to reduce the number of dependencies prior to version 3 to only the bare minimum required to run an MVC application — without all the bells and whistles. The majority of the components listed in the service configuration of the component are "opt-in", but due to being listed, become hard requirements for end-users.

As such, we need to determine how we can:

  • conditionally add components (solved via Composer)
  • wire factories from those components into the application configuration when installed
  • wire plugin managers from those components into the ServiceListener when installed

Any ideas towards these ends would be tremendously helpful!

Additionally, we need to determine which components are core to the MVC; feedback welcomed!

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

I was thinking in create different metapackages for different use scenarios.

@weierophinney
Copy link
Member Author

@Maks3w That's fine. That's not what I'm asking, though. 😄

I'm trying to determine which components we'll mark as required dependencies of zend-mvc, and how other components, when installed, can notify the application of their factories and plugin managers. Let's keep discussion to those two items, please.

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

which components we'll mark as required dependencies of zend-mvc

For what use case scenario? As I proposed we should consider different scenarios and provide different sets of required packages for those scenarios (metapackages)

how other components, when installed, can notify the application of their factories and plugin managers

  1. This should be discussed out of this specific MVC thread.
  2. Is this the same issue zend-expressive has?
  3. Probably we should turn those metapackages into ZF2 Modules and wire those configs with the standard module bootstrap.

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

Another option could be write a custom Composer installer and write a single file in some place with the config.

@gianarb
Copy link

gianarb commented Nov 25, 2015

In my opinion the MVC must work without ModuleManager..

MVC + ModuleManager is a perfect feature but it is not necessary for a MVC.. :) but it is only a my opinion.

And a lot of dependencies (loaded by ServiceListener) could be modules that you can choice to use or not..

  • Zend\Log
  • Zend\Cache
  • Zend\Session
  • Zend\Authentication

@weierophinney
Copy link
Member Author

which components we'll mark as required dependencies of zend-mvc

For what use case scenario? As I proposed we should consider different scenarios and provide different sets of required packages for those scenarios (metapackages)

This issue is on the zend-mvc repository. I'm talking specifically about the bare minimum required to write an MVC application. When we start talking about usage scenarios, we're talking more along the lines of skeleton packages or meta-distributions — and that belongs in a discussion on the main framework repository (linked). Any discussion of metapackages or installers belongs there. The discussion in here is around the the requirements for the MVC component specifically.

@akrabat
Copy link
Contributor

akrabat commented Nov 25, 2015

In my ideal world, MVC would just require:

  • EventManager
  • ServiceManager
  • ModuleManager
  • View

(Assuming Router is still part of Mvc, otherwise also Router!)

i.e. what I see as a ZF-Mvc apps is one that uses modules and a view. i.e. a version of skeleton without the i18n bits.

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

I disagree about move metapackages to parent discussion. optional dependencies are defined in each component composer so each component has a set of scenarios

@weierophinney
Copy link
Member Author

@gianarb The plan for v3 is to keep as much BC as possible. Currently, the MVC and ModuleManager have a symbiotic relationship, and we do not plan to change that. You are correct, however, in noting the current components that we might want to start removing as dependencies here: log, authentication, etc. are definitely candidates for removal!

@weierophinney
Copy link
Member Author

@Maks3w

I disagree about move metapackages to parent discussion. optional dependencies are defined in each component composer so each component has a set of scenarios

I've provided scope to ensure that the thread does not become unwieldy and present too many ideas/options/directions, in large part to reduce the BC risk and amount of development time required to implement. Please respect this.

@weierophinney
Copy link
Member Author

As noted in the thread on zendframework/zendframework#7646: One option for the wiring issues is to make the various components that need to provide factories and/or plugin managers act as modules; this could be as simple as adding a Module class to each one, and registering it with the application.

@alextech
Copy link

Agreed with akrabat, those listed are bare minimum and is the starting point for any application. Beyond that, I always tend to do further independent research of whether to use ZF lib for specific functionality (most often yes) or introduce external lib.
I am concerned a little with View. It in itself has a lot of dependencies. Thinking of Renderer and its plugins with strategies.

@akrabat
Copy link
Contributor

akrabat commented Nov 25, 2015

I like the idea of a Module.php. It's a standardised way that everyone else uses in order to integrate in with SM/EM.

@gianarb
Copy link

gianarb commented Nov 25, 2015

In my opinion a possibile design is

  • component is a package "framework agnostic" (it uses other components to provide features)
  • Zend\Mvc supports Module (ok @weierophinney I understand your position, module manager is not divisible)
  • components are integrable into the MVC as modules.. because we has a ModuleManager!!

The follow is

  • You could be use module-manager in zend-expressive to serve a module loader.. :) But this is only a reusability dream 😴 ..

@alextech
Copy link

You could only go so far making everything "framework agnostic". For the most part it is a great concept. But can get difficult where components do not seem to work well together. Advantage of monolithic frameworks like ZF2 is everything works really nicely together very seamlesly. Micro-frameworks require too much bridging and clashes of different interface code styles.

@gianarb
Copy link

gianarb commented Nov 25, 2015

@alextech the skeleton application is a monolithic IMO.. The single components have problems but work.. :)

@alextech
Copy link

@gianarb yes so I think taking what current skeleton application has, for the most part, is a good bare minimum dependency. This will also make documentation efforts easier giving a clear line where to start not causing more docs confusion.

@gianarb
Copy link

gianarb commented Nov 25, 2015

I agree with @akrabat the list of dependencies is perfect.. :)

@alextech docs is a required efforts but it can not decide the quality of our code.

@weierophinney a lot of time ago I tried to remove Zend\Log from MVC and move it in a module, maybe we could be "transparent".. I can try to resume my test.

@alextech
Copy link

@Maks3w custom installer seems almost like the only reasonable solution. But that's another tool to deal with. Adding through composer is half a step. If its a Module, still need to add it to a list of loaded modules manually. Or maybe have the autoloader also detect components in Zend\Modules namespace or whatever appropriate making them automatically available when attempt to use and configure as stated in second point of original message.

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

First Module can specify another modules which should be bootstraped too.

@akrabat
Copy link
Contributor

akrabat commented Nov 25, 2015

Another way of looking at it is that:

The dependencies of zend-mvc are the minimum required in order to dispatch the URL /hello and return the words "Hello world" to the client when these words are stored in the Application module's view/application/index/hello.phtml file

Any other component that needs to register with the MVC should do so the same way as any other user-land component: Module.php. It would be lovely to leverage Composer's installation hooks on the other components, such as zend-form, to automatically update application.config.php with the new module when it is composer require'd.

@alextech
Copy link

+1 for Composer Installation hook. How would take care of potential merge issues with custom configs? Or would Module.php be managed purely by that installation script?

@akrabat
Copy link
Contributor

akrabat commented Nov 25, 2015

No idea, but Apigility seems to cope…

@weierophinney
Copy link
Member Author

@alextech We should be able to automate injecting the modules into the application configuration using a composer installer script; working on the Expressive installer has given me a ton of ideas around this. 😄

@Maks3w
Copy link
Member

Maks3w commented Nov 25, 2015

Compiled config is only for compile factories. Rest of config and app configs are merged in a 2nd step

@akrabat
Copy link
Contributor

akrabat commented Nov 26, 2015

@hoppithek No. We're discussing the bare minimum set of components that need to be in the require section of composer.json.

Related to this, we're also discussing how to integrate any component that wants to register things with the MVC system when it's no longer in this list.

@MichaelGooden
Copy link

@hoppithek We are discussing the minimum to implement the Zend\MVC, not some "ideal" MVC stack that doesn’t exist yet.

Regarding the config files composer script thingy, I have been kicking around an idea of how the composer install script could work.

Something similar to Expressive installer, but instead of giving you options of packages, it gives you options of what config file you want to inject the module line into.

So depending on what it detects, you might get a prompt similar to this:

$ composer require zend\log
Please select which config file you wish to inject 'Zend\Log' into:
[0] Do not inject
[1] config/application.config.php
[2] config/modules.config.php
[3] config/http.config.php
[4] config/console.config.php
Enter your choice [0]:

@weierophinney Unless you already have coded something up, I would be happy to start prototyping an installation script?

@hoppithek
Copy link

Maybe it is clear to all of you that the EventManager needs to be part, it was not for me. I don't see why MVC should not be able to run without the EventManager but use it when it is available. Yes MVC currently relies completely on the EventManager, but if we plugin other components as needed and provide meta packages or Modules with "glue" effect (as proposed in this thread), to bind it all together the same might work for the EventManager. Since this is a different approach it is probably outside the scope of this discussion when we take all components as fixed and just see what needs to be there to get a running MVC. I also have no personal squabble with the EventManger, so I am happy to have it on board.

@Maks3w
Copy link
Member

Maks3w commented Nov 26, 2015

I think we should enumerate the scenarios where the MVC component will be used.

For a ZF3 app EM could be required as part of the parent composer and not here.

@alextech
Copy link

@hoppithek EventMenager is core component that is necessary to make many further plugins beyond basic code on top of MVC to work with it. Looking at how almost any other plugin and library in Zend works, many get hooked in one way or another through some event. Most predominant ones are Router and Renderer.

There is also a concept of application life cycle management. Take a look at table at http://framework.zend.com/manual/current/en/modules/zend.mvc.mvc-event.html These are fundamental concepts of Zend MVC that

(1) won't make it Zend anymore without it,
(2) will make additional components difficult to include beyond this core component
(3) make usage of even this core component alone difficult to impossible without leveraging life cycle events. Many things from identity management in session, authentication, to just basic error handling will break. Every basic MVC stack has that in one form or another.

Your concern with config management is valid. Concerning configuration files, I actually write them in XML, and then in Module.php leverage Zend\Config\Reader to merge them per module. I do not like using arrays for that. Can we leverage Zend\Config somehow to add/remove configs instead of php source manipulation? If using PHP's DOMDocument can safely parse and modify the config tree with much lower chance of messing up existing configs written by users.

@MichaelGooden
Copy link

@alextech Shame, I think the guy gets it by now :)

RE: Zend\Config. Good idea, except there will be a few people (myself included) that do not want to add the additional overhead of calling an external class and loading up another file over a native PHP array.

@alextech
Copy link

@MichaelGooden To be honest I thought same as him. It took me a long time to understand why EventManager is needed back in the day and thought it was a nuisance, until I realized the meaning of that table I linked. So knowing that pain of learning, I try to explain it as best I can when I get an opportunity.

Config wise, yes that is a problem. But ZF already has a mindset of development vs. production mode. As do many other languages and frameworks. A framework needs a clear focus of whether it is going to be performance oriented or development speed/comfort oriented. Zend has been in the second. So its not a huge leap to make configs finalized and written out somewhere when put in production mode.

@MichaelGooden
Copy link

@alextech I must apologise, I have been working with ZF2 since beta and forget people don’t always have the same expanse of experience that I do ;) That table is actually a good resource to link to, my brain skipped over the link at first.

Zend\Config actually supports reading and writing to PHP arrays, as well as XML (oh god why), JSON (< the best non-array one), YAML (it has a funny name :), and .INI (because some people are stuck in the 90s)

It wouldn't be hard to include in the script the option to use whichever one you want. Scan /config/ (excluding /config/autoload/) for all files with supported file extensions, and invoke the correct config adapter accordingly.

@akrabat
Copy link
Contributor

akrabat commented Nov 26, 2015

Remember that the config we're talking about is the list of modules loaded by ModuleManager. Not the module's own config as returned by Module::getConfig()

@alextech
Copy link

@MichaelGooden true it does support reading and writing arrays but I was afraid it will still be an issue cine PHP arrays are subject to unpredictable custom logic. But now that @akrabat clarified exactly which configs we are talking about then it should not be a problem. I thought we were discussing list of modules loaded PLUS configs for those modules. I stand corrected.

@hoppithek
Copy link

Even if only the application config is manipulated, including and exporting will remove any comment, use of named constants like APP_ROOT and break any internal logic in the file. Better create a separate config for auto generated content and parse/merge/cache that in the index.php. I am not sure how to do this and keep a good order of modules, though.
Or merge user application config with auto generated into one new merged application config and just change index.php to use the new merged config.

@alextech and others thanks for the link and explaining - upon taking a second look at the Mvc Application I accept EventManager cannot easily be made optional and as I already mentioned I don't mind it. I don't see a problem with other components, if they are added to MVC stack and require Events you just add EventManager at that point. Problem is with event usage within Mvc Application. Also since ModuleManager is required that needs the EventManager as well.

@alextech
Copy link

I realized in explanation I glossed over what lifecycle management actually means. In any MVC framework, it is not possible to tell what stage it is at without some form of event system. Most reliable way to tell the world that MVC has, for example, moved from processing controller action and entered response stage is through event system where MVC will let EventManager know its current position in its work and if you as MVC user or an additional component needs to act on it, it will be possible.

Regarding configs, thats why I propose to not use PHP array syntax itself to discourage users from modifying it by hand or do in a very limited way, using JSON like @MichaelGooden brought up, or XML which I like but most seem to be against. But if it is as @akrabat says where the only place that gets modified is the module loader then will have to make a giant disclaimer in the documentation to be aware that that file is not meant to be used to configure the application by hand and any custom ones should be kept within the module and merged at Module.php only.

@BreiteSeite
Copy link

@MichaelGooden wouldn't it make more sense to write the modules into an own file like vendor/zend/composer-plugin/installed_modules.php with a file which would look like

<?php
/* THIS FILE WAS GENERATED FROM THE ZF-COMPOSER-INSTALL-SCRIPT
DO NOT MODIFY THIS FILE */

return [
    'modules' => [
        'Zend\Log',
        'Zend\FooModule',
    ],
];

which i then could load and merge into my init_application.php script which would look something like

<?php

// ...
$applicationConfig = require 'application/config.php';
$installedModules = require 'vendor/zend/composer-plugin/installed_modules.php';

$config = array_merge_recursive($applicationConfig, $installedModules);

\Zend\Mvc\Application::init($config);

This way, your composer script could modify its own file and its not from messing with my code.

Zend would provide something like an own module loading config which i'm then free to use or not. It would also mean that in my application.config.php i just reference my own modules and do not need to care about third-party modules anymore. Would be easy to opt-in and opt-out of this behaviour for special needs.

@Maks3w
Copy link
Member

Maks3w commented Nov 27, 2015

You asume vendor folder location. This could be customized and don't be available. The point of use classes is the autodiscover feature of class autoloaders so you can use without any knowledge of the directory tree.

@Maks3w
Copy link
Member

Maks3w commented Nov 27, 2015

I've tested the minimum packages required for execute the test suite of zend-expressive-zendrouter

zend-expressive-zendrouter

  • Installed (17)

zend-diactoros zend-form zend-mvc zend-uri
zend-escaper zend-http zend-psr7bridge zend-validator
zend-eventmanager zend-hydrator zend-servicemanager
zend-expressive zend-inputfilter zend-stdlib
zend-filter zend-loader zend-stratigility

  • Used (9)

zend-diactoros zend-http zend-psr7bridge zend-stdlib zend-validator
zend-expressive zend-mvc zend-servicemanager zend-uri

  • Unused (8)

zend-escaper zend-eventmanager zend-form zend-hydrator
zend-inputfilter zend-filter zend-loader zend-stratigility

2 of 5 required MVC dependencies are used.

@gianarb
Copy link

gianarb commented Dec 26, 2015

@akrabat in my opinion View should be only a interface (abstract, something) that helps me to use or implement a template engine or a render library.

Current Zend\Mvc\View could be a stand alone component (template engine.. some of twig, plates..)

In my opinion in order to split this components

  • Zend\Log
  • Zend\Cache
  • Zend\Session
  • Zend\Authentication
  • Zend\Form
  • Zend\Console
  • Zend\Serializer
  • i18n
  • ..

We can create a FrameworkModule or we can add the Module.php on each component..
In my opinion a module is more clean..
This module should contains

  • Specific controller plugins
  • Services

I know that we are only moving all dependencies from Mvc to a module.. but it could be a good change.
Module borns to use third part components on ZF2 application.. The best way to create independent components is to be yourself third part, without shortcuts or reduction :)
A single module for each component sounds good but it is very strong to maintain.. it serves a strong team

@weierophinney
Copy link
Member Author

Finally at a point where we can start acting on this, and will respond to a few things before beginning.

Table of Contents

Responses to Feedback

@MichaelGooden — regarding this:

So depending on what it detects, you might get a prompt

I like that idea! Considering the module list varies between the ZF skeleton app and that in Apigility, an ZendDevelopmentTools recommends something else as well, this is a nice compromise. We can even have a default that is used when the --no-interaction flag is available.

@hoppithek and @Maks3w — regarding this:

For a ZF3 app EM could be required as part of the parent composer and not here.

The EventManager is a hard requirement of the current MVC, as everything that occurs is the result of triggered events: bootstrapping, routing, dispatching, rendering the view, and sending the response are all events. We are not proposing a substantial refactoring of the MVC; it's field-tested and works. What we're proposing is reducing the components to produce a "core" MVC distribution, and that work is primarily centered around the Zend\Mvc\Service subcomponent, which provides the bulk of the wiring between MVC applications and the individual ZF components.

@alextech — regarding this:

So its not a huge leap to make configs finalized and written out somewhere when put in production mode.

You can currently use any configuration format you want that is supported by Zend\Config\Reader, including XML and JSON (and YAML, if you do a little extra configuration to tell the reader how to parse YAML); we simply default to PHP as a) it's performant, b) it allows usage of constants, including ::class, and c) it does not require learning a configuration format.

Regardless of the format you use, the ConfigListener from zend-modulemanager can be configured to cache configuration, meaning any heavy-lifting of parsing configuration can be done precisely once, and then cached for all subsequent requests. My point is: this is a solved problem in ZF2 already.

@hoppithek — regarding this:

Even if only the application config is manipulated, including and exporting will remove any comment, use of named constants like APP_ROOT and break any internal logic in the file. Better create a separate config for auto generated content and parse/merge/cache that in the index.php. I am not sure how to do this and keep a good order of modules, though.

Not true. We managed a way to update configuration in zend-component-installer that uses static parsing, retaining all comments and formatting.

@Maks3w — regarding this:

2 of 5 required MVC dependencies are used.

which was in your comment detailing what components were installed when testing zend-expressive-router, this is largely irrelevant: zend-expressive-router is using the zend-mvc Router subcomponent, which is not itself event-driven. @DASPRiD is already discussing moving that to a separate repository precisely because it can be used standalone without the rest of the MVC.

@gianarb — regarding this:

in my opinion View should be only a interface (abstract, something) that helps me to use or implement a template engine or a render library.

That would be a major refactor, and a major change to the current workflow. For better or for worse, rendering is done as a separate event, and itself triggers events to allow both rendering content and updating the response; it's not as simple as just calling something like render(...). (If you want that, look at zend-expressive-template!)

And regarding this:

We can create a FrameworkModule or we can add the Module.php on each component..
In my opinion a module is more clean.

Why is it "more clean"?

What I see is an explosion of repositories, and code going out-of-sync between the individual components and the "module" repositories, as capabilities are added to the components, but not exposed in the factories provided in the modules. Considering that today we have more than 50 components, this is not a trivial concern.

Current Status

Now, for the update.

I alluded to this earlier, but I created a "component installer", zend-component-installer as a proof of concept a couple months ago. This installer is something you install in your application, and it adds both a Composer script class, as well as updates your composer.json, so that each time you first install a component, it will update your application configuration with the module, pushing it to the top of the module list (this is done to allow your own modules, or even third-party modules, to override component configuration).

Components opt-in to the workflow by adding the following to their composer.json:

"extra": {
  "zf": {
    "component": "Some\Component"
  }
}

This works surprisingly well and consistently. What I'd like to do is:

  • adapt it to prompt for the configuration file to update, per the suggestion from @MichaelGooden ; this should also allow providing an arbitrary file, in the same way that the Expressive installer allows providing arbitrary packages.
  • adapt it to accommodate both components and modules (the latter would be appended to the module list, vs prepended).

Additionally, another idea has been floating. In Expressive, we're planning to adopt mtymek/expressive-config-manager into our workflow. In that paradigm, an invokable class is used to provide application configuration. My thought is that the Module classes should either:

  • implement __invoke() and have it proxy to getConfig() (or vice versa), or
  • have getConfig() instantiate and invoke a configuration class (e.g., return (new Config())();)

In each case, this would allow re-use across both ZF and Expressive, and potentially pave a new path forward for shipping configuration with components in a re-usable fashion.

Proposed Dependencies

Having spent way too much time in zend-mvc while refactoring for forwards-compatibility with existing v3 components, what I see is the following:

Required components

  • zend-eventmanager (which provides the internal workflow engine)
  • zend-servicemanager and container-interop (from which all services are retrieved)
  • zend-view (used within the default workflow; however, if you return responses from your listeners and/or controllers, it can be omitted, but omission fails the default use cases as outlined by @akrabat above)
  • zend-http (not required for console-only applications, but required for the default use cases as outlined by @akrabat above)
  • zend-modulemanager (used by the Application during bootstrapping)
  • zend-stdlib (DispatchableInterface, RequestInterface, ResponseInterface, SplQueue, ArrayUtils, etc.)

Semi-required components

  • zend-stdlib (for things like ArrayUtils::merge() and error handling; most of that functionality could likely be duplicated in the component itself to reduce dependencies) (moved under required components, as quite a few features are required)
  • zend-psr7bridge (used by the MiddlewareListener, which is registered by default. However, if no routes map to middleware, no classes from this component are ever used)
  • zend-console (used for routing and in the view layer; if you're not defining any console routes, and not using any 3rd party tools that do, it's irrelevant. However invocation of public/index.php from the CLI will fail if it's not present)

Everything else

Everything else can and should be removed. This includes:

  • zend-authentication
  • zend-cache
  • zend-di
  • zend-filter
  • zend-form
  • zend-hydrator
  • zend-i18n
  • zend-inputfilter
  • zend-json
  • zend-log
  • zend-session
  • zend-serializer
  • zend-text
  • zend-uri (this is a dependency of zend-http anyways)
  • zend-validator
  • zend-version (this component is legacy at best at this time)

Interestingly, there are other components not currently in the composer.json that likely could stand the module treatment, too, due to their common appearance in applications:

  • zend-navigation
  • zend-paginator
  • zend-db
  • zend-ldap
  • zend-mail

Roadmap

At this point, my plan is:

  • Copy factories, abstract factories, etc. to their individual components.
  • Create Module and/or similar classes in these components.
  • Tag new minor releases of these components containing the above.
  • Remove each component receiving that treatment as a dependency of zend-mvc (on the develop branch).

@gianarb
Copy link

gianarb commented Mar 8, 2016

@weierophinney thanks for this summary!

Create Module and/or similar classes in these components.

It could be a suggested integration of all ZF ecosystem with Zend\Mvc, we can install this module as default into the ZendSkeletonApplication in order to maintain a similar experience for the users that don't care about witch components use or not.
But we will be a strong Mvc component without doesn't required dependencies and we don't dirty each component with a out of place Module.php (or whatever will be) file.

Why in my opinion is more clean?

  • Module.php is only an hack to manage integration with a component as a module without create a module (required dependency of Zend\Mvc).
  • You are creating a hybrid component/module when I think that the best flow that we (or only me) suggest is:
  1. Create your agnostic framework library.
  2. Manage integration with ZF or Symfony or PHPNuke with a Module, Bundle, I don't know which is the equivalent for PHPNuke 📦

I know practice we are only moving all dependencies in a module but only because create a "integration module" for each components it's more expensive (but i think that it is the most clean solution).

@weierophinney
Copy link
Member Author

@gianarb My argument for pushing into the components themselves is to allow simplified re-use regardless of the framework.

  • The factories belong with the components. Most of the dev dependencies exist to test factories. In a number of cases, I found the tests for these factories in the components themselves, which was an odd dependency inversion.
  • How the factories are wired into the service container should be part of the component. The rationale? If I want to re-use the component in, say, zend-expressive, right now I have to duplicate that configuration (and, in many instances, the factories themselves!). Having the component be able to provide that default configuration to me makes it easier for me to consume the component, regardless of context. (Of course, this begs for a standard around container configuration and mappings.)

What you describe, with a single module bringing in all current dependencies, is what should be in the skeletons; we can have multiple skeletons, targeting multiple use cases (e.g., a minimal skeleton, a "kitchen sink" skeleton with everything currently in ZF2, an API-centric skeleton, etc.). The main argument I can see for creating a module is for having a single thing to drop-in to existing applications when they upgrade to zend-mvc v3, and the approach of having each component exposed as a module does not mean we cannot or should not do that as well; it just allows for more flexibility and granularity.

While I understand the allure of omitting integration-related classes from the components, from a position of (a) managing the repositories, (b) thinking about overall dependencies, and (c) considering syncing issues, splitting this stuff into separate modules is a nightmare.

  • (a) as noted before we can have N*2 repositories (module repository per component), N+1 repositories (components + an integration module), or N repositories. Seeing as N repositories are already hard to manage, why should we add more?
  • (b) communicating that a developer needs to not add zend-i18n, but zend-i18n-module, is a nightmare. Developers will inevitably install the former, and wonder why things don't "just work". Telling them to use zend-i18m-module then becomes a FAQ. Anytime you need a FAQ, you need to ask if you're paving the cow path, or ignoring it. Additionally, users end up complaining about the fact that they need to install two dependencies for what is, as a consumer, only one. This may seem trivial, but when you look at folks in countries or regions with less available bandwidth and/or data caps, it's not. On top of that, it makes understanding why certain things are installed harder.
  • (c) We've already encountered problems due to new features being introduced into components, but the factories in zend-mvc being behind; moving that into an integration module, or even a module repository per component, does not make that problem go away, and that's a problem I'd really like to solve, as it makes my life and the life of other maintainers simpler.

I think a module containing all current ZF dependencies does make sense, but feel strongly it needs to be done in addition to having each component exposed as a module/configuration provider. The module will mainly exist to allow developers with existing applications an easy way to upgrade, and/or for folks looking for that "full stack" experience an easy path that does not involve individually installing each package (though this latter will likely be served by a skeleton).

@weierophinney
Copy link
Member Author

New finding: zend-stdlib is definitely required; we use it for DispatchableInterface, which consumes its own RequestInterface and ResponseInterface, as well as its SplQueue implementation.

@gianarb
Copy link

gianarb commented Mar 9, 2016

I understand, I try to do some questions:

  • Where we move the factories we must add Zend\ServiceManager dependency as "require" or you suggest to add another "suggest if you use" this factory?
  • Other point is the controller plugins, for example the IdentityPlugin will be move into the Zend\Authentication, with Zend\Mvc as "suggest if you use" dependency?

communicating that a developer needs to not add zend-i18n, but zend-i18n-module, is a nightmare

The skeleton application will contains all modules, if someone decide to start your own skeleton will be
informed because we will write it into the docs or because he has some skills and he will understand the composer.json configuration.

it makes my life and the life of other maintainers simpler

It's a good point but I received the same feedback before our spit from different current maintainers but now the same people, after the slit, they assess the result better.

@hoppithek
Copy link

@weierophinney Thanks for summing this up. I still say "including and exporting" will remove a lot from the file. The alternative you suggest: static parsing, which in the linked examples breaks down to a preg_replace of the file content is possible, but will just as often fail. Nonetheless, as long as the files being manipulated are simple, I think it will work. If it doesn't it might still be possible using source tokenization and adding the entries that are needed while rebuilding code from tokens.

@weierophinney
Copy link
Member Author

@gianarb

Where we move the factories we must add Zend\ServiceManager dependency as "require" or you suggest to add another "suggest if you use" this factory?

Most of these already have a dependency on zend-servicemanager. In the few cases where they do not, yes, it becomes a suggested dependency (and a development requirement).

Other point is the controller plugins, for example the IdentityPlugin will be move into the Zend\Authentication, with Zend\Mvc as "suggest if you use" dependency?

No, these will stay in zend-mvc. Plugins are points of integration, and should stay there. In those cases, the dependency becomes a suggestion, as not all plugins are used in every application.

communicating that a developer needs to not add zend-i18n, but zend-i18n-module, is a nightmare

The skeleton application will contains all modules, if someone decide to start your own skeleton will be
informed because we will write it into the docs or because he has some skills and he will understand the composer.json configuration.

You're making the assumption that everyone starts from the same skeleton. For users who are upgrading, this is not the case. Additionally, one of the suggestions made in this and other threads is that we have multiple skeletons, targeting different use cases. As such, we cannot assume that all components are necessarily present, and need a mechanism for automating installation of new components with their default configuration.

weierophinney added a commit to weierophinney/zend-component-installer that referenced this issue Mar 12, 2016
Per the discussion on zendframework/zend-mvc#46, this commit updates the
installer to allow the following behaviors:

- Discovery of available configuration files to update.
- Prompting for configuration file to update (including none)
  - Ability to select "do not inject"
- Separation of package injection into/removal from configuration into
  strategy objects.
@weierophinney
Copy link
Member Author

@MichaelGooden I've updated zend-component-installer to act as a composer plugin, and it now addresses the various criteria you outlined (discovering the multiple configuration files supported, prompting as to which one to inject into, allowing the option of "no injection"). At this point, that puts us in a position that we can start the work of separating out the various component-specific functionality into the components themselves.

@weierophinney
Copy link
Member Author

@weierophinney
Copy link
Member Author

Completed as of #128 !!!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants