Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Laravel: route-modeol-binding Redirect

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Laravel: route-modeol-binding Redirect

    Hallo,

    folgende Situation:

    Ich habe URLs nach dem folgenden Schema:

    www.example.invalid/posts/1-mein-erster-post
    www.example.invalid/posts/2-mein-zweiter-post

    Als PHP-Framework wird zur Entwicklung laravel eingesetzt. Dort gibt es die Möglichkeit, an Routen ein Model zu binden, sodass automatisch ein Fehler 404 geworfen wird, wenn der Beitrag (Model) nicht existiert. Jetzt gibt es die Überlegung, dass es ja sein kann, dass sich im Nachhinein die URL eines Beitrags verändert, der Beitrag aber noch existiert, aber noch mit der alten Url irgendwo im Web verlinkt ist.

    Beispiel:

    Url zu Beitrag lautet: www.example.invalid/posts/1-mein-erster-post
    Im Nachhinein wird der Link für den Beitrag verändert: 1-mein-erster-post-editiert

    Was sich niemals ändert, ist die ID, die zu Beginn jedes Links gesetzt wird. Die alte Url wird also ihre Gültigkeit nicht verlieren. Jetzt ist aber natürlich gewollt, dass hinter der ID nicht jeder x-beliebige Text zur Verlinkung stehen darf. Sonst könnte man auch Folgendes verlinken:

    http://www.example.invalid/posts/1-e...seite-ist-doof

    Die Idee ist also, zusätzlich zu prüfen, ob neben der ID auch der Text im Link (hierbeit handelt es sich immer um den Titel des Beitrags) stimmt. Wenn nicht, soll eine Weiterleitung zum korrekten Beitrag erfolgen.

    Hierfür habe ich in Laravel eine entsprechende Route erstellt, die an ein Model gebunden wurde:

    PHP-Code:
    Route::get('/posts/{Post}', [
        
    'as'     => 'post-detail',
        
    'uses'     => 'PostController@getDetail'
    ]);

    Route::bind('Post', function($slug$route)
    {
            
    // ID des Beitrags und Titel extrahieren
        
    sscanf($slug'%d-%s'$id$slugTitle);

        
    $postPost::with('user')
                ->
    where('id'$id)
                ->
    where('active'1)
                ->
    first(['id''user_id''date_create''title''content']);

        
    // Händisch 404 werfen, da Laravel das jetzt nicht mehr von alleine kann
        
    if(!$post) { App::abort(404); }

        
    // Hat sich der Titel geändert? Dann sag dem Nutzer, dass der Beitrag an sich
            // noch existiert, aber unter einer neuen URL zu erreichen ist und leite um.
        
    if($slugTitle != Str::slug($news->title))
        {
                    
    // HIER LIEGT DAS PROBLEM
                    // Wie sage ich Laravel, dass der Beitrag unter der neuen URL erreichbar ist?
            
    App::abort(302);
            
    Redirect::to('/posts/1-mein-erster-post-editiert');
        }

        return 
    $post;
    }); 
    Die Frage an alle, die ein ähnliches Problem hatten oder wissen, wonach ich suchen muss: Laravel erwartet als Rückgabewert eine Instance von Model Post, sodass ich nicht einfach ein Redirect machen kann. Aber auch das App::abort() scheint nicht zu wirken.

    Habe ich einen grundsätzlichen Fehler im Design? Gibt es dafür eine simple Lösung?

  • #2
    Benutze dafür Filter. Ist ungetestet.

    PHP-Code:

    //überlass das dem Router
    //sscanf($slug, '%d-%s', $id, $slugTitle);

    Route::get('/posts/{User}-{title}', [
        
    'as' => 'post-detail',
        
    'uses' => 'PostController@getDetail',
        
    'before' => 'post_redirect'
    ]);


    Route::filter('post_redirect', function( $route$request) {
        
    $id $route->getParameter('User')->getId();
        
    $title $route->getParameter('title');

        
    //@Todo: checks
        
    if ($title <> 'title_edited') {
            return 
    Redirect::route('post-detail', array('User' => $id'title' => 'title_edited'), 302);
        }
    }); 
    PHP-Code:
    App::abort(302); 
    Das ist für Fehler(4xx / 5xx) gedacht.

    Kommentar


    • #3
      Zitat von Dam Beitrag anzeigen
      Das ist für Fehler(4xx / 5xx) gedacht.
      Danke für den Hinweis und den Denkanstoß. Funktioniert super! Vielen vielen Dank! Wieder was gelernt.

      Kommentar

      Lädt...
      X