Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entwicklung eines Sichtbarkeits-Filterungs-Systems für wf-Anwendungen #1

Merged
merged 73 commits into from
Apr 18, 2021

Conversation

janopae
Copy link
Member

@janopae janopae commented Apr 14, 2021

@janopae janopae requested a review from mpdude April 14, 2021 11:28
Copy link
Member

@sebastiankugler sebastiankugler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Jano,

die Symfony- und Doctrine-Innereien kann ich nicht beurteilen. Mir fehlt wie oben gesagt in der Readme ein Anwendungsbeispiel, und ich vermute, dass es irgendwo auch noch ein Projekt oder einen Branch gibt, wo man dein Bundle im Einsatz sehen kann. Dazu würde ich mich noch über einen PR freuen.

Außerdem fände ich es gut, wenn du einige Basis-Checks noch einrichtest, z. B. den cs-style-fixer. Auch die Ausführung von Tests wäre natürlich gut, aber dafür musst du die Tests natürlich erstmal hinzufügen. Die Tests werden sicher auch noch zum Verständnis der Anwendung beitragen.

README.md Outdated Show resolved Hide resolved
Copy link
Member

@FabianSchmick FabianSchmick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magst du uns auch deine Dokumentation im Repo verlinken? Finde es vorallem gut, dass du mit echt wenig Code auskommst, habe nicht wirklich was anzumerken (abgesehen von dem was Sebastian bereits anmerkte).

DependencyInjection/services.yaml Outdated Show resolved Hide resolved
Filter/HatBestimmtenWertImSichtbarkeitsfeld.php Outdated Show resolved Hide resolved
Copy link
Member

@MalteWunsch MalteWunsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An ein paar Stellen scheint mir der CS noch nicht ganz rund.
Die Klassen würde ich final machen oder wenn Du Überschreibbarkeit beabsichtigst nichts private, sondern alles protected (nur polish).

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Filter/DoctrineSQLFilter.php Outdated Show resolved Hide resolved

public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
$this->assertSetUpCorrectly();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Korrekt (glaube ich), aber lässt mich sprachlich stolpern.

Annotation/VisibilityColumn.php Outdated Show resolved Hide resolved
@janopae
Copy link
Member Author

janopae commented Apr 15, 2021

@sebastiankugler @mpdude @FabianSchmick @MalteWunsch Was wäre eure Präferenz bezüglich Sprache? Die englischen Begriffe stammen vom Anfang, als ich noch den Größenwahn hatte, dass das ein riesiges Open-Source-Framework wird, das das Problem Sichtbarkeit von Entitäten in Symfony ein für alle Mal löst.

Derzeit glaube ich, dass das vor allem wf-intern genutzt werden wird, es käm also wirklich auf die Präferenz des Teams an.

@sebastiankugler
Copy link
Member

Unsere Grundregel ist, Begriffe aus der Fachwelt des Kunden in deren Sprache zu verwenden, Framework-nahe Begriffe englisch (also z. B. isHauptrolle() statt istHauptrolle()).

Das Konzept der Sichtbarkeit sehe ich an der Grenze zwischen Framework und Fachwelt.

Die @visibility-Annotation gehört für mich zum Framework, sollte englisch sein.

Eine konkrete Sichtbarkeitsregel könnte in der Fachwelt des Kunden leben, also SichtbarWennFreigeschaltet.

Open Source-Repos wollen wir tendenziell komplett englisch halten. Alle Pakete, die wir nicht speziell für einen Kunden schreiben, wollen wir tendenziell open sourcen.

Für mich ist die Unterscheidung nicht "Riesiges Open Source Framework" vs. "Kleine interne Library". Meine Hoffnung wäre, dass es eine kleine Open Source-Library werden könnte.

Fazit: Ich würde hier im Repo alles englisch benennen, es sei denn, es handelt sich um eine Beispielimplementierung für eine kundenspezifische Sichtbarkeitsstrategie (und selbst dann könnte man noch für englisch argumentieren, weil es ja ein englisches Open Source-Repo würde).

Copy link
Member

@sebastiankugler sebastiankugler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mit den Tests sind die Anwendung/Konfiguration und auch die Leistung des Pakets schon ein bisschen verständlicher.

