contao/core — pull request #6248 by tristanlins (2013-09-29 13:33:53+00:00)
Title: [WIP] Model registry

**Continue of #6131 but against develop branch!**

In Bezug auf #6070 wie versprochen ein PR für eine Model Registry.

**Checklist**
- [x] - (1) Registry zur Database Connection hinzufügen
- [x] - (2) Registry in den Models verwenden
- [x] - (3) Bei `Model::save` nur die Änderungen speichern
- [ ] - (4) Änderungen bei `Model::setRow` richtig protokollieren
- [ ] - (5) Model save darf nur dann ein Insert machen, wenn das Model nicht in der Registry verwaltet wird (siehe A)
- [ ] - (6) Model save darf nur dann ein Update machen, wenn das Model in der Registry verwaltet wird (siehe A)
- [ ] - (7) Nutzung der Registry in findBy optimieren, wenn dort ausschließlich nach PK gesucht wird
- [ ] - (8) Magic Properties entfernen?! (siehe B)
- [x] - (9) Collections iterierbar machen (das war eigentlich die Aufgabe von @discordier ^^)
- [x] - (10) Registry im Debug Tool tracen
- [x] - (11) Feldänderungen nur dann merken, wenn der Wert auch wirklich geändert wurde
- [ ] - (12) Einfache Möglichkeit Models freizugeben (z.B. `Model::free()`) für händische Speicheroptimierung
- [ ] - (13) Add `Model::refresh()` to reload the data from database.
- [ ] - (14) Track modifications on the primary key, by keep a copy of the original record.
- [ ] - (15) Out of sync check (https://github.com/contao/core/pull/6131#issuecomment-24012410)
- [ ] - (16) Do not store the database result within the `Model` (https://github.com/contao/core/issues/6182#issuecomment-24652619)
- [ ] - (17) Do not store the database result within the `Collection` (https://github.com/contao/core/issues/6182#issuecomment-24652619)
- [ ] - (18) Check if relations are correctly passed through the registry (https://github.com/contao/core/pull/6131#issuecomment-24726964)

Es gibt noch ein paar Punkte, an denen ich zu knabbern habe:

-----

**(A)** Das erste ist `Model::save(true)` was ja bewirkt, dass ein Model als neuer Record gespeichert wird. Das funktioniert aber in Verbindung mit der Registry ganz schlecht. Das Problem ist halt, dass ich quasi das Objekt re-registrieren müsste, für die neu erstellte ID. Das geht aber ja nicht.

```php
$model = \Model::findByPK(1);
// spl_object_hash($model) == 1
$model->save(true);
// spl_object_hash($model) == 1 müsste aber 2 sein, weil neue ID
```

Normalerweise sollte ein "Klon" so durchgeführt werden:

```php
$modelA = \Model::findByPK(1);
// spl_object_hash($modelA) == 1
$modelB = clone $modelA;
$modelB->save();
// spl_object_hash($modelB) == 2
```

Ganz davon abgesehen, dass durch die Registry man das hier natürlich gar nicht mehr machen kann:

```php
$model = \Model::findByPK(1);
$model->key = 'new value';
$model->save(true);
```

Obwohl man `save(true)` gemacht hat, wird hier natürlich der Originaldatensatz mit der ID 1 gleich mit verändert.

**Lösung:** das `$blnForceInsert` wird gedropt. Die `__clone` löscht bereits den PK von dem neuen Model, d.h. die richtige Variante mit clone ist bereits implementiert.

-----

**(B)** Die Models werden teilweise mit nicht existierenden Werten befüllt. Ein Beispiel ist [`PageModel::findPublishedSubpagesWithoutGuestsByPid`](https://github.com/contao/core/blob/hotfix/3.1.3/system/modules/core/models/PageModel.php#L347) im SELECT werden dort virtuelle Felder erzeugt, die im Model auch verfügbar sind, da dieses ja lediglich auf das Result zugreift. Eigentlich sollte das gar nicht unterstützt werden, um es zu unterstützen mache ich jetzt immer einen Merge mit dem Record, wenn ich ein Model aus der Registry hole. Siehe 35559ab

**Lösung:** derartige virtuellen Felder dürfen nicht über das Query kommen, sondern müssen über getter des Models kommen.

-----

Es gibt sicher noch ein paar Dinge, die ich gerade auf die schnelle nicht berücksichtigt habe.
Außerdem bin ich ja noch nicht fertig wie man an der Checkliste sehen kann ;-)
Trotzdem ist Feedback erwünscht, ich würde mich vor allem über Feedback von @leofeyer freuen, ob das so akzeptabel ist. Ich setze gerne Änderungswünsche um.