Global settings (varibales) for the whole website

Notice: This thread is very old.
TonnyVlcek
Member | 31
+
0
-

Hey,
I'm starting a new project with nette and even though I've been working with nette before a little bit, I'm still real beginner as far as nette development considered.

For this project I need to set up some global variables representing things such as default email address for email sending scripts, default images folder, and other general things like that. There is quite small chance that I'll have to change them but I just want to be sure that in case I would have to I would be able to change it just on one place.

I had two ideas how to do it:

Special table in MySQL database called config (or something like that):

VariableName Value
defaultEmail xxx@yyy.zz
imageFolder images
galeryFolder galer/photos

---OR---

To create a class ConfigManager which will get values of those variables through its constructor. This class would be registered in config.neon as service and values would be stored config.local.neon in parameters section:

//consig.local.neon
parameters:
	adminEmail: papi@gmail.com
	imagesDir: ./images/

//config.neon
services:
	- Vex\Config\ConfigManager ( %adminEmail% , %imagesDir% )

(One friend of mine told me to do it like that but it seems to be unnecessarily complicated to me.)

Which of those methods do you think is better for this purpose? Are you using something completely different?

Thank you for your time :)
Tony

Last edited by TonnyVlcek (2014-11-25 05:38)

Oli
Member | 1215
+
+1
-

I tried the first way, but there was a complications with inconsistent db between programators. So, if you don't need change this variables through application, i would prefer neon way. I have one wrap class for that, it looks like:

parameters:
	settings:
		adminEmail: papi@gmail.com
    	imagesDir: ./images/

services:
	- Settings(%settings%)
class Settings extends \Nette\Object
{
	protected $params;

	public function __construct($params)
	{
		$this->params = $params;
	}


	public function &__get($name)
	{
		return $this->params[$name];
	}
}
amik
Member | 118
+
+2
-

Well, things like “global variables” do not correspond to the Dependency Injection principle. To write a easily-readable and reusable code, you should provide the configuration only to these services that actually need them.
Your config.neon could look like this:

parameters:
	adminEmail: foo@example.com
	imagesDir: "%appDir%/../www/images"

services:
	- Vex\ContactMailSender(%adminEmail%)
	- Vex\ImageUploader(%imagesDir%)
	- Vex\ImageDownloader(%imagesDir%)

rather pass the %imagesDir% to all services that actually use it, than creating one ConfigManager maintaining all configuration, you will be later glad you did.
Why? Imagine that you will want to use your ImageUploader in another project. If you do it this way, you will just be able to use it “as is”, and you will exactly know what services/configuration your ImageUploader needs.
Using your way with ConfigManager, you will have to change the dependency of ImageUploader to a different ConfigManager of your other project, again inspect its code and again think about the dependencies it actually needs.

Another thing is I discourage you from using relative paths at all, as they are not much reliable (for example they will become invalid if someone calls “php www/index.php some-cli-command” from shell).

greeny
Member | 405
+
+1
-

Hi,

database version has only one advantage: values can be easily changed, if you implement some CMS form for it. Values in config cannot be changed so easily.

So it depends on your use-case (admin email and stuff like this should not change much often, so I'll prefer the second one (config)).

Regarding the “complicated way”: I don't think, there is anything complicated about it:

  • registering service in config is needed for DI
  • writing parameter values in config.neon (or better config.local.neon, so it can change between production/development) is obviously needed
  • pushing parameters to service is needed too :)
  • you can of course make parameters public in that service, but keep in mind, that they can be changed then wherever you want

Regarding transfering whole parameters array (or parameters.settings): it definitely breaks DI's principe (it's like using $presenter->context instead of injects)

TL;DR
If you expect these values to change often, use database version, in all other cases use config