Kommen noch Tests für die eigentliche Filter-Funktionalität?

janopae and others added 8 commits April 15, 2021 15:34
@janopae
Copy link
Member Author

janopae commented Apr 16, 2021

Halte den PR jetzt für mergebar. Ich bitte erneut um approval ;) @mpdude

PS: Ich weiß, dass ich für VisibilityColumnConsideringSQLFilterTest besser die Doctrine Test Infrastructure genutzt hätte. Aber jetzt weiß ich wenigstens, warum ;)

README.md Outdated Show resolved Hide resolved
Tests/Fixtures/EntityWithManyToManyRelationship.php Outdated Show resolved Hide resolved
Tests/Fixtures/EntityWithOneToOneRelationship.php Outdated Show resolved Hide resolved
Tests/Fixtures/Kernel/config.yml Outdated Show resolved Hide resolved
composer.json Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
README.md Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Tests/Filter/VisibilityColumnConsideringSQLFilterTest.php Outdated Show resolved Hide resolved
use Webfactory\VisibilityFilterBundle\Filter\Strategy\FilterStrategy;
use Webfactory\VisibilityFilterBundle\Filter\VisibilityColumnRetriever;

class VisibilityColumnConsideringSQLFilterMock extends SQLFilter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warum eine eigene Mock-Klasse?

Falls die Antwort: "weil VisibilityColumnConsideringSQLFilter final ist" lautet, würde ich in so einer Situation meistens überlegen, VisibilityColumnConsideringSQLFilter zu entfinalisieren oder (IMHO besser) ein Interface für VisibilityColumnConsideringSQLFilter einzuführen und das dann mit PHPUnit zu mocken.

Copy link
Member Author

@janopae janopae Apr 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich bin generell der Meinung, dass die Klasse VisibilityColumnConsideringSQLFilter (wie die meisten Klassen) nicht Teil der Schnittstelle des Bundles sein sollte - nur haben wir im Moment keinen guten Weg, zu kommunizieren, welche Klassen Teil der Schnittstelle sind und welche nicht. Dann könnte man sich IMHO das final sparen. (Ich hätte übrigens nichts dagegen, wenn Klassen per default final wären - aber aktiv dafür sorgen zu müssen, lädt dazu ein, es vereinzelt zu vergessen, und wenn ich alle Klassen final mache außer eine, wirkt das IMHO wie eine Aufforderung zum Beerben - im Gegensatz dazu, wenn ich beerbare Klassen explizit kennzeichnen würde)

Hättest du auch Interesse daran, dass wir fürs Kommunizieren, ob Klassen Teil der Library-Schnittstelle sind, einen Weg finden, und soll ich das als Backender-Gesprächs-Thema auf eine Mittags-Meetings-Karte als Thema setzen?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um zum Thema zurückzukehren: Es gibt eine eigene Mock-Klasse, weil jeder Doctrine-Filter einen Klassennamen braucht. Ohne Klassennamen kann man Filter nicht registrieren, weil Doctrine sie intern erzeugt.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hättest du auch Interesse daran, dass wir fürs Kommunizieren, ob Klassen Teil der Library-Schnittstelle sind, einen Weg finden, und soll ich das als Backender-Gesprächs-Thema auf eine Mittags-Meetings-Karte als Thema setzen?

Die Frage wird selten aufgeworfen, ich weiß nicht, wie groß ich die Antwort machen wollen würde. Sie in offener Runde zu diskutieren, und eine neue Regel zu vereinbaren und lernen scheint mir übertrieben, ich würde mich aber auch nicht sperren. Ich persönlich hab mich bisher mit final/protected durchgewieselt, Symfony deklariert Klassen @internal und ich glaube auch @Api.

Copy link
Member

@mpdude mpdude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sehr schön! 👏🏻 🙌🏻

Ich finde es toll, dass es Dir gelungen ist, das Problem jetzt doch auf ein ganz einfaches und damit gut verständliches Modell runterzubrechen. Die Probleme, die die Doctrine API Dir in den Weg gelegt hat, konntest Du ja letztlich doch ziemlich elegant umgehen.

Viele Kommentare sind nur Kleinigkeiten oder Anmerkungen, die m. E: nicht unbedingt zu Ändeurngen führen müssen. Bin auch so 👍.

