2016-05-24 10 views
1

私は、人々が先生と時間を予約できるWebアプリケーションを構築しています。現時点では、時間がユーザカートに追加されると、誰もこの時間が利用可能であるか、カートに追加することはできません。Laravel 5.2のキューに入れられたジョブからセッションデータにアクセスしようとしています。

私はdarryldecode's shopping cartを使用していますが、セッションが持続する間(2時間)アイテムが保存されています。ただし、追加してから5分後にアイテムが自動的に削除されるようにしたいと思います。これを達成するために、私は5分の遅れで待ち行列に入れられた仕事をセットアップしました。

私の問題は、ジョブが5分後にもう一度他のユーザーに見えるように時刻を変更しますが、カートのデータが保存されているセッションにアクセスできないと思われるためカートから削除しません。誰かが、キューに入れられたジョブからセッションに保存されているカートデータにどのようにアクセスするのかアドバイスできますか?おかげさまで

これは、すべてがカートを除いて動作しますが、仕事のためのコードである::削除()

namespace App\Jobs; 

use App\Jobs\Job; 
use Illuminate\Queue\SerializesModels; 
use Illuminate\Queue\InteractsWithQueue; 
use Illuminate\Contracts\Queue\ShouldQueue; 
use App\TimeSlot; 
use Cart; 

class RemoveTimeSlotFromCart extends Job implements ShouldQueue 
{ 
    use InteractsWithQueue, SerializesModels; 

    public $timeSlot; 

    /** 
    * Create a new job instance. 
    * 
    * @return void 
    */ 
    public function __construct(TimeSlot $timeSlot) 
    { 
     $this->timeSlot = $timeSlot; 
    } 

    /** 
    * Execute the job. 
    * 
    * @return void 
    */ 
    public function handle() 
    { 
     $timeSlot = $this->timeSlot; 
     if ($timeSlot->booked == 0 && $timeSlot->in_basket == 1) { 
      $timeSlot->in_basket = 0; 
      $timeSlot->save(); 
      Cart::remove($timeSlot->id); 
     } 
    } 
} 
+0

:更新次に、溶液を次のようになります。これは、すべてあなたの待ち行列に入れられた仕事によって処理される必要があります - あなたは現在どのようにデータベースからそれをクリアーしているのですか? –

+0

「開かれた予約」の意味がわからない、ごめんなさい。現在、カートに時間が追加されると、データベース内で 'in_cart'の値が1に設定され、待機中のジョブによって5分後に自動的に0に戻されます。問題は、仕事にアクセスすることができないように見えるため、職場内からカートファサードを使用できないということです。おそらくそれはできますし、私は何か間違っていますか? – jgjr

+0

あなたの仕事のコードを共有できますか? –

答えて

0

Cronジョブは、新しいセッションで実行されます。カートライブラリ(darryldecode/laravelshoppingcart)はセッションベースです。セッションデータを変更するのは非常に難しいでしょう(現在のユーザーのブラウザ起動セッションからのセッションデータではない場合、セッションドライバによっては不可能かもしれません)。具体的には、次の行になります。

Cart::remove($timeSlot->id); 

カートモデルでは、どのカートからアイテムを削除するかを知る方法がありません。 UXの観点からは、ユーザに、タイムスロットがとにかく落とされたというフィードバックを与えたいと思うでしょう。したがって、各ページの描画(または非同期的にjs)で削除のためのチェックを書くことは予期しない作業であってはなりません。

各ページの描画では、訪問者のカート内の各アイテムをループします。私はcart :: :: add(...)をどのように構築して一意のカートアイテムIDを扱うかわからないので、これはタイムスロットIDがカートアイテムIDと一致すると仮定しています。

$removed = []; 
foreach(Cart::getContent() as $item) { 
    $timeSlot = timeSlot::findOrFail($item->id); 
    if($timeSlot->in_basket === 0) { 
     Cart::remove($timeSlot->id); 
    } 
} 
if(count($removed)) { 
    //inject a HTML/JS popup message like "your timeslot has been dropped because you're too slow 
    //or pass it along into the request 
    $request->session()->flash('slots-dropped', $removed); 
} 

これは、理想的にはcartUpdateミドルウェア内で処理されますが、サイトの複雑さに応じて、コントローラの中に行うことができます。

[編集] データベース構造の結果、上記の解決策に欠陥があります。ユーザーAはタイムスロットを予約しますが、チェックアウトウィンドウ内ではチェックアウトしません。タイムスロットは「カートに入れません」状態に戻ります。ユーザーAが通知する数分前に一方、ユーザBは、利用可能なタイムスロットのプールに戻された後、ユーザAが別のページを見る前に(そしてカートが適切なメッセージで更新された後)、同じタイムスロットを見る。この時点で、タイムスロットは人Bのカート内にある。ページリフレッシュが、Person Aのタイムスロットが「any」カートにあるかどうかを調べるときに、「$ timeslot-> in_basket == 1であるためカート内にあります」と表示されます。人物Aはチェックアウトを継続し、人物Bのカート内にあってもタイムスロットを取得する。

これはかなり簡単です。in_basketのデータ型をbooleanから文字列に変更し、カートに追加するたびにsession_idの値を代入します。カートクラスで見ることができますが、おそらくapp() - > session-> get( 'session')です。 var_dump(app() - > session-> all())を使って、これをリファクタリングする前に正しいかどうかを確認することができます。あなたはカートからそれらを解放することができますので、あなたがそれらをゴミ箱前に、開いている予約の一覧を取得したいと思う

$removed = []; 
foreach(Cart::getContent() as $item) { 
    $timeSlot = timeSlot::findOrFail($item->id); 
    if($timeSlot->in_basket !== app()->session->get('session')) { 
     Cart::remove($timeSlot->id); 
    } 
} 
if(count($removed)) { 
    //inject a HTML/JS popup message like "your timeslot has been dropped because you're too slow 
    //or pass it along into the request 
    $request->session()->flash('slots-dropped', $removed); 
} 
+0

ありがとう!あなたの答えは非常に有用であり、私は本当にあなたがそれを書くために取った時間を感謝します。これは、サイトに滞在するユーザーに最適なソリューションです。ユーザーがカートに何かを追加してすぐにサイトを離れる場合は、何をお勧めしますか?セッションを5分後に終了する必要がありますか? – jgjr

+0

サイトを離れた場合、ナチュラルセッションの有効期限を使用してセッションが期限切れになります。使用しているセッションドライバによって異なりますが、デフォルトでは2時間になることが多く、カートはメモリから消えます。誰かがあなたのサイトを離れて2時間以内に戻ってくると、タイムスロットがまだ残っているカートが残っていると思われるかもしれません。このような状況を別の方法で処理する必要はありません。すべて同じロジックに従います。各ページの描画で、セッション/カートの有無を確認し、タイムスロットが無効になっている場合はカートを更新します。 –

関連する問題