weworkweplay/ProcessJSONInstaller — pull request #6 by owzim (2014-05-22 23:56:39+00:00)
Title: Adds functionality uninstall modules and to have selectors as values

# Summary
### Intro
I have tested my modifications with the installation and uninstallation of all module JSONs you provided, everything seems to still work as expected.
### Selectors as values
Some fields or pages have to reference other pages that are created while installing. Since one doesn't know the id of those newly installed pages, one would want to reference them via selector.
##### Example 1
This assigns the returned page instance to the parent property:
```
"attributes": [
{
"name": "parent",
"value": "parent.name=some-name,name=some-other-name",
"type": "selector"
}
]
```
##### Example 2
This assigns the returned page id to the parent_id property:
```
"attributes": [
{
"name": "parent_id",
"value": "parent.name=some-name,name=some-other-name",
"type": "selector_id"
}
]
```
##### Conditional Saving within each prepare method
Since pages must exist before being able to be selected by other pages created while installing, those pages are saved within the prepare method (hacky, since the prepare and save logic are originally separated).

I must admit that I don't understand why that logic is even separated in the first place.

##### Rerunning the installation of fields (see Module::install)
When a field references a page (PageField) that is created while installing, the page does not exist yet, because the pages are installed after fields and templates, so the field installation has to be run again, when any field references a page.

##### Module::prepareFields():
```
$hasSelector = self::applyAttributesOrDefaults($attributes, $f, $hasSelector);
if($hasSelector) {
$this->fieldsHaveSelectors = true;
}
```
##### Module::install():
```
if($this->fieldsHaveSelectors) {
$this->prepareFields();
foreach ($this->fields as $field) {
$field->save();
}
}
```
The whole scenario gets more clear, if you look at the ```simple-page.json```

### Uninstalling modules
* deletes pages, templates and fields defined in each module JSON
* it does not delete dependencies
* it does not delete pages (those, manually created after install) that use the created templates or fields (unsave, I think), so they have to be deleted manually beforehand
* since it deletes everything configured in the respective JSON file, it would also try and delete things that existed before and are merely modified, so those should be declared as **prefab** (```"prefab": true```), so that they are skipped in the deletion process.

### Next
I am planning on doing those things as well:
* proper docs in the readme
* possibility to define other JSON files as dependencies, so that they are installed before the actual JSON installation is run.
* perhaps have an export to JSON functionality of selected pages in admin, which includes all referenced dependencies, fields, templates, but that might be not toooo trivial =)