I want to write a php application using Zend Framework 2 (just the beta 2 yet).
Because it's going to be a collection of several webservices I decided to seperate it into different modules (with own databases).
Before starting to write the first module I want to write the code wich each module should need. For example the layout. Each module uses the same layout. That's why I want to write it globally to improve the development process of single modules.
How can I provide defaults for each module globally? (e.g. layout, plugin, default database model, ...)
In ZendFramework2 configurations from all modules are always merged.
Additionally there is a global config which can overwrite module-wise config.
So including a vendor module brings in a default configuration you can and should overwrite via your global config.
The global config may consist of multiple files making it easy to distinguish between modules-to-be-configured.
The first example I have is an article of akrabat about module configuration and overrides.
Another nice example of this pattern is Akrabat's quickstart (https://github.com/akrabat/zf2-tutorial):
one App module, based on ZendSkeletonApp
one Album module, the part you actually did.
In the App module there is config for the basic routing, Views and the Layout are set up
In the Album module there is only the set-up for Album-specific things (e.g. dependency injection), the view and routing are used from the App-modules config.
You may decide to overwrite this config on a per-module basis or globally, in the default project layout your configs are placed like this:
/config/application.config.php the base configuration
/config/autoload/*.config.php may be used to overwrite modules or app config (e.g. for local development)
/module/[your-module]/config/[your-module].config.php the default configuration of your module
/vendor/[vendor-module]/config/[vendor-module].config.php a module you dropped in, but has definitions for it's dependency injection. if it uses e.g. a database you want to overwrite some parameters in your /config/autoload/*
Related
Is there a nice way in Symfony 2 or 3 to load all classes within a directory that implements a particular interface?
Since Symfony 3.3/3.4 it is possible by using configuration only (without a need to write custom CompilerPass):
# config/services.yaml
services:
# ...
_instanceof:
App\HandlerInterface:
tags: ['app.handler']
App\HandlerCollection:
# inject all services tagged with app.handler as first argument
arguments: [!tagged app.handler]
and if you need to restrict services to register from a single directory see importing with resource
references:
https://symfony.com/doc/current/service_container/3.3-di-changes.html#auto-configure-with-instanceof
https://symfony.com/doc/3.4/service_container/tags.html#reference-tagged-services
http://symfony.com/doc/3.4/service_container.html#importing-many-services-at-once-with-resource
Short answer is: you can't.
You don't know, what is in a file until you load it.
Long answer (taking into account what you have wrote in the comment under the question):
The only thing you know before you load a file is its name. So one of solution is to name your modules' classes (and files) with a fixed pattern like UserModule, ProductModule and so on. That way you can load all modules by their names. But this is the solution that I wouldn't suggest.
I my opinion you should change the approach and inverse the workflow. Create a class in which you will define all modules that need to be loaded. In Symfony it's called by default AppKernel, in which you define bundles (modules) to be loaded and initialized.
This has a few advantages.
You can have multiple entry points to your application and configure each one with different modules.
You may have a few different environments (like production and development) with different modules loaded in both of them. (e.g. add some modules in development like profiler)
Also dependency managment is much easier, since you can load defined modules and add their dependencies also with autoloading.
In general I think that you should avoid manual loading any php files (except autoload.php or similar that contains autoloaders) at all.
As the subject says, really.
Assume I have two apps, namespaced as App_A and App_B. App_A has App_B imported as a git submodule and then autoloaded via its composer.json.
When I call App_B\SomeModel->someMethod() from an App_A controller, will the model query the database configured in App_B's config files, or will it inherit the config values from App_A?
Short answer: it won't inherit App_B's config files.
Expanded answer: App_A is loaded with it's config files. You call App_B\SomeModel::someMethod() from App_A, App_A's configuration will be used. To have two independent applications with 'knowledge' of each others state you would need to define a communication method between the two such as Message Queues(MQ), HTTP, Sockets, Streams etc etc. You would also never import App_B as a submodule of App_A and vice versa unless you're ok with App_*'s classes being used in the context of the loaded application stack.
Another option is to look at the HMVC or Heirarchical MVC pattern. This could possibly give you a solution to this problem without keeping the applications separate. There was a bundle in Laravel 3 enabling HMVC but I haven't looked into it since then as it (imo) is an anti-pattern. I don't know if one exists for Laravel 4 or 5.
I am solving a problem: I have a ZF2 Skeleton application which runs fine, service manager, db adapter, routing, everything is fine. But what I need to solve is how, when or how better load some configuration (settings) from database?
The point is (AFAIK) to have the Zend configs that are not visible nor editable from outside (or let's say via administration). But I need to have the ability to administer many configuration settings - and these should be loaded also on the startup (bootstrap, whatever). These settings could be managing e.g. widgets displaying (let's assume that almost every block on the website is controlled by widget - view helper - and I have to decide - via configuration - whether to display that widget or with what additional settings).
What I would need to help with is how to manage this configuration that will be loaded from DB.
should I merge it with Zend config?
should I load it in module's onBoostrap?
should I use better solution (what)?
I was thinking of having editable PHP config file (that will Zend simply load with other config files) so that administering these settings would lead to reading from and writing to a file but this is really a bad idea as there is possibility of more simultaneous edits for which purposes the database handles this far better.
Your module.php should have a function getConfig() which returns an array. You should be able to modify it in such a way to fetch your config key/values from the database.
How to integrate module inside application? I have modules having two controllers and two respective views inside module. Now I want to integrate this module inside my application, so that views and actions can be handled by this module only.
Note that your Application, modules and System files may intersect. Use this picture to understand Kohana cascading filesystem:
So, if both application and your module have a views/welcome.php, application one will be found. When two modules have files with the same path, Kohana will select module with highest position in Kohana::modules() list.
Once you have created the module enable it in the application bootstrap.php then you should be able to visit [your-website]/modualController/action you might need to look at routes.
This is a great resource for modules and routing, and everything else Kohana http://kerkness.ca/wiki/doku.php
I am creating a custom magento module and cant decide the best place to store some config files i require with the module?
Anyone out there suggest the best place for this? Should it be in the root of the module or in with the helpers maybe?
Edit:
Along the same lines as this question: is it acceptable to have a folder in the root of the namespace for the modules for includes that will be shared amongst the modules?
If these files are for configuration, they belong in etc. Think of the etc folder the same way you would a unix/linux/bsd system's etc folder. It's where you put configuration information. Convention is that you should use an XML file to hold your config data, and then load it with
Mage::getConfig()->loadModulesConfiguration('your-xml-name-here.xml')
When you use the loadModulesConfiguration method to load your configuration values, Magento combines XML files for ALL modules in the system into one big tree. This allows other modules you'll write (or others would write) to share the configuration information.
You don't need to do this, but etc is definitely the defined place for any configuration files you want to include with your module. Also, whatever method you're choosing, I'd pick a unique file name (packagename_modulename.xml, packagename_modulename.inc, etc.) to ensure against the slim possibility that someone at Magento might pick your name to use in a future version.
Along the same lines as this question: is it acceptable to have a folder in the root of the namespace for the modules for includes that will be shared amongst the modules?
No, that would not be acceptable. If you want a shared configuration, use the method I mentioned above. If modules need to share other information with each other, they should either do so directly (one module instantiates another module's model) or you should define a central "broker" module that handles all inter-module communication. If you're interested more in the topic, I'd recommend the first few chapters of Meyer's Object-oriented Software Construction. If you can get past the whole "how to implement low level data structures" aspected of old programming books, its a great introduction to what CS people when they say "module".
(it's also worth mentioning that if there are simple configuration values, learning how to use the Magento System Config Admin section is worth it.)
You could probably get away with this, but you're purposely avoiding Magento to do so. Inside a module, make a directory called etc and put an XML config file in it called config.xml. That file will be read and included in the Magento configuration, which means you won't have to try to escape the framework to grab your configuration data. Take a look at the existing files for some examples.
The other benefit to this approach is that the conversion from config XML files to user configuration options (in the admin panel) isn't too difficult (requires minor refactoring), so you can later change your configuration method with ease.
Hope that helps!
Thanks,
Joe