Ankündigung

Einklappen
Keine Ankündigung bisher.

Virtual properties in Entities

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Symfony] Virtual properties in Entities

    Hallo,

    das Thema betrifft nicht nur Symfony, sondern auch Doctrine. Folgendes möchte ich realisieren: ich habe eine Entity-Klasse, die wie nachstehend aufgebaut ist:

    PHP-Code:
    <?php

    namespace AppBundle\Entity;

    use 
    Doctrine\ORM\Mapping as ORM;

    /**
     * News
     *
     * @ORM\Table(name="news", options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"})
     * @ORM\Entity
     */
    class News
    {
        
    /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        
    private $id;

        
    /**
         * @var string
         *
         * @ORM\Column(length=255)
         */
        
    private $title;

        
    /**
         * Get id
         *
         * @return integer
         */
        
    public function getId()
        {
            return 
    $this->id;
        }

        
    /**
         * Set title
         *
         * @param string $title
         * @return News
         */
        
    public function setTitle($title)
        {
            
    $this->title $title;

            return 
    $this;
        }

        
    /**
         * Get title
         *
         * @return string
         */
        
    public function getTitle()
        {
            return 
    $this->title;
        }
    }
    Ich benötige zusätzlich den Titel in einer bereinigten Form (slug). Im Laravel-Framework gibt es dazu die Möglichkeit, Funktionen anzulegen, auf die wie Eigenschaften zugegriffen werden kann. Nach langem Googlen habe ich keinen Weg gefunden, der mir sauber erscheint. Gibt es einen sauberen Weg? Oder bleibt nur der folgende Weg:

    Eine Funktion anlegen, die die entsprechende Eigenschaft zurück gibt:

    PHP-Code:
    public function getSlugTitle()
    {
        return 
    $this->get('slugify')->slugify($this->title);

    Wobei ich hier noch dafür sorgen müsste, dass ich auf den Service "slugify" zugreifen kann, was innerhalb von Entites eigentlich nicht gewollt ist, aber natürlich durch Injection machbar wäre... Ich arbeite noch nicht sehr lange mit Symfony (wie man unschwer erkennen kann) und freue mich über Eure Hilfe. Ich benutze Symfony in Version 2.7.

  • #2
    Die Frage ist eher:
    Warum möchtest du das?

    Ein Slug möchte man normalerweise, um eine URL aufzubauen um danach wieder auf besagtes Objekt zugreifen zu können.
    Wenn du den Slug nicht abspeicherst, müsstest du dir erstmal alle Objekte holen, jeden Titel sluggen und dann gucken ob der übergebene Slug gleich ist.

    Nicht dass ich dir das kaputt reden will oder so. Mich interessiert nur, wofür du den Slug brauchst, und ob es nicht einen Grundsätzlich besseren Weg gäbe.
    Zitat von derwunner
    "Ein FISI ist auf gut-deutsch der Netzwerker. Das heißt Du gehst rauß zum Kunden oder auf die Straße und verlegst Leitungen" - derwunner 2015

    Kommentar


    • #3
      Gerne kannst Du mir einen besseren Weg aufzeigen, wenn es einen gibt. Ich freue mich wenn ich dazu lernen kann. Folgendes ist geplant:

      Auf einer Seite werden News-Meldungen ausgegeben. Diese werden gekürzt dargestellt, über einen Link gelangt man zum vollständigen Artikel. Die vollständige Url zum Artikel ist wie folgt aufgebaut:

      Code:
      /id/eine-tolle-neuigkeit
      
      # id = Primärschlüssel / eindeutige ID
      # eine-tolle-neuigkeit = slug
      Jetzt passiert beispielhaft folgendes: Der Artikel wird auf einer externen Seite verlinkt. Währenddessen ändert sich der Titel und damit auch die Url zum vollständigen Artikel:

      Code:
      /id/eine-tolle-neuigkeit-editiert
      Wenn der Benutzer jetzt über den externen Link auf den Artikel gelangt, soll geprüft werden, ob der Slug immer noch korrekt ist. Wenn nicht, soll eine Weiterleitung auf den neuen Link erfolgen:

      Code:
      Neue URL:                /id/eine-tolle-neuigkeit-editiert
      Benutzer kommt von /id/eine-tolle-neuigkeit
      
      Neue URL != URL von Benutzer:
          Weiterleitung zu Neuer URL
      Das ist eigentlich alles, was geplant ist. Der Slug wird also sehr häufig benötigt:

      * Verlinkung zum vollständigen Artikel (im Template)
      * Überprüfen im Controller und zur Weiterleitung

      Wenn sich jetzt irgendwann einmal die Zusammensetzung des Slugs verändert, wäre es schön, wenn die Anpassung nur innerhalb einer Funktion erforderlich wäre und nicht an allen Stellen, wo dieser eventuell neu erstellt wird. Daher meine Idee, das ähnlich wie in Laravel zu lösen.

      Kommentar


      • #4
        Also erstmal:
        Wegen dem Neu erstellen brauchst du dir keine Sorgen machen, wenn du zB. DoctrineExtensions\Sluggable nutzt. Das updated automatisch jedes mal den Slug wenn sich das Objekt ändert.

        In einem Fall wie diesen hier:
        Im Endeffekt ist der Slug ja in diesem Fall, abgesehen davon dass der Nutzer sehen können soll worum es sich bei dem Link handelt, nutzlos, richtig?
        Den Datensatz holst du dir über die ID, nicht über den Slug.
        In so einem Fall, würde ich beim Aufruf eines solchen Datensatzes einfach nur von außen überprüfen, ob das übergebene einer gesluggten Version des Titels gleich ist.

        Wenn nicht, dann leite ich an mich selbst weiter, und ersetze dabei den alten Slug durch den Neuen.

        Schön finde ich die ganze Lösung hier leider nicht, weil das zu zusätzlichen Requests führt. Man könnte auch einen Wert an JS übergeben mit dem neuen Slug, der den alten nur in der URL austauscht.

        Im großen und ganzen ist in diesem ganzen Beispiel aber der Slug nicht bestandteil des Objekts, weswegen ich den Slug-Kram nicht ins Objekt selbst packen würde, sondern von außen erstellen und verwalten würde.

        PS: Meine Variante wäre, beim Erstellen eines Objektes einmalig einen Slug zu generieren. Der wird sich nicht mehr ändern und ist einzigartig. (Von mir aus auch aus ID und Titel zusammengesetzt)
        Diesen benutze ich um auf den Datensatz zuzugreifen. Wenn sich der Titel leicht ändert, sieht man das ja wenn man auf den Link geht. Wenn sich der Inhalt der News mit diesem Slug komplett ändert, finde ich, habe ich eh etwas falsch gemacht.
        Zitat von derwunner
        "Ein FISI ist auf gut-deutsch der Netzwerker. Das heißt Du gehst rauß zum Kunden oder auf die Straße und verlegst Leitungen" - derwunner 2015

        Kommentar


        • #5
          Okay, also lese ich daraus, dass die beste Variante jene wäre, einmalig einen Slug zu speichern und den dann immer zu verwenden und dieser Teil des Objekts wird. Du schreibst, dass man den Slug, da er nicht Teil des Objekts ist, besser von außen behandelt. Daraus interpretiere ich im Umkehrschluss, dass ich überall dort, wo ich den Slug benötige, diesen Erstellen soll und dann damit arbeite?

          Kommentar


          • #6
            Von "benötigen" würde ich hier nicht einmal reden. Benötigen würdest du den Slug, wenn du ihn als Identifier für dein Objekt benutzt.

            So wie ich das verstehe, ist es aber bloß etwas, was hinten an den Link geklatscht wird, aber eigentlich egal ist.

            Da du mit Symfony arbeitest, und warscheinlich dann auch twig benutzt (?), würde ich einfach an den Stellen wo du den Slug ausgeben willst den Titel ausgeben und durch n Slugifier werfen.

            Ich will nicht behaupten dass das die beste Variante ist. Du kannst durchaus natürlich im Objekt selbst eine Funktion bauen, welche dir direkt den Slug zurückgibt.
            Ich halte meine Doctrine-Entitäten nur gerne klein und zu 95% auf das begrenzt, was auch in der DB landet, deswegen würde ich den Slug nicht ins Objekt packen, wenn ich ihn nicht auch wegspeichern wollen würde.

            Wenn ich du die Variante mit dem Speichern nehmen würdest, würde der Slug natürlich Teil des Objekts werden.
            Gleichzeitig ermöglicht das, je nachdem wie du den Slug aufbaust (wenn du noch sowas wie ein Datum mit reinklatscht, oder sogar Datum + Zeit), dass du deine Internen IDs nicht nach außen gibst, und im Endeffekt von außen nur den Slug entgegennimmst, und nach dem in der DB suchst.

            Wofür du dich entscheidest ist letztendlich deine Sache. Ich versuche nur Möglichkeiten aufzuzeigen, und gebe zum Teil meine Meinung dazu ab.
            Zitat von derwunner
            "Ein FISI ist auf gut-deutsch der Netzwerker. Das heißt Du gehst rauß zum Kunden oder auf die Straße und verlegst Leitungen" - derwunner 2015

            Kommentar


            • #7
              Nein, das macht schon alles Sinn was Du sagst. Ich bin in Symfony neu und habe vorher viele andere Frameworks benutzt, die wieder alles anders machen. Ich danke Dir für Deine Meinung und weiß jetzt, was ich zu tun habe

              Vielen Dank.

              Kommentar


              • #8
                Als kleine Anmerkung:

                Ein Slug hat grundlegend zwei mögliche Funktionen:

                Keine ID's zu haben aus denen man auf die Datenbankstruktur schließen kann und URL's Suchmaschinen, bzw. Anwenderfreundlich zu machen.

                Desweiteren sind solche Probleme wie du sie hast schon vielfach implementiert worden.
                Solltest du zu deinem Problem (insofern es sich um Standard Sachen wie z.B. Blog o.ä.) keine Lösungsansätze finden, kannst du dir über dein Problem evtl. Gedanken machen, ob dies denn wirklich ein Problem ist oder nicht, denn scheinbar ist niemand anderes darüber gestolpert
                "Software is like Sex, it's best if it's free." - Linus Torvalds

                Kommentar

                Lädt...
                X