discourse/discourse — pull request #570 by ZogStriP (2013-03-27 00:21:50+00:00)
Title: add requires_restart attribute to site settings

This is part **1** of **2** of the work needed to get #481 to work properly.

## What's new?

This adds the `requires_restart` attribute to the site settings.
You can now define a site setting as follow:

```ruby
client_setting(:top_menu, 'popular|new|unread|favorited|categories', requires_restart: true)
```
This will display a warning message below the site setting:
![Screenshot_27_03_13_00_35](https://f.cloud.github.com/assets/362783/306105/54347b54-966e-11e2-941e-bbafa6e8fecf.png)

When saved, a message will be displayed warning the administrator he has to restart Discourse for the setting to take effect:
![Screenshot_27_03_13_00_36](https://f.cloud.github.com/assets/362783/306118/a37b9828-966e-11e2-937d-b9edfb3dfc6d.png)

The message will **only** disappear if the application is restarted.

## How is it done?

### Special Application Flag

First, we need a special application flag that is triggered if you change certain settings and is communicated to all the processes, saying a restart is required for some settings to take effect.

My first idea was to use a file but I was having two concerns: performance and multi-sites requirement. So I decided to use **Redis** and implemented the `require_restart` flag in the `lib/discourse.rb` file.

I made sure the flag is removed when the application is started by calling the `Discourse.application_started` method in the `site_setting` initializer.

### The `requires_restart` attribute

I then proceeded to add the `requires_restart` attribute to the `site_setting` model. Most of the changes went into the `lib/site_setting_extension.rb` module. They're pretty straigtforward except one thing: I made sure that the `requires_restart` attributes is **only** serialized when its value is `true`, hence reducing the data to be transmitted to the client (in the `all_settings` method).

I also modified both `add_override!` and the *only-used-in-test* `remove_override!` methods so that they set the application-wise `require_restart` flag.

### The client-side

In order to inform the administrator, I had to convey the information to the JS application.

I updated both `setting_bool` and `setting_string` templates to display the warning message when the setting requires a restart *(side-note: they should probably be refactored someday)*

I modified the `index` method of the `admin/site_settings_controller.rb` to include the previously defined flag alongside the site settings.

I added the `restartRequired` property to the `AdminSiteSettingsController` and updated both the `findAll` and `save` methods of the `site_setting` emberjs model to make sure it is kept up to date on the client-side.

**Note:** this line feels hacky *ish*, but I don't know other way to get a controller's instance.

```javascript
Discourse.__container__.lookup('controller:adminSiteSettings').set('restartRequired', data.restart_required);
```

Finally, I added the warning message to be displayed at the top of the site setting template whenever a restart is required.