Wichtige Punkte:

  • Momentan ist die Filterregel, die angewendet wird, für alle Klassen immer die gleiche. Das sollte man aber m. E. problemlos erweitern können, wenn der Anwendungsfall kommt.
  • Die Initialisierung über das GetResponseEvent wird nicht passieren, wenn man Console Kommandos ausführt.


$filterCollection = $this->entityManager->getFilters();

if (!$filterCollection->has(VisibilityColumnConsideringSQLFilter::NAME)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wäre es auch möglich, das über die Klasse zu erkennen? Nur als Idee, ist auch so 👍.

src/Filter/Strategy/ValueInField.php Show resolved Hide resolved
return $classMetadata->getColumnName($property->getName());
}

private function getVisibilityProperty(ClassMetadata $classMetadata): ?ReflectionProperty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Klitzekleine Anmerkung: find... würde hier IMHO deutlicher machen, dass die in den $classMetadata gesucht wird, und dass es nicht etwa ein Feld (-> Getter) für diese Klasse selbst ist.

src/Filter/VisibilityColumnRetriever.php Show resolved Hide resolved
*/
public function injects_dependencies_into_filter(): void
{
$this->entityManager->getConfiguration()->addFilter(VisibilityColumnConsideringSQLFilter::NAME, VisibilityColumnConsideringSQLFilterMock::class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich verstehe, dass Du hier die Klasse VisibilityColumnConsideringSQLFilter brauchst, weil Du sie über den fest vorgesehenen Filter-Namen registrierst und damit später schauen kannst, ob der Filter richtig konfiguriert wurde. Ein "echtes" Mock-Objekt hat keinen vorhersehbaren Klassennamen (?) und kann wahrscheinlich auch nicht von Doctrine erzeugt werden.

Martin Fowlers Typologie (https://martinfowler.com/articles/mocksArentStubs.html) würde diese Klasse eher als "Spy" bezeichnen, nicht als "Mock".

Aber noch eine andere Überlegung:

Der Test hier ist sowieso schon ein KernelTestCase, d. h. ein Integrationstest, der ja schon darauf basiert, dass der OnRequestDependencyInjector richtig im DIC verdrahtet und konfiguriert ist.

Kannst du da nicht auch direkt (habe mir nicht überlegt, wie...) schauen, ob der VisibilityColumnConsideringSQLFilter korrekt eingerichtet wurde?

use RuntimeException;
use Webfactory\VisibilityFilterBundle\Filter\Strategy\FilterStrategy;

final class VisibilityColumnConsideringSQLFilter extends SQLFilter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...SQLFilter oder SqlFilter?

tests/Filter/Strategy/ValueInFieldTest.php Outdated Show resolved Hide resolved
/**
* @test
*/
public function filter_gets_applied_on_findAll_method_of_repository(): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auf der einen Seite finde ich es schön, diese Tests hier einfach zu haben, weil sie dokumentieren, was passiert.

Auf der anderen Seite zeigen sie mit ..._on_findAll_..., on_custom_DQL, ... etc auch nur, was man doch eigentlich von Haus aus von einem Doctrine ORM Filter erwarten dürfte?

Copy link
Member Author

@janopae janopae Apr 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich finde die Tests auch gut zur Dokumentation - bei Doctrine ist das alles nur sehr spärlich und abstrakt dokumentiert. Ich war teilweise selbst sehr gespannt, ob und wie die Tests funktionieren werden.

Ich würde mir sogar noch eher wünschen, dass es für den One-To-One-Fall noch einen Extra-Test mit Lazy-Loading gibt - denn wie sich der Filter bei One-To-One-Beziehungen mit und ohne Lazy-Loading verhält, ist AFAIK nirgendwo dokumentiert und kann nur geraten werden. Im Falle von Eager Loading ist die Beziehung nämlich null, mit Lazy Loading hat man erst mal ein Proxyobjekt und beim Versuch, es anzusprechen, eine NotFoundException.

Ich glaube auch nicht, dass Doctrine all diese Fälle durchtestet, entsprendend wären wir im Falle eines Falles ggf. die ersten, die es merken würden ;)

@janopae janopae merged commit 2983bfc into master Apr 18, 2021
@janopae janopae deleted the development branch April 18, 2021 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants