text:
<repo_name>go9/steamgm<file_sep>/resources/views/users/profile.blade.php
@extends('main')

@section('title')

@section('content')

    @if(Auth::check())
@section('actionbar-contents')

        <button class="dropdown-item">
            Hello!
        </button>
        <button class="dropdown-item" onclick="startConversation()">
            Start Conversation
        </button>

    @if(Auth::user()->checkRole("admin"))
    @endif

@endsection

@endif

        {{$user->name}}
        @if($user->checkSteam())
            {!! App\Icon::find("check")->wrap(["color" => "#90C2E7", "title" => "Verified with Steam"]) !!}
        @endif
        avatar !!}">

@endsection
<file_sep>/app/Http/Controllers/MessageController.php
<?php

namespace App\Http\Controllers;

use App\Conversation;
use App\Message;
use App\User;

use App\Events\MessagePosted;
use App\Events\ConversationPosted;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Auth;
use View;

class MessageController extends Controller
{

    public function __construct(){

    }

    public function index(){
        return view("messages.index");
    }

    public function createConversation(Request $request){
        $this->validate($request, [
            "user_ids.*" => "numeric"
        ]);

        // check if these two users already have a conversation

        $users = [];
        foreach($request->user_ids as $user_id){
            if(($user = User::find($user_id))){
                $users[] = $user;
            }
            else{
                return ["success" => false];
            }
        }

        $conversation_id = array_intersect(
            $users[0]->conversations->pluck("id")->toArray(),
            $users[1]->conversations->pluck("id")->toArray()
        );

        if(sizeof($conversation_id) > 0){
            $conversation = Conversation::find($conversation_id[0]);
        }
        else{
            $conversation = new Conversation();
            $conversation->save();
        }

        foreach($users as $user){
                $conversation->users()->syncWithoutDetaching($user);
        }

        event(new ConversationPosted($users[0]));
        event(new ConversationPosted($users[1]));

        return [
            "success" => true,
            "data" => [
                "conversation" => $conversation,
                "conversation_id" => $conversation_id
            ]
        ];
    }

    public function getUsersConversations(Request $request){

        if(Auth::check()){
            return [
                "success" => true,
                "data" => [
                    "user" => Auth::user(),
                    "test" => true,
                    "conversations" => Auth::user()->conversations->sortByDesc("most_recent_message_timestamp")->load("messages", "users")
                ]
            ];
        }

        return [
            "success" => false
        ];

    }

    public function insertUserIntoConversation(Request $request){
        $this->validate($request, [
            "user_id" => "required|numeric",
            "conversation_id" => "required|numeric"
        ]);

        if($conversation = Conversation::find($request->conversation_id)){
            if(($user = User::find($request->user_id))){
                $conversation->users()->syncWithoutDetaching($user);
            }

            return [
                "success" => true,
                "data" => [
                    "conversation" => $conversation,
                    "user" => $user
                ]
            ];
        }

        return [
            "success" => false,
            "data" => $request->only(["user_id", "conversation_id"])
        ];

    }

    public function createMessage(Request $request){
        $this->validate($request, [
            "user_id" => "required|numeric",
            "conversation_id" => "required|numeric",
            "message" => "required|string"
        ]);

        if( ($conversation = Conversation::find($request->conversation_id)) && ($user = User::find($request->user_id)) ){
                $message = Message::create(
                    [
                        "user_id" => $request->user_id,
                        "conversation_id" => $request->conversation_id,
                        "message" => $request->message
                    ]
                );

            event(new MessagePosted($message, $user));

            return [
                "success" => true,
                "data" => [
                    "conversation" => $conversation,
                    "user" => $user,
                    "message" => $message
                ]
            ];
        }

        return [
            "success" => false,
            "data" => $request->only(["user_id", "conversation_id", "message"])
        ];

    }

    // OLD

//    public function createConversationWithMessage(Request $request){
//        $this->validate($request, [
//            "from_user" => "required|numeric",
//            "to_user" => "required|numeric",
//            "message" => "required|string"
//        ]);
//
//        // Create conversation
//        $conversation = Conversation::where("user_id", $request->from_user);
//
//        // Add users to conversation
//        foreach([$request->from_user, $request->to_user] as $user_id){
//            if(($user = User::find($user_id))){
//                $conversation->users()->syncWithoutDetaching($user);
//            }
//            else{
//                return false;
//            }
//        }
//
//        dd($conversation);
//
//        // Create message
//        $message = Message::create(
//            [
//                "user_id" => $request->from_user,
//                "conversation_id" => $conversation->id,
//                "message" => $request->message
//            ]
//        );
//
//        event(new MessagePosted($message, $user));
//
//        // redirect to messages
//        return redirect(route("/messages"));
//
//    }

//    public function sendNewMessage(Request $request){
//        $this->validate($request, [
//            "message" => "required|string",
//            "user_id" => "required|numeric"
//        ]);
//
//        // Check if we already have a conversation
//
//        $convo = Conversation::where("user_one",Auth::user()->id)->where("user_two", $request->user_id)->first();
//        if($convo == null){
//            $convo = Conversation::where("user_one",$request->user_id)->where("user_two", Auth::user()->id)->first();
//        }
//        if($convo == null){
//            $convo = new Conversation();
//            $convo->user_one = Auth::user()->id;
//            $convo->user_two = $request->user_id;
//            $convo->save();
//        }
//
//
//
//
//        $message = new Message();
//        $message->message = $request->message;
//        $message->user_id = Auth::user()->id;
//        $message->conversation_id = $convo->id;
//        $message->save();
//
//        return redirect()->action("MessageController@index");
//
//
//
//    }
//
//    public function sendMessage(Request $request){
//        $this->validate($request, [
//            "conversation_id" => "required|numeric",
//            "message" => "required|string",
//            "user_id" => "required|numeric"
//        ]);
//
//        $conversation = Conversation::find($request->conversation_id);
//        if(!$conversation){
//            return ["success" => false];
//        }
//
//        $message = new Message();
//        $message->message = $request->message;
//        $message->user_id = $request->user_id;
//        $message->conversation_id = $request->conversation_id;
//        $message->save();
//
//        $conversation->messages()->save($message);
//
//        return [
//            "success" => true,
//            "data" => [
//                "conversation" => $conversation->load("messages", "user_one", "user_two"),
//                "message" => $message
//            ]
//        ];
//    }
//
//    public function getConversation(Request $request){
//        $this->validate($request, [
//            "conversation_id" => "required|numeric",
//        ]);
//
//        $conversation = Conversation::find($request->conversation_id);
//        if(!$conversation){
//            return ["success" => false];
//        }
//
//        return [
//            "success" => true,
//            "data" => [
//                "conversation" => $conversation->load("messages", "user_one", "user_two"),
//            ]
//        ];
//    }
//
//    public function getConversations(Request $request){
//        $this->validate($request, [
//            "user_id" => "numeric",
//        ]);
//
//        return [
//            "success" => true,
//            "data" => [
//                "conversations" =>
//                    Conversation::where("user_one", Auth::user()->id)
//                    ->orWhere("user_two", Auth::user()->id)
//                    ->get()
//                    ->load("messages", "user_one", "user_two"),
//                "user" => Auth::user()
//            ]
//        ];
//
//
//    }

}<file_sep>/app/Icon.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Icon extends Model
{
    public $incrementing = false;
    public $timestamps = false;

    public function wrap($style = []){

        // get the color
        if(!isset($style['color'])) {
            $style['color'] = $this->attributes['default_color'] ? $this->attributes['default_color'] : "black";
        }

        // get the size
        if(!isset($style['size'])) {
            $style['size'] = $this->attributes['default_size'] ? $this->attributes['default_size'] : "";
        }

        // Check if the id is set
        $style["id"] = isset($style["id"]) ? "id='{$style['id']}'" : null;
        $style["title"] = isset($style["title"]) ? $style["title"] : $this->attributes['name'];

        return "attributes['id']} {$style['size']}'
                style='color:{$style['color']}'
                title='{$style["title"]}'
                aria-hidden='true'>";
    }
}
<file_sep>/resources/assets/js/components/MessengerUser.vue

<template>

                {{ conversation.users.friend.name}}

                 0 && messages[messages.length-1].fromUser ? icons.from : icons.to" aria-hidden='true'>
                {{messages.length > 0 ? messages[messages.length-1].message : ""}}

                <time
                        v-bind:class="conversation.messages.length > 0 ? 'need_to_be_rendered' : ''"
                        v-bind:datetime="conversation.messages.length > 0 ? conversation.messages[conversation.messages.length -1].created_at.replace(' ', 'T')+ 'Z' : '0'">
                </time>

</template>

<file_sep>/resources/views/settings/icons.blade.php
@extends('settings.index')

@section('settings-content')

@section('actionbar-contents')
    @parent

Icon Actions

    <button class="dropdown-item" type="button" data-toggle="modal" data-target="#new-icon-modal">
        New Icon
    </button>

@endsection

Icon Manager

            There are {!! count($icons) !!} icons in the database.

            {!! App\Icon::find("font-awesome")->wrap() !!}

            ID
            Name
            Color
            Size

        @foreach($icons as $icon)

                {!! $icon->id !!}
                {!! $icon->name !!}
                {!! $icon->default_color !!}
                {!! $icon->default_size !!}
                {!! $icon->wrap(["size" => ""]) !!}

                    <button class="btn-empty"
                            style="text-align:center;font-size: 1em;padding:0px;"
                            type="button"
                            data-toggle="modal"
                            data-target="#edit-icon-modal"
                            data-id="{!! $icon->id !!}"
                            data-name="{!! $icon->name !!}"
                            data-color="{!! $icon->default_color !!}"
                            data-size="{!! $icon->default_size !!}">
                        {!! App\Icon::find("pencil-square-o")->wrap() !!}
                    </button>

        @endforeach

Icon Creator

                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    ×
                </button>

            <form id="new-icon-form" method="POST" action="{!! action("IconController@store") !!}">
                {!! csrf_field() !!}

Preview

                    <input class="form-control" name="id" oninput="refreshPreview(0);">
                    <input class="form-control" name="name" oninput="refreshPreview(0);">
                    <input class="form-control" name="default_color" oninput="refreshPreview(0);">

                    <select name="default_size" class="form-control" oninput="refreshPreview(0);">
                        <option value="default">Default</option>
                        <option value="fa-lg">fa-lg(133%)</option>
                        <option value="fa-2x">fa-2x(200%)</option>
                        <option value="fa-3x">fa-3x(300%)</option>
                        <option value="fa-4x">fa-4x(400%)</option>
                        <option value="fa-5x">fa-5x(500%)</option>
                    </select>

                    <button form="new-icon-form" type="submit" class="btn btn-secondary">
                        Continue
                    </button>

            </form>

Icon Editor

                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    ×
                </button>

            <form id="icon-form" method="POST" action="{!! action("IconController@update") !!}">
                {!! csrf_field() !!}

Preview

                    <input type="hidden" id="form-old-id" name="old_id">
                    <input class="form-control" id="form-id" name="id" oninput="refreshPreview(1);">
                    <input class="form-control" id="form-name" name="name" oninput="refreshPreview(1);">
                    <input class="form-control" id="form-color" name="default_color" oninput="refreshPreview(1);">

                    <select id="form-size" name="default_size" class="form-control" oninput="refreshPreview(1);">
                        <option value="default">Default</option>
                        <option value="fa-lg">fa-lg(133%)</option>
                        <option value="fa-2x">fa-2x(200%)</option>
                        <option value="fa-3x">fa-3x(300%)</option>
                        <option value="fa-4x">fa-4x(400%)</option>
                        <option value="fa-5x">fa-5x(500%)</option>
                    </select>

                    <button form="icon-form" type="submit" class="btn btn-secondary">
                        Continue
                    </button>

            </form>

@endsection

<file_sep>/app/User.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

use App\Role;

class User extends Authenticatable
{
    use Notifiable;

    public $catalogs = [
        "scanned" => false,
        "inventory" => [],
        "library" => [],
        "wishlist" => []
    ];

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    public function purchases()
    {
        return $this->hasMany('App\Purchase');
    }

    public function games(){
        return $this->belongsToMany("App\Game");
    }

    public function conversations(){
        return $this->belongsToMany("App\Conversation");
    }

    public function messages(){
        return $this->hasMany("App\Message");
    }

    public function library()
    {
        if ($this->catalogs["scanned"] == false) {
            $this->catalogs();
        }

        return Game::whereIn("id", $this->catalogs["library"]);
    }

    public function inventory()
    {
        if ($this->catalogs["scanned"] == false) {
            $this->catalogs();
        }
        return Game::whereIn("id", $this->catalogs["inventory"]);
    }

    public function wishlist(){
        if ($this->catalogs["scanned"] == false) {
            $this->catalogs();
        }
        return Game::whereIn("id", $this->catalogs["wishlist"]);
    }

    public function isIn($game_id, $catalog)
    {
        // Verify that catalogs was scanned
        if ($this->catalogs["scanned"] == false) {
            $this->catalogs();
        }

        if (sizeof($this->catalogs[$catalog]) > 0 && in_array($game_id, $this->catalogs()[$catalog])) {
            return true;
        } else {
            return false;
        }
    }

    public function catalogs()
    {
        // Check if we scanned already
        if ($this->catalogs["scanned"] == false) {
            // Get all the purchases (for library and inventory)
            foreach ($this->purchases as $purchase) {
                // Go through the purchases' items
                foreach ($purchase->games as $game) {
                    // Check if the game is available
                    if ($game->pivot->availability == -1) {
                        if (!in_array($game->id, $this->catalogs["library"])) {
                            $this->catalogs["library"][] = $game->id;
                        }
                    }
                    if ($game->pivot->availability == 0) {
                        if (!in_array($game->id, $this->catalogs["inventory"])) {
                            $this->catalogs["inventory"][] = $game->id;
                        }
                    }
                }
            }

            // Get wishlist
            foreach($this->games as $game){
                $this->catalogs["wishlist"][] = $game->id;
            }

            // Set scanned to true
            $this->catalogs["scanned"] = true;
        }

        return $this->catalogs;
    }

    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }

    public function checkRole($role){
        return $this->roles()->where("name",$role)->exists() ? true : false;
    }

    public function attachRole($role){
        $this->roles()->attach(Role::where("name", $role)->first());
        return $this;
    }

    public function detachRole($role){
        $this->roles()->detach(Role::where("name", $role)->first());
        return $this;
    }

    public function checkSteam(){
        return $this->attributes["steamid"] == null ? false : true;
    }
}
<file_sep>/resources/assets/js/components/MessengerMessage.vue

<template>

            {{ message.message}}

</template>

<file_sep>/resources/views/tools/updatedb.blade.php
@extends('main')
@section('title', " | Update Database")
@section('content')

Update Database

        There are {!! count($games) !!} appid's remaining.

        Number of games added:
        <input id="counter" value="0">

    <button class="btn" id="start">Start</button>
    <button class="btn" id="stop">Stop</button>

                Appid
                Name
                Type
                Message

@endsection<file_sep>/resources/views/games/index.blade.php
@extends('main')

@section('title')

@section('content')

        @include("games.games_printer", ["games" => $games, "settings" => ["print_advanced" => true]])

        @if(count($games) == 0)

                Your search did  not return any matches.

                Suggestions:

Make sure all words are spelled correctly.

Try different keywords.

Try more general keywords.

Try fewer keywords.

Remove filters

        @endif
@endsection
<file_sep>/resources/views/partials/_head.blade.php
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>
    SteamGM
    @yield("title")
</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="<KEY>" crossorigin="anonymous">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<link href="https://fonts.googleapis.com/css?family=Fjalla+One|Ubuntu|Signika" rel="stylesheet">

<link rel="stylesheet" href="/lightslider/src/css/lightslider.css">

<link rel="stylesheet" href="/lightgallery/src/css/lightgallery.css">

<link rel="stylesheet" href="/css/normalize.css">
<link rel="stylesheet" href="/css/bootstrap_override.css">
<link rel="stylesheet" href="/css/styles.css">

<file_sep>/resources/views/bundles/index.blade.php
@extends('main')

@section('title', ' | Bundles')

@section('content')

    @if(Auth::check() && Auth::user()->checkRole("admin"))
        @section('actionbar-contents')
            <button class="dropdown-item"
                    type="button"
                    data-toggle="modal"
                    data-target="#bundle-modal">Add new bundle
            </button>

        @endsection
    @endif

    {{-- Print the bundles --}}
    @foreach($bundles as $bundle)

            {{-- Print the bundle title --}}

                        id}}">{{$bundle->name}}
                        {!! $bundle->stores->name !!}

                        @include("games.games_printer", ["games" => $bundle->games, "settings" => ["print_advanced" => false, "display_type" => "grid"]])

    @endforeach

        {{$bundles->links("vendor.pagination.bootstrap-4")}}

@endsection

Add New Bundle

                <form class="form" id="submit-bundle-form" method="POST" action="{{route('bundles.store')}}">
                    {{ csrf_field() }}

                        Name

                            <input type="text" class="form-control" name="name" id="submit-bundle-name">

                        Store

                            <select class="form-control" name='store_id' data-live-search="true">
                                @foreach(App\Store::all() as $store)
                                    <option value="{{$store->id}}">{{$store->name}}</option>
                                @endforeach
                            </select>

                        Date Started

                            <input type="date" class="form-control" name="date_started" id="submit-bundle-start-date">

                        Date Ended

                            <input type="date" class="form-control" name="date_ended" id="submit-bundle-end-date">

                        Notes

                            <textarea type="text" class="form-control" name="notes" id="submit-bundle-notes"></textarea>

                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button for="submit-bundle-form" type="submit" class="btn btn-primary">Submit</button>

            </form>

<file_sep>/resources/views/main.blade.php
<!DOCTYPE html>

@yield('stylesheets')
@yield('scripts')

    @include("partials._head")

    @include("partials._nav")

                <button class="btn btn-sm btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton"
                        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Actions
                </button>

                    @yield("actionbar-contents")

            @include('partials._messages')

        @yield("content")

    @include("partials._footer")

<file_sep>/database/migrations/2017_06_16_221715_create_games_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGamesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('games', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name')->nullable();
            $table->string('type')->default("unknown");
            $table->boolean('public')->default(-1);

            // external skus
            $table->integer('steam_id');
            $table->integer('g2a_id')->nullable();

            // Descriptions
            $table->text('description')->nullable();
            $table->text('short_description')->nullable();
            $table->text('about_the_game')->nullable();

            // Platforms
            $table->boolean('platform_windows')->nullable();
            $table->boolean('platform_mac')->nullable();
            $table->boolean('platform_linux')->nullable();

            // System Req's
            $table->text('req_win_min')->nullable();
            $table->text('req_win_rec')->nullable();
            $table->text('req_mac_min')->nullable();
            $table->text('req_mac_rec')->nullable();
            $table->text('req_lin_min')->nullable();
            $table->text('req_lin_rec')->nullable();

            // Misc
            $table->text('reviews')->nullable();
            $table->text('website')->nullable();
            $table->text('legal_notice')->nullable();
            $table->string('release_date')->nullable();
            $table->boolean('is_free')->nullable();
            $table->integer('full_game')->nullable(); // For DLC
            $table->integer('required_age')->nullable();
            $table->text('support_url')->nullable();
            $table->string('support_email')->nullable();
            $table->string('external_account')->nullable();
            $table->string('controller_support')->nullable();

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('games');
    }
}
<file_sep>/resources/views/games/show.blade.php
@extends('main')

@section('title', " | $game->name")

@section('content')

    @if(Auth::check())
        @section('actionbar-contents')
            <button class="dropdown-item" type="button" data-toggle="modal" data-target="#bundle-modal">
                Add to Purchases
            </button>

            <form method="post" action="{{action("GameController@updateWishlist")}}">
                {{ csrf_field() }}
                <input type="hidden" name="game_id" value="{!! $game->id !!}">
                <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">

                @if(Auth::user()->isIn($game->id, "wishlist"))
                    <button class="dropdown-item">
                        Remove from Wishlist
                    </button>

                @else
                    <button class="dropdown-item">
                        Add to Wishlist
                    </button>
                @endif
            </form>

            @if(Auth::user()->checkRole("admin"))
            @endif

        @endsection
    @endif

                    {{$game->name}}
                @if(Auth::user())
                        @if(Auth::user()->isIn($game->id, "inventory"))
                            {!! App\Icon::find("archive")->wrap() !!}
                        @endif

                        @if(Auth::user()->isIn($game->id, "library"))
                            {!! App\Icon::where("name","Library")->first()->wrap() !!}
                        @endif

                            @if(Auth::user()->isIn($game->id, "wishlist"))
                                {!! App\Icon::where("name","Wishlist")->first()->wrap() !!}
                            @endif
                    @endif

            @php($counter = 0)
            @foreach($game->movies as $movie)
                @php($counter++)

                    <video class="lg-video-object lg-html5" controls preload="none">
                        <source src="{{$movie->webm_hd}}" type="video/mp4">
                        Your browser does not support HTML5 video.
                    </video>

            @endforeach

            {{-- Display The games images--}}

headerImage()->url}}"
                            data-thumb="{{$game->headerImage()->url}}">
                        headerImage()->url}}"/>

                    @php($counter = 0)
                    @foreach($game->movies as $movie)
                        @php($counter++)

thumbnail}}"
                                data-thumb="https://c3metrics.com/wp-content/uploads/2016/08/feature-video-thumbnail-overlay.png"
                                data-html="#video-{{$counter}}">
                            thumbnail}}"/>

                    @endforeach
                    @foreach($game->screenshots as $screenshot)

url}}"
                                data-thumb="{{$screenshot->thumbnail}}">
                            url}}"/>

                    @endforeach

                {{-- Display The games description--}}

                    {!! strip_tags($game->description,"
") !!}

                <button class="btn btn-secondary"
                        style="width:100%;"
                        onclick="$('#game_description').fadeToggle('fast')">
                    Toggle description
                </button>

        @if(Auth::check() && Auth::user()->checkRole("G2a"))

                    @php
                        $data = ["dates" => [], "prices" => [], "stores" => []];
                        foreach($game->prices->sortByDesc("created_at") as $result){
                            if($result->pivot->store_id ==  resolve("App\External\G2aApi")->getStore()->id){
                                $data["dates"][] = strtotime($result->pivot->created_at);
                                $data["prices"][] = (float)$result->pivot->price;
                                $data["stores"][] = $result->pivot->store_id;
                            }
                        }

                        $g2a = $game->g2a;
                    @endphp

                    @if(sizeof($data["prices"]) > 0)

                            @if($g2a != null)

                                        slug}}"
                                           target="_blank"
                                        >
                                            {!! $g2a->name !!}

                                            diffForHumans()!!}">
                                                {{money(end($data["prices"]))}}

                                    {{--

                                        slug}}"
                                           target="_blank"
                                           data-toggle="tooltip"
                                           title="{!! $g2a->name !!}">
                                            thumbnail}}">

                                    --}}

                            @else

                                    No G2A Match Manually adding games is currently not
                                    available.

                            @endif

                    @endif

            @endif

            {{-- Display The games steam info--}}

                    @if(count($game->packages()) > 0)

                            Packages

                                @foreach($game->packages() as $package)
                                    id !!}"> {{$package->name}}

                                @endforeach

                    @endif
                    @if(count($game->bundles) > 0)

                            Bundles

                                @foreach($game->bundles as $bundle)
                                    id !!}"> {{$bundle->name}}

                                @endforeach

                    @endif
                    {{-- Check if metacritic score exists--}}
                    @if($game->metacritics)

                            Metacritic
                            {{-- Check if metacritic url exists--}}
                            {{$game->metacritics->score}}
                                @if($game->metacritics->url)
                                    metacritics->url}}" target="_blank">
                                        {!! App\Icon::find("external-link-square")->wrap() !!}

                                @endif

                    @endif
                    {{-- Check if metacritic score exists--}}
                    @if($game->release_date)

                            Release Date

                                @php($date = \Carbon\Carbon::createFromTimeStamp(strtotime($game->release_date)))
                                {{ $date->toFormattedDateString() }}
                                ({{ $date->diffForHumans() }})

                    @endif
                    {{-- Check if publishers exists--}}
                    @if($game->Publishers)

                            Publishers

                                @foreach($game->Publishers as $publisher)
                                    id}}"> {{$publisher->name}}

                                @endforeach

                    @endif
                    {{-- Check if Categories exists--}}
                    @if($game->Categories)

                            Categories

                                @foreach($game->Categories as $cat)
                                    id}}"> {{$cat->name}}

                                @endforeach

                    @endif
                    {{-- Check if Genres exists--}}
                    @if($game->genres)

                            Genres

                                @foreach($game->Genres as $genre)
                                    id}}"> {{$genre->name}}

                                @endforeach

                    @endif
                    {{-- Check if Developers exists--}}
                    @if($game->developers)

                            Developers

                                @foreach($game->Developers as $developer)
                                    id}}"> {{$developer->name}}

                                @endforeach

                    @endif
                    @if($game->languages)

                            Languages

                                @foreach($game->languages as $lang)
                                    id}}"> {{$lang->name}}

                                @endforeach

                    @endif
                    {{-- Check if website exists--}}
                    @if($game->website)

                            Website

                                    <input type="text" class="form-control" style="padding:2px;font-size:.7em;"
                                           value="{{$game->website}}">
                                    website}}"
                                       target="_blank">
                                        {!! App\Icon::find("external-link-square")->wrap() !!}

                    @endif
                    {{-- Check if support url exists--}}
                    @if($game->support_url)

                            Support

                                    <input type="text" class="form-control" style="padding:2px;font-size:.7em;"
                                           value="{{$game->support_url}}">
                                    support_url}}"
                                       target="_blank">
                                        {!! App\Icon::find("external-link-square")->wrap() !!}

                    @endif

@endsection

<file_sep>/database/migrations/2017_06_30_080619_create_game_purchase_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGamePurchaseTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('game_purchase', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('game_id');
            $table->integer('purchase_id')->unsigned();

            $table->integer('availability');

            $table->decimal('price_paid')->nullable();
            $table->decimal('price_sold')->nullable();

            $table->date('date_paid')->nullable();
            $table->date('date_sold')->nullable();

            $table->string('key')->nullable();
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        Schema::table('game_purchase', function (Blueprint $table) {
            $table->foreign('purchase_id')->references('id')->on('purchases')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('game_purchase');
    }
}
<file_sep>/resources/views/bundles/edit.blade.php
@extends('main')

@section('title', ' | Edit Bundle')

@section('content')

    @section('actionbar-contents')
        <button class="dropdown-item" type="button" data-toggle="modal" data-target="#bundle-modal">
            Add to Purchases
        </button>
        <button class="dropdown-item" type="button" data-toggle="modal" data-target="#add-game-modal">
            Add a game
        </button>
        <button class="dropdown-item" type="button" data-toggle="modal" data-target="#bulk-import-modal">
            Bulk Importer
        </button>

        <button class="dropdown-item" href="/bundles/{!! $bundle->id !!}" >
            View Bundle
        </button>

    @endsection

        {{-- Print the games --}}
        @foreach($bundle->tiers() as $i => $tier)
            @if(sizeof($tier) > 0)

                        Tier {{ $i }}

                @foreach($tier as $game)

                            headerImage()->url !!}"
                                 alt="Card image cap"
                            >

                            <form method="POST" action="{{route("bundle.change_tier")}}">
                                {!! csrf_field() !!}
                                <input type="hidden" name="bundle_game_id" value="{!! $game->pivot->id !!}">

                                id}}"
                                   class="card-title"
                                   style="background-color:rgba(1,1,1,.6);color:white;font-size:1.4em;padding:5px;">
                                    {!! $game->name !!}

                                    <button name="new_tier" value="{{$i - 1}}" class="btn-empty">
                                        {!! App\Icon::find("arrow-up")->wrap(["color" => "white"]) !!}
                                    </button>

                                    <button name="new_tier" value="{{$i + 1}}" class="btn-empty">
                                        {!! App\Icon::find("arrow-down")->wrap(["color" => "white"]) !!}
                                    </button>

                                    <button name="new_tier" value="0" class="btn-empty">
                                        {!! App\Icon::find("trash")->wrap() !!}
                                    </button>

                            </form>

                @endforeach
            @endif
        @endforeach

    @include("games.bulk_import")

    @include("games.game_import")

Add To Purchase

                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        ×
                    </button>

                <form class="form" id="submit-bundle-form" method="POST"
                      action="{{ action('PurchaseController@addBundleToPurchase') }}">
                    {{ csrf_field() }}
                    <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">
                    <input type="hidden" name="bundle_id" value="{!! $bundle->id !!}">
                    <input type="hidden" name="store_id" value="{!! $bundle->store_id !!}">
                    <input type="hidden" name="name" value="{!! $bundle->name !!}">

                            Purchase Date*

                                <input class="form-control" type="date" id="purchase-date" name="date_purchased">

                            Tier Purchased

                                <select id="purchase-tier" name="tier_purchased" class="form-control">
                                    @for($i = 1; $i <= count($bundle->tiers()); $i++)
                                        <option value="{!! $i !!}">Tier {!! $i !!}</option>
                                    @endfor
                                </select>

                            Price*

                                <input class="form-control" type="number" id="purchase-price" name="price_paid">

                            Notes

                            <textarea
                                    class="form-control"
                                    id="purchase-notes"
                                    name="notes"
                                    value="">
                            </textarea>

                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                        <button type="submit" class="btn btn-primary">Submit</button>

                </form>

@endsection

<file_sep>/resources/assets/js/app.js
/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('messenger-users', require('./components/MessengerUsers.vue'));
Vue.component('messenger-user', require('./components/MessengerUser.vue'));
Vue.component('messenger-messages', require('./components/MessengerMessages.vue'));
Vue.component('messenger-message', require('./components/MessengerMessage.vue'));
Vue.component('messenger-composer', require('./components/MessengerComposer.vue'));

const app = new Vue({
        el: '#app',
        data: {
            conversations: [],
            auth: null
        },
        mounted(){
            axios
                .post(
                    "/conversation/get/all", {
                        //user_id: this.auth.id
                    })
                .then(
                    response => {
                        console.log(response);

                        this.auth = response.data.data.user;

                        var data  = response.data.data.conversations;

                        // Go through convos
                        for (var conversation_id in data){
                            var conversation = data[conversation_id];

                            var users = {};
                            for(var i in conversation.users){
                                if(this.auth.id === conversation.users[i].id) {
                                    users.user = conversation.users[i];
                                }else{
                                    users.friend = conversation.users[i];
                                }
                            }
                            conversation.users = users;

                            //delete conversation.users;

                            // Go through messages
                            for(var message_id in conversation.messages){
                                conversation.messages[message_id].fromUser
                                    = this.auth.id === conversation.messages[message_id].user_id;
                            }
                        }

                        this.conversations = response.data.data.conversations;
                     }
                );
        },

        created(){
            Echo.join('chatroom')
                .here(function(){
                    console.log("here");
                })
                .joining(function(){
                    console.log("joining");
                })
                .leaving(function(){
                    console.log("leaving");
                })
                .listen('MessagePosted', (e) => {
                    for(var i in this.conversations){
                        if(this.conversations[i].id === e.message.conversation_id){

                            timeago.cancel();
                            timeago().render(document.querySelectorAll('.need_to_be_rendered'));

                            e.message.fromUser = e.message.user_id === this.auth.id;
                            this.conversations[i].messages.push(e.message);

                            var audio = new Audio("https://notificationsounds.com/soundfiles/68ce199ec2c5517597ce0a4d89620f55/file-sounds-954-all-eyes-on-me.mp3");
                            audio.play();
                            break;
                        }
                    }
                })

            Echo.join(`conversations-updated.19`)
                .listen('ConversationPosted', (e) => {
                    var data = e.user.conversations;

                    // Go through convos
                    for (var conversation_id in data){
                        var conversation = data[conversation_id];

                        var users = {};
                        for(var i in conversation.users){
                            if(this.auth.id === conversation.users[i].id) {
                                users.user = conversation.users[i];
                            }else{
                                users.friend = conversation.users[i];
                            }
                        }
                        conversation.users = users;

                        //delete conversation.users;

                        // Go through messages
                        for(var message_id in conversation.messages){
                            conversation.messages[message_id].fromUser
                                = this.auth.id === conversation.messages[message_id].user_id;
                        }
                    }

                    this.conversations = data;

                });
        }
    })
;
<file_sep>/app/Http/Controllers/AuthController.php
<?php

namespace App\Http\Controllers;

use GuzzleHttp\Psr7\Request;
use Illuminate\Support\Facades\Session;
use Invisnik\LaravelSteamAuth\SteamAuth;
use App\User;
use Auth;

class AuthController extends Controller
{
    /**
     * The SteamAuth instance.
     *
     * @var SteamAuth
     */
    protected $steam;

    /**
     * The redirect URL.
     *
     * @var string
     */
    protected $redirectURL = '/';

    /**
     * AuthController constructor.
     *
     * @param SteamAuth $steam
     */
    public function __construct(SteamAuth $steam)
    {
        $this->steam = $steam;
    }

    /**
     * Redirect the user to the authentication page
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function redirectToSteam()
    {
        return $this->steam->redirect();
    }

    /**
     * Get user info and log in
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function handle()
    {
        // Check if the user just validated their info
        if ($this->steam->validate()) {

            // Get the info
            $info = $this->steam->getUserInfo();

            if($info){
                // Check if steam is account is already linked to local account
                if($user = User::where('steamid', $info->steamID64)->first()){

                    // Check if the user is currently logged in and the accounts match
                    if(Auth::check()){
                        if($user->id != Auth::user()->id){
                            Session::flash("message-danger", "Another user is already synced with this Steam account.");
                            return redirect("settings/connections");
                        }
                    }

                    // The user is trying to log in
                    Auth::login($user);
                    return redirect($this->redirectURL); // redirect to site
                }
                else{
                    // the user is signing up
                    // Check if the user is currently logged in
                    if(Auth::check()){
                        // the user is syncing their steam account to their local account
                        $user = Auth::user();
                        $user->steamid = $info->steamID64;
                        $user->avatar = $info->avatar;
                        $user->save();

                        return redirect("settings/connections");
                    }
                    else{
                        return view("auth.register")->withInfo($info);
                    }

                }
            }
        }
        return $this->redirectToSteam();
    }

}<file_sep>/resources/views/games/bulk_import.blade.php

Bulk Importer

                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    ×
                </button>

                    Quickly search for multiple games
                    <textarea id="games" style=""></textarea>

                <button class="btn btn-primary" style="width:100%;" onclick="parseUserInput();">Search</button>

                        User Input
                        Results
                        Save
                        Delete

                <button type="button" class="btn btn-secondary"  onclick="resetModal();">
                    Reset
                </button>

                <button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="processImport(saved, from);">
                    Continue
                </button>

<file_sep>/resources/views/games/package.blade.php
@extends('main')
@if(!$game)

        Error! Game not found

@endif

@php
    $game->header_image = $game->images->where("type","header_image")->first()->url;
@endphp
@section('title', " | $game->name")

@section('content')

        @if(Auth::check())

                    <button class="btn btn-secondary dropdown-toggle"
                            style="width:100%;"
                            type="button"
                            id="dropdownMenuButton"
                            data-toggle="dropdown"
                            aria-haspopup="true"
                            aria-expanded="false">
                        Actions
                    </button>

                                Catalogs

                                Lists

                                Bundle

                                    <button class='empty-button' type="button" data-toggle="modal"
                                            data-target="#bundle-modal">

                                    </button>

                                Purchases

                                    <button class='empty-button' type="button" data-toggle="modal"
                                            data-target="#purchase-modal">

                                    </button>

                                Tools

        @endif

                    {{$game->name}}

                    @php($counter = 0)
                    @foreach($game->movies as $movie)
                        @php($counter++)

                            <video class="lg-video-object lg-html5" controls preload="none">
                                <source src="{{$movie->url_hd}}" type="video/mp4">
                                Your browser does not support HTML5 video.
                            </video>

                    @endforeach

                    {{-- Display The games image--}}

header_image}}"
                                    data-thumb="{{$game->header_image}}">
                                header_image}}"/>

                            @php($counter = 0)
                            @foreach($game->movies as $movie)
                                @php($counter++)

thumbnail}}"
                                        data-thumb="https://c3metrics.com/wp-content/uploads/2016/08/feature-video-thumbnail-overlay.png"
                                        data-html="#video-{{$counter}}">
                                    thumbnail}}"/>

                            @endforeach
                            @foreach($game->screenshots as $screenshot)

url}}"
                                        data-thumb="{{$screenshot->thumbnail}}">
                                    url}}"/>

                            @endforeach

                {{-- Print the games in the package --}}

Package Contents:

                    @foreach($game->packageContents as $content)
                        {{-- Get the package content indo --}}
                        @php($content = App\Game::find($content->content_id))

                            images->where("type","header_image")->first()->url == null ? "http://cdn.akamai.steamstatic.com/steam/apps/10/header.jpg?t=1447887426" : $game->images->where("type","header_image")->first()->url}}"
                                 alt="Card image cap">

                                id}}"
                                   class="card-title"
                                   style="background-color:rgba(1,1,1,.6);color:white;font-size:1.4em;padding:5px;">
                                    {!! $content->name !!}

                    @endforeach

@endsection
<file_sep>/app/Http/Controllers/IconController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use App\Icon;

class IconController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            "id" => "required",
            "name" => "required",
            "default_color" => "nullable",
            "default_size" => "nullable",
        ]);

        $icon = new Icon();

        $icon->id = $request->id;

        if(isset($request->name) && $request->name){
            $icon->name = ucfirst($request->name);
        }
        else{
            $icon->name = ucfirst($request->id);
        }

        if(isset($request->default_color) && $request->default_color){
            $icon->default_color = $request->default_color;
        }

        if(isset($request->default_size) && $request->default_size){
            $icon->default_size = $request->default_size;
        }

        $icon->save();

        Session::flash("message-success", "Icon updated");
        return back();

    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request)
    {
        $this->validate($request, [
            "old_id" => "required|string",
            "id" => "nullable|string",
            "name" => "nullable|string",
            "default_color" => "nullable|string",
            "default_size" => "nullable|string",
        ]);

        if(($icon = Icon::find($request->old_id)) == null){
            Session::flash("message-danger", "Icon not found.");
            return back();
        }

        if(isset($request->id) && $request->id){
            $icon->id = $request->id;
        }

        if(isset($request->name) && $request->name){
            $icon->name = $request->name;
        }

        if(isset($request->default_color) && $request->default_color){
            $icon->default_color = $request->default_color;
        }

        if(isset($request->default_size) && $request->default_size){
            $icon->default_size = $request->default_size == "default" ? "" : $request->default_size;
        }

        $icon->save();

        Session::flash("message-success", "Icon updated");
        return back();

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}
<file_sep>/app/Bundle.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Bundle extends Model
{
    protected $fillable = ["store_id", "name", "date_started", "date_ended"];

    public function games(){
        return $this->belongsToMany('App\Game')->withPivot("tier", "id");
    }

    public function stores(){
        return $this->belongsTo('App\Store', "store_id", "id");
    }

    public function tiers(){
        $gamesByTier = [];
        foreach($this->games as $bundleItem){
            $gamesByTier[$bundleItem->pivot->tier][] = $bundleItem;
        }

        ksort($gamesByTier);
        return $gamesByTier;
    }
}
<file_sep>/resources/views/settings/index.blade.php
@extends('main')
@section('title')

@section('content')
@section('actionbar-contents')
    My Account
    @if(Auth::check() && Auth::user()->checkRole("admin"))

Admin Actions

        Manage Icons
        Update Games
        Update Packages
        G2aAuto Matcher
        G2aUpdate Prices

    @endif

@endsection

    @yield("settings-content")

@endsection<file_sep>/app/Http/Controllers/PurchaseController.php
<?php

namespace App\Http\Controllers;

use App\Http\Middleware\RedirectIfAuthenticated;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;

use App\Purchase;
use App\Game;
use App\User;
use App\Bundle;

use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\DB;

class PurchaseController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */

    public function index(){

        if (!Auth::check()) {
            Session::flash("message-info", "Log in or create an account to track your purchases");
            return Redirect::route("login");
        }

        return view("purchases.index");
    }

    public function getPurchases(Request $request){
        $this->validate($request, [
            "user_id" => "required|numeric"
        ]);

        return ["success" => true, "data" => User::find($request->user_id)->purchases->load("games")];

    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return back();
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            "user_id" => "required|numeric",
            "store_id" => "required|numeric",
            "name" => "required|string",
            "price_paid" => "nullable|numeric",
            "date" => "nullable|date",
            "notes" => "nullable",
            "tier_purchased" => "nullable|numeric",
            "bundle_id" => "nullable|numeric",
        ]);

        $purchase = new Purchase($request->except(["_token"]));
        $purchase->save();

        return back();

    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {

    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function updatePurchasePrice(Request $request)
    {
        $this->validate($request, [
            "purchase_id" => "required|numeric",
            "price_paid" => "required_without:price_sold|numeric",
            "price_sold" => "required_without:price_paid|numeric",
        ]);

        if(isset($request->price_paid)){
            DB::update("update purchases set price_paid = ? where id = ? ", [$request->price_paid, $request->purchase_id]);
        }
        if(isset($request->price_sold)){
            DB::update("update purchases set price_sold = ? where id = ? ", [$request->price_sold, $request->purchase_id]);
        }

        return ["success" => true];
    }

    public function updatePurchaseItemPrice(Request $request)
    {
        $this->validate($request, [
            "game_purchase_id" => "required|numeric",
            "price_paid" => "required_without:price_sold|numeric",
            "price_sold" => "required_without:price_paid|numeric",
        ]);

        if(isset($request->price_paid)){
            DB::update("update game_purchase set price_paid = ? where id = ? ", [$request->price_paid, $request->game_purchase_id]);
        }
        if(isset($request->price_sold)){
            DB::update("update game_purchase set price_sold = ? where id = ? ", [$request->price_sold, $request->game_purchase_id]);
        }

        return ["success" => true];
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $purchase = Purchase::find($id);

        if($purchase == null){
            return ["sucess" => false, "message" => "Purchase not found."];
        }
        else if ($purchase->user->id != Auth::user()->id){
            return ["sucess" => false, "message" => "The purchase doesn't belong to you" ,"data" => $purchase];
        }
        else{
            $purchase->delete();
            return ["sucess" => true, "message" => "The purchase was deleted" ,"data" => $purchase];
        }
    }

    public function destroyPurchaseItem(Request $request){
        $this->validate($request, array(
            'game_purchase_id' => 'required|numeric'
        ));

    }

    public function insertGamesIntoPurchase(Request $request){
        $this->validate($request, array(
            'game_ids' => 'required|max:255',
            'purchase_id' => 'required|numeric',
            'availability' => 'required|numeric',
            'price_paid' => 'nullable|numeric',
            'price_sold' => 'nullable|numeric',
            'key' => 'nullable|string',
            'notes' => 'nullable|string',
        ));

        // Get the Purchase
        $purchase = Purchase::find($request->purchase_id);
        if($purchase == null){
            return ["success" => false, "code" => 0, "message" => "Invalid Purchase ID"];
        }

        // Verify that the id's are in an array
        if(!is_array($request->game_ids)){
            $request->game_ids = [$request->game_ids];
        }

        // Add each game
        $results = [
            ["added" => null],
            ["skipped" => null]
        ];

        foreach($request->game_ids as $game_id){
            $game = Game::find($game_id);
            // Verify the game was found
            if($game == null){
                $results["skipped"][] = $game_id;
            }
            else{
                $data = $request->except(["_token", "game_ids"]);
                $data["game_id"] = $game_id;

                $purchase->games()->save($game, $data);
                $results["added"][] = $game_id;
            }
        }

        return ["success" => true, "results" => $results];
    }

    public function addBundleToPurchase(Request $request){
        $this->validate($request, array(
            'user_id' => 'required|numeric',
            'name' => 'required|max:255',
            'store_id' => 'required|numeric',
            'date_purchased' => 'nullable|date',
            'price_paid' => 'nullable|numeric',
            'bundle_id' => 'nullable|numeric',
            'tier_purchased' => 'nullable|numeric',
            'notes' => 'nullable|string',
        ));

        // Add to purchase
        $purchase = $this->update(new Purchase(), $request->except("_token"));

        // Add the games
        foreach(Bundle::find($request->bundle_id)->games as $game){
            if($game->pivot->tier <= $request->tier_purchased){
                $purchase->games()->save($game, ["availability" => 0]);
            }
        }

        return Redirect("purchases");
    }

    public function massAction(Request $request){
        $this->validate($request, array(
            'action' => 'required|max:255',
            'ids' => 'required',
            'move_to' => 'numeric|required_if:action,move',
        ));

        if($request->action == "delete"){
            foreach($request->ids as $game){
                DB::delete("delete from game_purchase where id = ? ", [$game]);
            }
        }
        else if($request->action == "move"){

            foreach($request->ids as $game){
                DB::update("update game_purchase set purchase_id = ? where id = ? ", [$request->move_to, $game]);
            }
        }

        return ["sucess" => true];
    }

    public function update($item, $data){
        foreach($data as $key => $attribute){
            if($attribute == null){
                continue;
            }
            $item->{$key} = $attribute;
        }
        $item->save();
        return $item;
    }

    public function updateAvailability(Request $request){
        $this->validate($request, array(
            'game_purchase_id' => 'required|numeric',
            'availability' => 'required|numeric',
        ));

        DB::table("game_purchase")->where("id",$request->game_purchase_id)->update(["availability" => $request->availability]);

        return ["success" => "true", "data" => $request];
    }

    public function findMissingGames($user){
        $steam = resolve('App\External\Steam');

        $steamLibrary =  Game::whereIn("steam_id", $steam->getOwnedGamesAsArray($user->steamid))->pluck("id")->toArray();
        $localLibrary = $user->catalogs()["library"];

        return ["steam" => array_diff($localLibrary, $steamLibrary),"local" => array_diff($steamLibrary, $localLibrary)];
    }

}
<file_sep>/resources/views/auth/signup.blade.php
@extends('main')
@section('title', ' | Sign Up')
@section('content')

        Soon, this page will have all the reasons why you should up. For now, you're going to have to trust us:
        it's worth it!

@endsection<file_sep>/app/Screenshot.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Screenshot extends Model
{
    protected $fillable = ['game_id', 'url', 'thumbnail'];

    public function games()
    {
        return $this->belongsTo('App\Game');
    }
}
<file_sep>/resources/views/settings/updatedatabasepackages.blade.php
@extends('settings.index')

@section('settings-content')

Update Database

        Number of packages remaining:
        <input id="counter" value="{{count($games)}}">

    <button class="btn" id="start">Start</button>
    <button class="btn" id="stop" style="display:none;">Stop</button>

                Appid
                Name
                Type
                Message

@endsection

<file_sep>/resources/assets/js/components/MessengerMessages.vue

<template>

            <messenger-message v-for="message, index in conversation.messages" :message="message" :index="index"></messenger-message>

            <messenger-composer :conversation="conversation"></messenger-composer>

</template>

<file_sep>/database/migrations/2017_07_04_091728_create_icons_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateIconsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('icons', function (Blueprint $table) {
            $table->string('id');
            $table->string('name')->nullable();
            $table->string('default_color')->nullable();
            $table->string('default_size')->nullable();
        });

        // Default Values
        DB::table('icons')->insert(
            [
                [
                    'id' => 'book',
                    "name" => "Library",
                    "default_color" => "blue",
                    "default_size" => ""
                ],
                [
                    'id' => 'archive',
                    "name" => "Inventory",
                    "default_color" => "brown",
                    "default_size" => ""
                ],
                [
                    'id' => 'external-link-square',
                    "name" => "Link",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'sticky-note',
                    "name" => "Note",
                    "default_color" => "yellow",
                    "default_size" => ""
                ],
                [
                    'id' => 'plus',
                    "name" => "Add",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'plus-circle',
                    "name" => "Bulk Add",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'trash',
                    "name" => "Delete",
                    "default_color" => "red",
                    "default_size" => ""
                ],
                [
                    'id' => 'arrow-down',
                    "name" => "Down",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'arrow-up',
                    "name" => "Up",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'circle',
                    "name" => "Circle",
                    "default_color" => "",
                    "default_size" => ""
                ],
                [
                    'id' => 'pencil-square-o',
                    "name" => "Edit",
                    "default_color" => "",
                    "default_size" => ""
                ]
            ]

        );
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('icons');
    }
}
<file_sep>/app/Http/Controllers/BundleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;
use App\Bundle;
use App\Game;

class BundleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('bundles.index')->withBundles(Bundle::paginate(10));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, array(
            'name'      =>'required|max:255',
            'store_id'      =>'required|numeric',
            'date_started'      =>'date|nullable',
            'date_ended'      =>'date|nullable',
        ));

        Session::flash('message-success', 'The bundle was successfully saved');
        $bundle = new Bundle($request->except(["_token"]));
        $bundle->save();

        return back();
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $bundle = Bundle::find($id);
        if($bundle == null){
            Session::flash("message-danger", "The bundle was not found.");
            return Redirect::route("bundles.index");
        }

        return view('bundles.show')->withBundle($bundle);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        if(Auth::check()){
            if(!Auth::user()->checkRole("admin")){
                Session::flash("message-info", "You do not have access to this page. Please login with the proper credentials.");
                return back();
            }
        }
        else{
            Session::flash("message-info", "This is a restricted page. You must be logged in and have the appropriate access to view this page");
            return Redirect::route("login");
        }

        return view("bundles.edit")->withBundle(Bundle::find($id));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $bundle = Bundle::find($id);

        if($bundle == null){
            Session::flash("message-danger", "The bundle could not be located. Nothing was deleted.");
        }
        else{
            Session::flash("message-success", "The purchase was deleted");
            $bundle->delete();
        }

        return back();
    }

    public function linkGameToBundle(Request $request){
        $this->validate($request, array(
            'bundle_id'      =>'required',
            'game_ids'          =>'required',
            'tier'          =>'nullable|numeric',

        ));
        // Get the bundle
        $bundle = Bundle::find($request->bundle_id);
        if($bundle == null){
            return ["success" => false, "code" => 0, "message" => "Invalid Bundle ID"];
        }

        // Verify that the id's are in an array
        if(!is_array($request->game_ids)){
            $request->game_ids = [$request->game_ids];
        }

        // Add each game
        $results = [
            ["added" => null],
            ["skipped" => null]
        ];

        foreach($request->game_ids as $game_id){
            $game = Game::find($game_id);
            // Verify the game was found
            if($game == null){
                $results["skipped"][] = $game_id;
            }
            else{
                $bundle->games()->attach($game, ["tier" => $request->tier]);
                $results["added"][] = $game_id;
            }
        }

        return ["success" => true, "results" => $results];
    }

    public function removeGameFromBundle(Request $request){
        $this->validate($request, array(
            'bundle_id'      =>'required',
            'game_id'          =>'required',

        ));

        $bundle = Bundle::find($request->bundle_id);
        $game = Game::find($request->game_id);

        if($game == null || $bundle == null){
            // One of the ID's were bad.
            Session::flash('error', 'Invalid Input');
        }
        else{
            Session::flash('message-success', 'Successfully added removed from bundle');
            $bundle->games()->detach($game);
        }

        return back();
    }

    public function changeTier(Request $request){
        $this->validate($request, array(
            'bundle_game_id'      =>'numeric|required',
            'new_tier'       =>'numeric|min:0|required'
        ));

        if($request->new_tier == 0){
            Session::flash('message-success', 'Successfully removed bundle item');
            DB::table('bundle_game')->where('id', $request->bundle_game_id)->delete();
        }
        else{
            DB::table("bundle_game")->where("id",$request->bundle_game_id)->update(["tier" => $request->new_tier]);
        }

        return back();
    }
}
<file_sep>/app/Purchase.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Purchase extends Model
{
    protected $fillable = ['user_id','store_id','name','price_paid','date_purchased','tier_purchased','bundle_id','notes'];

    public function games(){
        return $this->belongsToMany('App\Game')->withPivot("id", "availability", "price_paid", "price_sold","key","notes");
    }

    public function user(){
        return $this->belongsTo('App\User');
    }

    public function store(){
        return $this->belongsTo('App\Store');
    }
}
<file_sep>/resources/views/partials/_nav.blade.php

                @if(Auth::check())

                                <button id="user-menu" class="btn btn-empty dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                    {{Auth::user()->name}}
                                    @if(Auth::user()->checkSteam())
                                        {!! App\Icon::find("check")->wrap(["color" => "#90C2E7", "title" => "Verified with Steam"]) !!}
                                    @endif
                                </button>

                                    Settings
                                    Messages
                                    id !!}">Profile
                                    <form method="post" action="{!!route("logout") !!}">
                                        {{ csrf_field() }}
                                        <button class="dropdown-item">Logout</button>
                                    </form>

                            avatar !!}">

                @else

                                {!! App\Icon::find("user")->wrap(["color" => "white"]) !!} login

                @endif

default_color !!};">

                {!! App\Icon::find("book")->wrap() !!}
                Library

default_color !!};">

                {!! App\Icon::find("archive")->wrap() !!}
                Inventory

default_color !!};">

                {!! App\Icon::find("gift")->wrap() !!}
                Wishlist

                Purchases

                Bundles

                Games

@if(strpos(url()->current(), "library") !== false)

@elseif(strpos(url()->current(), "inventory") !== false)

@elseif(strpos(url()->current(), "wishlist") !== false)

@elseif(strpos(url()->current(), "purchases") !== false)

@elseif(strpos(url()->current(), "bundles") !== false)

@elseif(strpos(url()->current(), "games") !== false)

@endif

<file_sep>/app/External/Steam.php
<?php
/**
 * Created by PhpStorm.
 * User: johnorlando
 * Date: 7/27/2017
 * Time: 10:06 PM
 */

namespace App\External;

use App\Store;

class Steam
{
    protected $key;
    protected $store = null;
    protected $applist = null;

    protected $urls = [
        "base" => "http://api.steampowered.com",
        "applist" => "http://api.steampowered.com/ISteamApps/GetAppList/v0002/",
        "app" => "http://store.steampowered.com/api/appdetails/?appids=",
        "appPriceFilters" => "&cc=us&filters=price_overview",
        "package" => "http://store.steampowered.com/api/packagedetails/?packageids="
    ];

    public function __construct($key)
    {
        // Get key
        $this->key = $key;
    }

    public function getKey()
    {
        return $this->key;
    }

    public function getStore()
    {
        // Check if we already have the store
        if ($this->store == null) {
            //Get store from DB
            if (!$this->store = Store::where("name", "Steam")->first()) {
                $store = new Store;
                $store->name = "Steam";
                $store->save();
                $this->store = $store;
            }
        }
        return $this->store;
    }

    public function getApplist()
    {
        // Check if we already have the applist
        if ($this->applist == null) {
            $this->applist = json_decode(file_get_contents($this->urls['applist']), true)["applist"]["apps"];
        }
        return $this->applist;
    }

    public function parseData($id, $type = "app")
    {

        // Validate the appid
        if (!is_numeric($id)) {
            return ["success" => false, "code" => 1, "message" => "Invalid appid"];
        }

        // Get the data from Steam
        if (!$content = file_get_contents($this->urls[$type] . $id)) {
            return ["success" => false, "code" => 2, "message" => "Steam blocked the call."];
        }
        $json = json_decode($content, true);

        // Remove the key from the data
        $json = reset($json);

        // Check if steam had the info for the appid we provided.
        if (!isset($json["success"])) {
            return ["success" => false, "code" => 3, "message" => "There was an error parsing the JSON from Steam."];
        }

        if ($json["success"] == false) {
            return ["success" => false, "code" => 4, "message" => "Steam didn't have any data for this appid"];
        }

        if ($json["success"] == true) {
            // Set the Steam id
            if (!isset($json["data"]["steam_id"])) {
                $json["data"]["steam_id"] = $id;
            }

            // Convert the languages to array
            if (isset($json["data"]["supported_languages"])) {
                $json["data"]["supported_languages"] = $this->getLanguagesAsArray($json["data"]["supported_languages"]);
            }
        }

        return $json;
    }

    public function parseAppData($id)
    {
        return $this->parseData($id);
    }

    public function parsePackageData($id)
    {
        return $this->parseData($id, "package");
    }

    public function getLanguagesAsArray($languages)
    {
        /**
         * Explode language string into array
         * Case: Normal
         * Input:
         *      English,Spanish,German
         * Resolution: Explode by ','
         *
         * Case:
         * Input:
         * Resolution:
         *
         * Case: System calls for new lines
         * Input:
         *      English\r\n
         *      Spanish\r\n
         *      German\r\n
         * Resolution: Replace all instances of '\r' and '\n' with a marker, '~!~', and explode by that marker.
         */

        $result = [];

        foreach (explode(",", preg_replace(array('/\n/', '/\r/'), '~!~', $languages)) as $lang) {
            foreach (explode('~!~', $lang) as $chunk) {
                foreach ($this->cleanLang($chunk) as $bit) {
                    if (in_array($bit, $result) || $bit == "") {
                        continue;
                    }
                    $result[] = $bit;
                }
            }
        }
        return $result;
    }

    public function cleanLang($chunk)
    {
        $result = [];

        $chunk = (explode("<", $chunk)[0]);
        $chunk = (explode('(', $chunk)[0]);
        $chunk = (explode('-', $chunk)[0]);
        $chunk = (explode(';', $chunk)[0]);
        $chunk = (explode('[', $chunk)[0]);
        $chunk = trim($chunk);

        // special cases
        if ($chunk == "English Dutch  English") {
            $result[] = "English";
            $result[] = "Dutch";
        } else if ($chunk == "#lang_français" || $chunk == "французский" || $chunk == "Francês") {
            $result[] = "French";
        } else if ($chunk == "Inglês" || $chunk == "английский") {
            $result[] = "English";
        } else if ($chunk == "русский" || $chunk == "Russo") {
            $result[] = "Russian";
        } else if ($chunk == "немецкий" || $chunk == "Alemão") {
            $result[] = "German";
        } else if ($chunk == "испанский" || $chunk == "Espanhol") {
            $result[] = "Spanish";
        } else if ($chunk == "чешский") {
            $result[] = "Czech";
        } else if ($chunk == "японский") {
            $result[] = "Japanese";
        } else if ($chunk == "бразильский португальский") {
            $result[] = "Brazilian Portuguese";
        } else if ($chunk == "турецкий") {
            $result[] = "Turkish";
        } else if ($chunk == "польский") {
            $result[] = "Polish";
        } else if ($chunk == "корейский") {
            $result[] = "Korean";
        } else if ($chunk == "Italiano") {
            $result[] = "Italian";
        } else {
            $result[] = $chunk;
        }
        return $result;
    }

    function buildUrl($api, $items){
        $base = "http://api.steampowered.com";
        $args = [];

        foreach($items as $key => $item){
            if($key == null || $item == null){
                continue;
            }
            $args[$key] = $item;
        }

        return $base . $api . "?" . http_build_query($args);
    }

    function decodeUrl($url){

        $json = file_get_contents($url);
        $content = json_decode($json, true);
        return $content;

    }

    // Api's
    function newsForApp($appid, $count = 999999, $length = 999999)
    {
        return $this->decodeUrl($this->buildUrl("/ISteamNews/GetNewsForApp/v0002/", [
            "count" => $count,
            "maxlength" =>$length,
            "appid" =>$appid
        ]));
    }

    function globalAchievementPercentagesForApp($appid)
    {
        return $this->buildUrl("/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v0002/", [
            "gameid" => $appid,
            "format" =>"json"
        ]);
    }

    function globalStatsForGame($appid)
    {
        // ??

        return $this->buildUrl( "/ISteamUserStats/GetGlobalStatsForGame/v0001/", [
            "gameid" => $appid,
            "format" =>"json"
        ]);
    }

    function playerSummaries($steamids)
    {
        return $this->buildUrl("/ISteamUser/GetPlayerSummaries/v0002/", [
            "steamids" => $steamids,
            "key" => $this->key,
            "format" =>"json"
        ]);
    }

    function friendList($steamid)
    {
        return $this->buildUrl("/ISteamUser/GetFriendList/v0001", [
            "key" => $this->key,
            "steamids" => $steamid,
            "relationship" =>"friend",
            "format" =>"json"
        ]);
    }

    function playerAchievements($steamid, $appid)
    {
        return $this->buildUrl("/ISteamUserStats/GetPlayerAchievements/v0001/", [
            "key" => $this->key,
            "steamid" => $steamid,
            "appid" => $appid,
        ]);
    }

    function userStatsForGame($steamid, $appid)
    {
        return $this->buildUrl( "/ISteamUserStats/GetUserStatsForGame/v0002/", [
            "key" => $this->key,
            "steamid" => $steamid,
            "appid" => $appid,
        ]);
    }

    function ownedGames($steamid)
    {
        return $this->buildUrl( "/IPlayerService/GetOwnedGames/v0001/", [
            "key" => $this->key,
            "steamid" => $steamid,
            "format" => "json",
        ]);
    }

    function getOwnedGamesAsArray($steamid){
        $games = [];
        foreach($this->decodeUrl($this->ownedGames($steamid))["response"]["games"] as $game){
            $games[] = $game["appid"];
        }
        return $games;
    }

    function recentlyPlayedGames($steamid, $count = 999999)
    {
        return $this->buildUrl( "/IPlayerService/GetRecentlyPlayedGames/v0001/", [
            "key" => $this->key,
            "steamid" => $steamid,
            "count" => $count,
            "format" => "json"
        ]);
    }

    function IsPlayingSharedGame($steamid, $appid)
    {
        return $this->buildUrl( "/IPlayerService/IsPlayingSharedGame/v0001/", [
            "key" => $this->key,
            "steamid" => $steamid,
            "appid_playing" => $appid,
            "format" => "json"
        ]);
    }

    function schemaForGame($appid)
    {
        return $this->buildUrl( "/IPlayerService/IsPlayingSharedGame/v0001/", [
            "key" => $this->key,
            "appid" => $appid,
            "format" => "json"
        ]);
    }

    function playerBans($steamids){
        return $this->buildUrl( "/ISteamUserStats/GetSchemaForGame/v2/", [
            "key" => $this->key,
            "steamids" => $steamids
        ]);
    }

}

<file_sep>/resources/views/purchases/index.blade.php
@extends('main')
@section('title')

@section('content')

Add new Purchase

                    <form class="form" id="submit-bundle-form" method="POST" action="/purchases">
                        {{ csrf_field() }}
                        <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">

                            Name*

                                <input type="text" class="form-control" name="name" id="submit-bundle-name" required>

                            Price Paid

                                <input type="text" class="form-control" name="price_paid" id="submit-bundle-price">

                            Store

                                <select class="form-control" name='store_id' data-live-search="true" required>
                                    @foreach(App\Store::all() as $store)
                                        <option value="{{$store->id}}">{{$store->name}}</option>
                                    @endforeach
                                </select>

                            Date Purchased

                                <input type="date" class="form-control" name="date_purchased" id="submit-bundle-date"
                                       value="{!! \Carbon\Carbon::today()->toDateString() !!}">

                            Notes

                                <textarea class="form-control" name="notes" id="submit-bundle-notes"></textarea>

                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            <button for="submit-bundle-form" type="submit" class="btn btn-primary">Submit</button>

                    </form>

    @include("games.bulk_import")

    @include("games.game_import")

    @section('actionbar-contents')
        <button class="dropdown-item" type="button"
                data-toggle="modal"
                data-target="#new-purchase-modal">
            Add New Purchase
        </button>

        @if(Auth::user()->checkRole("admin"))
        @endif

    @endsection

        <form id="action-form">
            <select  style="" name="action" onchange="$('#action-form').submit();">
                <option hidden>Bulk</option>
                <option value="delete">Delete</option>
                <option value="move">Move</option>
                <option>Reset</option>
            </select>
        </form>

Name

Availability

Paid

Sold

Actions

@endsection<file_sep>/resources/views/bundles/show.blade.php
@extends('main')
@section('title', ' | ' . $bundle->name)
@section('content')

    @if(Auth::check())
        @section('actionbar-contents')
            <button class="dropdown-item" type="button" data-toggle="modal" data-target="#bundle-modal">
                Add to Purchases
            </button>

             @if(Auth::user()->checkRole("admin"))
                id !!}/edit'>Edit
            @endif

        @endsection
    @endif

            {!! $bundle->name !!}

                                Store

                                {!! $bundle->stores->name !!}

                        @if($bundle->date_started)

                                Started

                                    {!! \Carbon\Carbon::parse($bundle->date_started)->diffForHumans()!!}

                        @endif
                        @if($bundle->date_ended)

                                Ended

                                    {!! \Carbon\Carbon::parse($bundle->date_ended)->diffForHumans()!!}

                        @endif

            @foreach($bundle->tiers() as $i => $tier)

                            Tier {{ $i }}

                    @include("games.games_printer", ["games" => $tier, "settings" => ["print_advanced" => false, "display_type" => "grid"]])

            @endforeach

Add To Purchase

                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    ×
                </button>

            <form class="form" id="submit-bundle-form" method="POST"
                  action="{{ action('PurchaseController@addBundleToPurchase') }}">
                {{ csrf_field() }}
                <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">
                <input type="hidden" name="bundle_id" value="{!! $bundle->id !!}">
                <input type="hidden" name="store_id" value="{!! $bundle->store_id !!}">
                <input type="hidden" name="name" value="{!! $bundle->name !!}">

                        Purchase Date*

                            <input class="form-control" type="date" id="purchase-date" name="date_purchased" value="{!! \Carbon\Carbon::today()->toDateString() !!}">

                        Tier Purchased

                            <select id="purchase-tier" name="tier_purchased" class="form-control">
                                @for($i = 1; $i <= count($bundle->tiers()); $i++)
                                    <option value="{!! $i !!}">Tier {!! $i !!}</option>
                                @endfor
                            </select>

                        Price paid

                            <input class="form-control" type="text" id="purchase-price" name="price_paid">

                        Notes

                                    <textarea class="form-control" id="purchase-notes" name="notes"></textarea>

                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Submit</button>

            </form>

@endsection

<file_sep>/resources/assets/js/components/MessengerUsers.vue

<template>

        <input class="form-control" style="width:100%;">
        <messenger-user
                v-for="(conversation, index) in conversations"
                :conversation="conversation"
                :index="index"></messenger-user>

</template>

<file_sep>/app/Http/Controllers/GameController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

use App\Game;
use App\Genre;
use App\Category;
use App\Language;
use App\Metacritic;
use App\Screenshot;
use App\Movie;
use App\Developer;
use App\Publisher;
use App\Image;
use App\User;
use App\ImageTheme;
use App\PackageContent;
use App\Store;
use App\Role;

use App\Purchase;

class GameSearch
{
    public $query = null;
    public $results = null;

    // Options
    public $perPage = 12;

    public function __construct($query = null)
    {
        // Check if we are searching/filtering from a list of games
        if (isset($query) && $query == null) {
            // If a list was provided, it will be filtered.
            // If that list is empty, it will act as all()
            // Set it to empty
            $this->query = (new Game)->newQuery();
            $this->query->where("public", 10); // doesn't exist.
        } else if (isset($query)) {
            // The query isn't empty, so set it
            $this->query = $query;
        } else {
            // The query is not set.
            $this->query = (new Game)->newQuery();
        }

        // Only show public games
        $this->query->where("public", 1);
    }

    public function searchBy($categories)
    {
        $allowed = [
            "keywords",
            "types",
            "genres",
            "languages",
            "developers",
            "publishers",
            "categories",
            "languages",
        ];
        $skipped = [];

        if (isset($categories["sorting"])) {
            $sorting = $categories["sorting"];
            unset($categories["sorting"]);
        }

        if (isset($categories["display"])) {
            if (in_array($categories["display"], [12, 24, 36])) {
                $this->perPage = $categories["display"];
            }
            unset($categories["display"]);
        }

        foreach ($categories as $key => $items) {
            if (!in_array($key, $allowed)) {
                $skipped[] = $key;
                continue;
            }

            if ($key == "keywords" && $key != "") {

                // Check if string contains anything
                foreach (explode(" ", trim($items)) as $keyword) {
                    $this->query->where('name', 'LIKE', "%$keyword%");
                }
                continue;
            }

            // Make sure it's an array
            // The only parameter that isn't expecting an array is keywords, so it's been skipped

            if (!is_array($items)) {
                $items = [$items];
            }

            if ($key == "types") {
                $this->query->where(function ($query) use ($items) {
                    foreach ($items as $type) {
                        // Check if first
                        $query->where("type", $type);
                    }
                });
                continue;
            }

            foreach ($items as $item) {
                $this->query->whereHas("$key", function ($query) use ($item, $key) {
                    $query->where("$key.id", '=', $item);
                });
            }
        }

        // sorting
        if (isset($sorting) && $sorting != null) {
            $params = explode("-", $sorting);
            $this->query->orderBy($params[0], $params[1]);
        }

        return $this;
    }

    public function results()
    {
        $this->results = $this->query->get();

        $this->sort();

        if (isset($_GET)) {
            $this->results->input = $_GET;
        }

        return $this->results;
    }

    public function paginatedResults()
    {

        $this->results = $this->query->paginate($this->perPage);

        if (isset($_GET)) {
            $this->results->input = $_GET;
        }

        return $this->results;
    }
}

function GameSearch($data = null)
{
    return new GameSearch($data);
}

class GameController extends Controller
{

    // Views
    public function test()
    {

        dd(Auth::user()->catalogs());
        /*
        $steam = resolve('App\External\Steam');

        //$steamLibrary =  Game::whereIn("steam_id", $steam->getOwnedGamesAsArray($user->steamid));

        return view("games.index")->withGames(
            GameSearch(Game::whereIn("steam_id", $steam->getOwnedGamesAsArray(Auth::user()->steamid)))
                ->searchBy($_GET)->paginatedResults()
        );

        /*
        $steam = resolve('App\External\Steam');
        return \redirect(
           $steam->urlBuilder()->isPlayingSharedGame(Auth::user()->steamid, 10)->get()
        );
        //return view("test");
        */
    }

    public function home()
    {

        return view("home");
    }

    public function showLibrary()
    {
        if (!Auth::check()) {
            Session::flash("message-info", "Log in or create an account to add games to your library!");
            return Redirect::route("login");
        }

        return view("games.index")->withGames(GameSearch(Auth::user()->library())->searchBy($_GET)->paginatedResults());

    }

    public function showInventory()
    {
        if (!Auth::check()) {
            Session::flash("message-info", "Log in or create an account to add games to your Inventory!");
            return Redirect::route("login");
        }

        return view("games.index")->withGames(GameSearch(Auth::user()->inventory())->searchBy($_GET)->paginatedResults());
    }

    public function showWishlist()
    {
        if (!Auth::check()) {
            Session::flash("message-info", "Log in or create an account to add games to your Wishlist!");
            return Redirect::route("login");
        }

        return view("games.index")->withGames(GameSearch(Auth::user()->wishlist())->searchBy($_GET)->paginatedResults());
    }

    public function show($id)
    {
        $game = Game::find($id);

        return view("games.show")->withGame($game);
    }

    public function index()
    {
        return view("games.index")->withGames(GameSearch()->searchBy($_GET)->paginatedResults());
    }

    public function updateGames()
    {
        // Sync with steam
        $this->syncApplist();
        return view("settings.updatedatabase")->withGames(
            Game::where("public", "-1")
                ->where("type", "unknown")
                ->pluck("steam_id")
                ->toArray()
        );
    }

    public function updateWishlist(Request $request)
    {
        $this->validate($request,
            [
                "game_id" => "required|numeric",
                "user_id" => "required|numeric",
            ]
        );

        // continue validation
        if (($user = User::find($request->user_id)) == null) {
            Session::flash("message-danger", "Invalid user");
            return back();

        }
        else if (($game = Game::find($request->game_id)) == null) {
            Session::flash("message-danger", "Invalid game");
            return back();
        }

        $user->games()->toggle($request->game_id);
        return back();

    }

    public function updatePackages()
    {
        return view("settings.updatedatabasepackages")->withGames(
            Game::where("public", "-1")
                ->where("type", "package")
                ->pluck("steam_id")
                ->toArray()
        );
    }

    public function userProfile($id)
    {
        $user = User::find($id);

        if ($user == null) {
            return ["success" => false];
        }

        return view("users.profile")->withUser($user);

    }

    // Functions

    public function search()
    {
        return GameSearch()->searchBy($_GET)->paginatedResults();
    }

    // Steam

    public function syncApplist()
    {
        // We're going to need more than 30 seconds
        ini_set('max_execution_time', 300); //300 seconds = 5 minutes

        // Get all appids that are in the list and subtract all the appids that are in the database
        $steam = resolve('App\External\Steam');
        $appids = array_diff(
            array_column($steam->getApplist(), "appid"),
            Game::where("type", "!=", "package")->pluck("steam_id")->toArray()
        );

        $games = [];
        foreach ($appids as $key => $appid) {
            // Get the game info from the json file
            $game = $steam->getApplist()[$key];

            // Change key name
            $game["steam_id"] = $game["appid"];
            unset($game["appid"]);

            // Add game to list
            $games[] = array_merge(
                $game,
                [
                    "type" => "unknown",
                    "public" => "-1"
                ]
            );
        }

        // Add the games to the database. Split into chunks to avoid errors
        foreach (array_chunk($games, 1000) as $chunk) {
            Game::insert($chunk);
        }

        return $games;
    }

    public function unlinkSteam()
    {

    } // TODO

    // G2a

    public function g2aAutoMatcher(Request $request)
    {
        $this->validate($request, [
            "game_id" => "required|numeric",
        ]);

        $game = Game::find($request->game_id);

        if ($game == null) {
            return ["success" => false, "code" => 1, "message" => "Invalid game id.", "input" => ["game_id" => $request->game_id]];
        }

        if ($this->g2aAutoMatch($game) == false) {
            return ["success" => false, "code" => 2, "message" => "No match found", "data" => ["game" => [
                "id" => $game->id,
                "name" => $game->name,
                "type" => $game->type,
                "g2a_id" => $game->g2a_id
            ]]];;
        } else {
            return ["success" => true, "data" => ["game" => [
                "id" => $game->id,
                "name" => $game->name,
                "type" => $game->type,
                "g2a_id" => $game->g2a_id
            ]]];
        }

    }

    public function g2aAutoMatch($game)
    {

        // Search G2a For any matches
        $results = resolve("App\External\G2aApi")->searchByPhrase($game->name);

        if (isset($results["perfect_match"]) && $results["perfect_match"] != false) {
            $game->g2a_id = $results["perfect_match"]["id"];
            $game->save();
            return true;
        } else {
            $game->g2a_id = 0;
            $game->save();
            return false;
        }
    }

    public function g2aUpdatePrice(Request $request)
    {
        $this->validate($request, [
            "game_id" => "required|numeric",
            "hours" => "required|numeric"
        ]);

        $game = Game::find($request->game_id);
        if ($game == null) {
            return ["success" => false, "code" => 0, "message" => "Game was not found.", "data" => ["id" => $request->game_id]];
        }

        $g2a = resolve("App\External\G2aApi");
        $prices = DB::table("game_store")
            ->where("game_id", $game->id)
            ->where("store_id", $g2a->getStore()->id)
            ->where("created_at", '>=', Carbon::now()->subHours($request->hours)->toDateTimeString())
            ->get();

        // Check if the request contains hours flag. If it's greater than 0, check if we have the prices already
        if ($request->hours > 0 && count($prices) > 0) {
            return [
                "success" => false,
                "code" => 1,
                "message" => "Already have new enough price ({$request->hours} old)",
                "data" => $game,
                "prices" => $prices
            ];

        } else {
            // Save price
            $price = $g2a->fetchPrice($game->g2a_id);
            $game->prices()->attach($g2a->getStore(), ["price" => $price]);
            return [
                "success" => true,
                "data" => $game,
                "price" => $price
            ];
        }
    }

    // Crud

    public function storeGame($id)
    {
        // Get the data
        $steam = resolve("App\External\Steam");

        $json = $steam->parseAppData($id);
        $json["data"]["steam_id"] = $id;
        $content = $json["data"];

        // Check if we have the game
        $packages = null;
        $game = Game::where("steam_id", $id)->where("type", "!=", "package")->first();
        // If the game is not in the db, create it.

        // Check if the data is good
        if ($json["success"] == false) {
            // Check what kind of error it was
            if ($json["code"] == 4) {
                // Steam didn't have anything for us. If we aleady have it, let's update it.
                if ($game != null) {
                    $game->public = 0;
                    $game->save();
                }
            }
            return $json;
        }

        // Make sure we have the game, if not, let's make it.
        if ($game == null) {
            $game = new Game;
            $game->steam_id = $id;
        }
        $game->name = $content['name'];
        $game->type = $content['type'];

        if ($game->type == "game" || $game->type == "dlc") {
            $game->public = 1;

            $game->description = isset($content['detailed_description']) ? $content['detailed_description'] : null;
            $game->about_the_game = isset($content['about_the_game']) ? $content['about_the_game'] : null;
            $game->short_description = isset($content['short_description']) ? $content['short_description'] : null;

            $game->platform_windows = isset($content['platforms']["windows"]) ? $content['platforms']["windows"] : null;
            $game->platform_mac = isset($content['platforms']["mac"]) ? $content['platforms']["mac"] : null;
            $game->platform_linux = isset($content['platforms']["linux"]) ? $content['platforms']["linux"] : null;

            $game->req_win_min = isset($content['pc_requirements']['minimum']) ? $content['pc_requirements']['minimum'] : null;
            $game->req_win_rec = isset($content['pc_requirements']['recommended']) ? $content['pc_requirements']['recommended'] : null;
            $game->req_mac_min = isset($content['mac_requirements']['minimum']) ? $content['mac_requirements']['minimum'] : null;
            $game->req_mac_rec = isset($content['mac_requirements']['recommended']) ? $content['mac_requirements']['recommended'] : null;
            $game->req_lin_min = isset($content['linux_requirements']['minimum']) ? $content['linux_requirements']['minimum'] : null;
            $game->req_lin_rec = isset($content['linux_requirements']['recommended']) ? $content['linux_requirements']['recommended'] : null;

            $game->website = isset($content['website']) ? $content['website'] : null;
            $game->legal_notice = isset($content['legal_notice']) ? $content['legal_notice'] : null;

            $game->is_free = isset($content['is_free']) ? $content['is_free'] : null;
            $game->full_game = isset($content['full_game']) ? $content['full_game'] : null;
            $game->required_age = isset($content['required_age']) ? $content['required_age'] : null;
            $game->support_url = isset($content['support_info']["url"]) ? $content['support_info']["url"] : null;
            $game->support_email = isset($content['support_info']["email"]) ? $content['support_info']["email"] : null;
            $game->external_account = isset($content['ext_user_account_notice']) ? $content['ext_user_account_notice'] : null;
            $game->controller_support = isset($content['controller_support']) && $content['controller_support'] == "full" ? true : false;

            if (isset($content['release_date']["date"])) {
                try {
                    $game->release_date = new Carbon($content['release_date']["date"]);
                } catch (\Exception $e) {
                    $game->release_date = $content['release_date']["date"];
                }

            }

            $game->save();

            // Add images
            if (isset($content['header_image']) && !Image::where('game_id', $game->id)->where("url", $content['header_image'])->exists()) {
                $image = new Image;
                $image->type = "header_image";
                $image->url = $content['header_image'];
                $image->image_themes_id = 1;
                $game->images()->save($image);
            }
            if (isset($content['background']) && !Image::where('game_id', $game->id)->where("url", $content['background'])->exists()) {
                $image = new Image;
                $image->type = "background";
                $image->url = $content['background'];
                $image->image_themes_id = 1;
                $game->images()->save($image);
            }

            if (!Metacritic::where("game_id", $game->id)->exists() && isset($content['metacritic']['score']) && isset($content['metacritic']['url'])) {

                $metacritic = new Metacritic;
                $metacritic->score = $content['metacritic']['score'];
                $metacritic->url = $content['metacritic']['url'];
                $game->metacritics()->save($metacritic);
            }

            if (isset($content['supported_languages'])) {
                foreach ($content['supported_languages'] as $item) {

                    // Get the language ID
                    $language = Language::firstOrCreate(["name" => $item]);

                    // Let's see if this game already has this language
                    $game->languages()->syncWithoutDetaching([$language->id]);
                }
            }
            if (isset($content['publishers'])) {
                foreach ($content['publishers'] as $item) {
                    // Check if the publisher is already in the database.
                    $publisher = Publisher::firstOrCreate(["name" => $item]);

                    // Let's see if this game already has this category
                    $game->publishers()->syncWithoutDetaching([$publisher->id]);
                }
            }
            if (isset($content['developers'])) {
                foreach ($content['developers'] as $item) {
                    // Check if the developer is already in the database.
                    $developer = Developer::firstOrCreate(["name" => $item]);

                    $game->developers()->syncWithoutDetaching([$developer->id]);

                }
            }
            if (isset($content['categories'])) {
                foreach ($content['categories'] as $item) {
                    // Check if the category is already in the database.
                    $category = Category::firstOrCreate(
                        [
                            "name" => $item["description"],
                            "id" => $item["id"]
                        ]
                    );

                    // Let's see if this game already has this category
                    $game->categories()->syncWithoutDetaching([$category->id]);
                }
            }
            if (isset($content['genres'])) {
                foreach ($content['genres'] as $item) {
                    // Check if the genre is already in the database.
                    $genre = Genre::firstOrCreate(
                        [
                            "name" => $item["description"],
                            "id" => $item["id"]
                        ]
                    );

                    // Let's see if this game already has this genre
                    $game->genres()->syncWithoutDetaching([$genre->id]);
                }
            }
            if (isset($content['screenshots'])) {
                foreach ($content['screenshots'] as $item) {
                    // Get the screenshot
                    $screenshot = Screenshot::where("url", "=", $item['path_full'])->first();
                    if ($screenshot == null) {
                        // The screenshot isn't in the DB. Let's add it.
                        $screenshot = new Screenshot;
                        $screenshot->thumbnail = $item['path_thumbnail'];
                        $screenshot->url = $item['path_full'];
                        $game->screenshots()->save($screenshot);
                    }
                }
            }
            if (isset($content['movies'])) {
                foreach ($content['movies'] as $item) {
                    // Get the movie ID
                    $movie = Movie::where("movie_id", "=", $item['id'])->first();
                    if ($movie == null) {
                        // The screenshot isn't in the DB. Let's add it.
                        $movie = new Movie;
                        $movie->movie_id = $item['id'];
                        $movie->name = $item['name'];
                        $movie->thumbnail = $item['thumbnail'];
                        $movie->webm_sd = $item['webm']['480'];
                        $movie->webm_hd = $item['webm']['max'];
                        $movie->highlight = $item['highlight'];

                        $game->movies()->save($movie);
                    }
                }
            }

            if (isset($content['packages'])) {
                foreach ($content['packages'] as $pid) {
                    // Check if the package is already in the database.
                    $package = Game::where("steam_id", $pid)->where("type", "package")->first();

                    if ($package != null) {
                        continue;
                    }

                    // Save package, get info later
                    $package = new Game();
                    $package->steam_id = $pid;
                    $package->public = -1;
                    $package->name = "";
                    $package->type = "package";
                    $package->save();

                    $packages[] = $package;

                }
            }
        } else {
            $game->public = 0;
            $game->save();
        }

        return [
            "success" => true,
            "data" => $game,
            "packages" => $packages
        ];
    }

    public function storePackage($id)
    {
// Check if we have the package.
        $package = Game::where("steam_id", $id)->where("type", "package")->first();
        if ($package == null) {
            // If not, make it. (don't save it though)
            $package = new Game;
            $package->type = "package";
            $package->public = -1;
            $package->steam_id = $id;
        }

        // Get the data from steam
        $json = resolve("App\External\Steam")->parsePackageData($id);

        // Verify the data is good
        if ($json["success"] == false) {
            // Check what kind of error it was
            if ($json["code"] == 4) {
                // Steam didn't have anything for us. If we aleady have it, let's update it.
                if ($package != null) {
                    $package->public = 0;
                    $package->save();
                }
            }
            return $json;
        }

        // Store steam id
        $json["data"]["steam_id"] = $id;
        $content = $json["data"];

        $package->name = $content['name'];
        $package->description = isset($content['page_content']) ? $content['page_content'] : null;
        $package->controller_support = isset($content["controller"]["full_gamepad"]) ? $content["controller"]["full_gamepad"] : null;
        $package->platform_windows = isset($content['platforms']["windows"]) ? $content['platforms']["windows"] : null;
        $package->platform_mac = isset($content['platforms']["mac"]) ? $content['platforms']["mac"] : null;
        $package->platform_linux = isset($content['platforms']["linux"]) ? $content['platforms']["linux"] : null;
        $package->save();

        // Add images
        if (isset($content['header_image']) && !Image::where('game_id', $package->id)->where("url", $content['header_image'])->exists()) {
            $image = new Image;
            $image->type = "header_image";
            $image->url = $content['header_image'];
            $image->image_themes_id = 1;
            $package->images()->save($image);
        }

        if (isset($content['page_image']) && !Image::where('game_id', $package->id)->where("url", $content['page_image'])->exists()) {
            $image = new Image;
            $image->type = "package_image_large";
            $image->url = $content['page_image'];
            $image->image_themes_id = 1;
            $package->images()->save($image);
        }

        if (isset($content['small_logo']) && !Image::where('game_id', $package->id)->where("url", $content['page_image'])->exists()) {
            $image = new Image;
            $image->type = "package_image_small";
            $image->url = $content['small_logo'];
            $image->image_themes_id = 1;
            $package->images()->save($image);
        }

        // Get the package contents
        $gamesInPackage = null;

        // Verify that there are some apps
        if (!isset($content['apps'])) {

            $package->public = false;
            $package->save();

            return [
                "success" => false,
                "data" => $package,
                "message" => "There were no games in this package"
            ];
        }

        foreach ($content['apps'] as $appid) {
            // Check if the game is in the database.
            $game = Game::where("steam_id", $appid['id'])->where("type", "!=", "package")->first();

            if ($game == null) {
                // Don't have it. Have to get it first!
                $game = $this->storeApp($appid['id']);
            }

            // Add to pivot table.
            $packageContent = PackageContent::firstOrCreate([
                "package_id" => $package->id,
                "content_id" => $game->id
            ]);

            $gamesInPackage[] = $game;
        }

        // Check if only one in package- if so, set public to false
        $package->public = count($gamesInPackage) > 1 ? true : false;
        $package->save();

        return [
            "success" => true,
            "data" => $package,
            "contents" => $gamesInPackage
        ];
    }

    public function create()
    {
        return view("games.create");
    }

    public function store()
    {
        return back()->withInput();
    }

    public function edit($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        //
    }

    public function destroy($id)
    {
        // There is no deleting games.
        // Deleting a game means setting public to false.

        return back();
    }
}
<file_sep>/resources/views/home.blade.php
@extends('main')
@section('title')

@section('content')

            The homepage is under construction.

        View All Games

@endsection<file_sep>/routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get("/test", function(){
    return view("test");
});

Route::post('conversation/insert/user', 'MessageController@insertUserIntoConversation');
Route::post('conversation/create/message', 'MessageController@createMessage')->name("message.create");
Route::post('conversation/create', 'MessageController@createConversation')->name("conversation.create");
Route::post('conversation/get/all', 'MessageController@getUsersConversations');

//Route::post('message/send', 'MessageController@sendMessage')->name('message.send');
//Route::post('message/send_new', 'MessageController@sendNewMessage')->name('message.new');
//Route::post('message/get_conversation', 'MessageController@getConversation')->name('message.convo');
//Route::post('message/get_conversations', 'MessageController@getConversations')->name("messages.convos");
//Route::delete('message/delete/{id}', 'MessageController@deleteMessage')->name('message.delete');
Route::get("/messages", 'MessageController@index');

Route::get("/user/{id}", 'GameController@userProfile');

Route::get("/library", 'GameController@showLibrary')->name("games.library");
Route::get("/inventory", 'GameController@showInventory')->name("games.inventory");
Route::get("/wishlist", 'GameController@showWishlist')->name("games.wishlist");
Route::get('/search', 'GameController@search');

Route::get('/games/sync_applist_from_steam', 'GameController@SyncApplistTest');
Route::get('/games/store/{id}', 'GameController@storeGame');
Route::get('/games/store_package/{id}', 'GameController@storePackage');
Route::post('/games/auto_match', 'GameController@g2aAutoMatcher');
Route::post('/games/update_wishlist', 'GameController@updateWishlist');
Route::resource('games', 'GameController');

Route::resource('purchases', 'PurchaseController');
Route::post('/purchase/get_purchases', 'PurchaseController@getPurchases');
Route::post('/purchase/update_availability', 'PurchaseController@updateAvailability');
Route::post('/purchase/update_purchase_price', 'PurchaseController@updatePurchasePrice');
Route::post('/purchase/update_purchase_item_price', 'PurchaseController@updatePurchaseItemPrice');
Route::post('/purchase/insert_game', 'PurchaseController@insertGamesIntoPurchase');
Route::post('/purchase/insert_bundle', 'PurchaseController@addBundleToPurchase');
Route::post('/purchase/action', 'PurchaseController@massAction');
Route::post('/purchase/insert_bundle', 'PurchaseController@addBundleToPurchase');

Route::resource('bundles', 'BundleController');
Route::post('/bundles/change_tier','BundleController@changeTier')->name("bundle.change_tier");
Route::post('/bundles/link_game_bundle', 'BundleController@linkGameToBundle')->name("bundle.link_game_bundle");

Route::get("/settings", "SettingsController@index");
Route::get("settings/connections", "SettingsController@showConnections");
Route::post("settings/toggle_g2a", "SettingsController@toggleG2a")->name("settings.toggle_g2a");
Route::get("settings/g2a_auto_matcher", "SettingsController@g2aAutoMatcher");
Route::get("settings/g2a_price_updater", "SettingsController@g2aPriceUpdater");
Route::post("settings/g2a_update_price", "GameController@g2aUpdatePrice");
Route::get("settings/myaccount", "SettingsController@showMyAccount");
Route::get("settings/edit_icons", "SettingsController@editIcons");
Route::post("settings/update_icon", "IconController@update");
Route::post("settings/new_icon", "IconController@store");
Route::get("settings/update_database_games", "GameController@updateGames");
Route::get("settings/update_database_packages", "GameController@updatePackages");

Route::get('auth/steam', 'AuthController@redirectToSteam')->name('auth.steam');
Route::get('auth/steam/handle', 'AuthController@handle')->name('auth.steam.handle');
Route::post('logout', 'Auth\LoginController@logout')->name('logout');
Auth::routes();

Route::get("/", "GameController@index");
//Route::get("/", "GameController@home");

<file_sep>/app/Http/Controllers/SettingsController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;

use App\User;
use App\Game;
use App\Icon;

class SettingsController extends Controller
{
    public function index(){
        if (!Auth::check()) {
            Session::flash("message-info", "You must be logged in to use this feature");
            return Redirect::route("login");
        }

        return view("settings.myaccount");
    }

    public function editIcons(){
        return view("settings.icons")->withIcons(Icon::all());
    }

    public function showConnections(){
        return view("settings.connections");
    }

    public function showMyAccount(){
        return view("settings.myaccount");
    }

    public function toggleG2a(Request $request){
        $this->validate($request, [
            "user_id" => "numeric"
        ]);

        // Get user and verify they exist
        $user = User::find($request->user_id);
        if($user == null){
            Session::flash("message-danger", "User not found.");
        }

        // Toggle
        if($user->checkRole("G2a")){
            // They have the role, get rid of it
            Session::flash("message-success", "G2a has been removed from your account.");
            $user->detachRole("G2a");
        }
        else{
            // They don't have the role, add it
            Session::flash("message-success", "G2a has been added to your account.");
            $user->attachRole("G2a");
        }

        return back();
    }

    public function g2aPriceUpdater(){
        return view("settings.g2a_price_updater")->withGames(Game::whereNotNull("g2a_id")->where("g2a_id",">",0)->where("public",1)->get());
    }

    public function g2aAutoMatcher(){

        ini_set('memory_limit', '-1');

        return view("settings.g2a_auto_matcher")->withGames(Game::whereNull("g2a_id")->where("public",1)->pluck("id")->toArray());
    }
}
<file_sep>/app/PackageContent.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class PackageContent extends Model
{
    public $fillable = ["package_id","content_id"];

    public function games()
    {
        return $this->belongsTo('App\Game', 'game_id', 'package_id');
    }
}
<file_sep>/resources/views/auth/login.blade.php
@extends('main')
@section('title', ' | Login')
@section('content')

Sign in

                <form class="form" role="form" method="POST" action="{{ route('login') }}">
                    {{ csrf_field() }}

has('email') ? ' has-error' : '' }}">

                            Email address
                            <input id="email"
                                   name="email"
                                   value="{{ old('email') }}"
                                   type="email" class="form-control"
                                   placeholder="Enter email"
                                   required
                                   autofocus>

                                Password

                                    (Forgot)

                            <input id="password" name="password" type="<PASSWORD>" class="form-control"
                                   id="<PASSWORD>" placeholder="<PASSWORD>" required>

                                <input type="checkbox" class="form-check-input"
                                       name="remember" {{ old('remember') ? 'checked' : '' }}>
                                Remember me on this computer

                    <button type="submit" class="btn btn-secondary" style="width:100%;">
                        Login
                    </button>
                </form>

Register

                <form class="form-horizontal" role="form" method="POST" action="{{ route('register') }}">
                    {{ csrf_field() }}

                    @if(isset($info))
                        {!! var_dump($info) !!}
                        <input type="hidden" name="steamid" value="{{ $info->steamID64 }}">
                        <input type="hidden" name="avatar" value="{{ $info->avatar }}">
                    @endif

                        Email
                        <input id="email" type="email" class="form-control" name="email"
                               value="{{ old('email') }}" required>

                        Name
                        <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}"
                               required>

                        Password
                        <input id="password" type="<PASSWORD>" class="form-control" name="password" required>

                        Confirm Password
                        <input id="password-confirm" type="<PASSWORD>" class="form-control"
                               name="password_confirmation" required>

                    <button type="submit" class="btn btn-secondary" style="width:100%;">
                        Register
                    </button>
                </form>

@endsection
<file_sep>/resources/assets/js/components/MessengerComposer.vue
<template>

            <input style="float:left;width:75%;border:none;background-color:transparent;" type="text" class="form-control" placeholder="Type your message" v-model="composerText" @keydown.enter="sendMessage">
            <button style="float:left;width:25%;" class="btn btn-secondary btn" @click="sendMessage">SEND</button>

</template>

<file_sep>/app/External/G2aApi.php
<?php
/**
 * Created by PhpStorm.
 * User: johnorlando
 * Date: 7/27/2017
 * Time: 10:06 PM
 */

namespace App\External;

use App\G2a;
use App\Store;

class G2aApi{

    public $store = null;

    protected $urls = [
        "search" => "http://www.g2a.com/lucene/search/quick?phrase=",
        "price" => "https://www.g2a.com/marketplace/product/auctions/?id="
    ];

    public function getStore(){
        if($this->store == null){
            $this->store = Store::firstOrCreate(["name" => "G2a"]);
        }
        return $this->store;
    }

    public function searchByPhrase($phrase){
        // Format the phrase

        // Remove special characters and make lowercase
        $searchTerm = trim(strtolower(preg_replace("/[^-a-zA-Z0-9_': ]/", '', $phrase)));

        // Make sure the phrase isn't empty
        if($searchTerm == null || $phrase == ""){
            return false;
        }

        // Get JSON
        $url = $this->urls["search"] . urlencode($searchTerm);
        $json = json_decode(file_get_contents($url), true);

        // Prepare result

        $results = ["results" => $json["docs"], "input" => $phrase];
        foreach ($results["results"] as $key => $result) {
            if (!isset($result["name"])) {
                continue;
            }
            if ($this->checkIfPerfectMatch($phrase, $result['name'])) {
                $results["perfect_match"] = $result;
            }

            // Always save all G2A's
            $this->saveG2a($result);
        }
        return $results;
    }

    public function fetchPrice($gid){
        // Get data from G2a
        $url = $this->urls["price"] . $gid;
        $content = file_get_contents($url);
        $json = json_decode($content, true);

        // Insert new price into database
        if(isset($json['a'])){
            // There is pricing data
            foreach ($json['a'] as $chunk) {
                // Just want the newest price.
                break;
            }
        }
        else{
            return false;
        }

        // Return the new price
        return $chunk["p"];
    }

    public function saveG2a($result){
        $g2a = G2a::find($result["id"]);
        if($g2a == null){
            $g2a = new G2a();
            $g2a->id = $result["id"];
            $g2a->name = $result['name'];
            $g2a->slug = $result['slug'];
            if (array_key_exists('thumbnail', $result)) {
                $g2a->thumbnail = $result['thumbnail'];
            }
            if (array_key_exists('smallImage', $result)) {
                $g2a->smallImage = $result['smallImage'];
            }
            if (array_key_exists('bigSearchImage', $result)) {
                $g2a->bigSearchImage = $result['bigSearchImage'];
            }
            $g2a->save();
        }
        return $g2a;
    }

    public function checkIfPerfectMatch($userPhrase, $g2aPhrase){
        // Make lowercase, trim, and get rid of all special chars
        $g2aPhrase = trim(strtolower(preg_replace("/[^a-zA-Z0-9 ]/", '', $g2aPhrase)));
        $userPhrase = trim(strtolower(preg_replace("/[^a-zA-Z0-9 ]/", '', $userPhrase)));

        //take the game's name out of it
        $remainder = trim(str_replace($userPhrase, "", $g2aPhrase));
        //take "STEAM CD-KEY GLOBAL: out. it's cdkey and not cd-key because we removed special characters
        $remainder = trim(str_replace("steam cdkey global", "", $remainder));
        //take "STEAM CD-KEY GLOBAL: out. it's cdkey and not cd-key because we removed special characters
        $remainder = trim(str_replace("steam key global", "", $remainder));
        // Remove "EARLY ACCESS"
        $remainder = trim(str_replace("early access", "", $remainder));

        // If there's nothing left, it's the right game.
        return  $remainder == "" ? true : false;
    }
}<file_sep>/resources/views/settings/myaccount.blade.php
@extends('settings.index')

@section('settings-content')

My Account

                Name
                {{Auth::user()->name}}

                Email
                {{Auth::user()->email}}

                Type

                    @foreach(Auth::user()->roles as $role)
                        {!! $role->name !!}

                    @endforeach

    @php($isEnabled = Auth::check() && Auth::user()->checkRole("g2a"))

            G2a Settings
            {!! App\Icon::find("circle")->wrap(["color" => $isEnabled ? "green" : "red"]) !!}

        <form class="form" method="POST" action="{!! route("settings.toggle_g2a") !!}">
            {{ csrf_field() }}
            <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">
            {{-- Check if the user has access --}}
            @if($isEnabled)
                <button class="btn btn-danger col-xs-12 col-lg-3 col-xl-2">Disable G2A</button>

            @else

                    Caution!
                    G2a is a gray market website. You can read more about them here (coming soon).
                    Enabling this feature will allow you to track and view G2A values for your games.

                <button class="btn btn-primary col-xs-12 col-lg-3 col-xl-2">Enable G2A</button>
            @endif
        </form>

    @php($isEnabled = Auth::check() && Auth::user()->checkSteam())

            Steam Settings
            {!! App\Icon::find("circle")->wrap(["color" => $isEnabled ? "green" : "red"]) !!}

        <form class="form" method="POST" action="{!! route("settings.toggle_g2a") !!}">
            {{ csrf_field() }}
            <input type="hidden" name="user_id" value="{!! Auth::user()->id !!}">
            {{-- Check if the user has access --}}
            @if($isEnabled)
                <button class="btn btn-danger col-xs-12 col-lg-3 col-xl-2">Unlink Steam Account</button>
            @else

                    Caution!
                    You will be redirected to Steam.

                    Sign into Steam

            @endif
        </form>

@endsection
<file_sep>/resources/views/partials/_footer.blade.php

        Copyright © {!! date("Y") !!} SteamGM.com

<file_sep>/app/Conversation.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Conversation extends Model
{
    public function messages(){
        return $this->hasMany("App\Message");
    }

    public function users(){
        return $this->belongsToMany("App\User");
    }

    public function getMostRecentMessageTimestampAttribute(){
        return $this->messages()->orderBy("created_at", 'desc')->pluck("created_at")->first();
    }
}
<file_sep>/resources/views/games/games_printer.blade.php
@php

    if(isset($_GET['display_type'])){
        session()->put('display_type', $_GET['display_type']);
        unset($_GET['display_type']);
    }
    $defaultSettings = [
        "display_type" => session()->has('display_type') ? session()->get('display_type') : "grid",
        "print_advanced" => false,
    ];

    $settings = isset($settings) ? array_merge ($defaultSettings, $settings) : $defaultSettings;
@endphp

    {{-- Print advanced search --}}
    @if($settings["print_advanced"])
        <form class="form" id="advanced-search" style="width:100%;padding:10px;padding-top:30px;">

                    <input type="text"
                           class="form-control"
                           id="form-keyword"
                           name="keywords"
                           placeholder="Search Term: Ex. 'Grand Theft Auto V'"
                           value="{{
                                isset($_GET['keywords']) ? $_GET['keywords'] : null
                           }}">

                    <button class="btn btn-primary" style="width:100%;" type="submit">Search</button>

                    Advanced

                        Type

                                    @php($type = isset($_GET['types']) ? $_GET['types'] : null)
                                    <input
                                            {!! isset($_GET['types']) && in_array("game",$_GET['types']) ? "checked" : "" !!}
                                            class="form-check-input"
                                            type="checkbox"
                                            id="form-type"
                                            name="types[]"
                                            value="game"> Game

                                    <input
                                            {!! isset($_GET['types']) && in_array("dlc",$_GET['types']) ? "checked" : "" !!}
                                            class="form-check-input"
                                            type="checkbox"
                                            id="form-type"
                                            name="types[]"
                                            value="dlc"> DLC

                                    <input
                                            {!! isset($_GET['types']) && in_array("package",$_GET['types']) ? "checked" : "" !!}
                                            class="form-check-input"
                                            type="checkbox"
                                            id="form-type"
                                            name="types[]"
                                            value="package">Package

                        Genre
                        <select multiple class="form-control" id="filter-genre" name="genres[]">
                            @foreach(App\Genre::all() as $genre)
                                <option value="{{$genre->id}}"
                                        {{isset($_GET['genres']) && in_array($genre->id, $_GET['genres'])
                                        ? "selected"
                                        : ""
                                        }}
                                >{{$genre->name}}</option>
                            @endforeach
                        </select>

                        Category
                        <select multiple class="form-control" id="filter-category" name="categories[]">
                            @foreach(App\Category::all() as $category)
                                <option value="{{$category->id}}"
                                        {{isset($_GET['categories']) && in_array($category->id, $_GET['categories'])
                                        ? "selected"
                                        : ""
                                        }}
                                >{{$category->name}}</option>
                            @endforeach
                        </select>

                        Language
                        <select multiple class="form-control" id="filter-language" name="languages[]">
                            @foreach(App\Language::all() as $language)
                                <option value="{{$language->id}}"
                                        {{isset($_GET['languages']) && in_array($language->id, $_GET['languages'])
                                        ? "selected"
                                        : ""
                                        }}
                                >{{$language->name}}</option>
                            @endforeach
                        </select>

                        Developer
                        <select multiple class="form-control" id="filter-developer" name="developers[]">
                            @foreach(App\Developer::all() as $developer)
                                <option value="{{$developer->id}}"
                                        {{isset($_GET['developers']) && in_array($developer->id, $_GET['developers'])
                                        ? "selected"
                                        : ""
                                        }}

                                >{{$developer->name}}</option>
                            @endforeach
                        </select>

                        Publisher
                        <select multiple class="form-control" id="filter-publisher" name="publishers[]">
                            @foreach(App\Publisher::all() as $publisher)
                                <option value="{{$publisher->id}}"
                                        {{isset($_GET['publishers']) && in_array($publisher->id, $_GET['publishers'])
                                        ? "selected"
                                        : ""
                                        }}
                                >{{$publisher->name}}</option>
                            @endforeach
                        </select>

                    <button class="btn" style="width:100%;" type="reset">Reset</button>

                            <input type="radio"
                                   form="advanced-search"
                                   name="display_type"
                                   value="grid"
                                   autocomplete="off"
                                   onchange="this.form.submit()">

                            <input type="radio"
                                   form="advanced-search"
                                   name="display_type"
                                   value="list"
                                   autocomplete="off"
                                   onchange="this.form.submit()">

                    Sort By
                    <select
                            form="advanced-search"
                            class="form-control form-control-sm"
                            id="sorting"
                            name="sorting"
                            onchange="this.form.submit()">
                        <option value="name-asc" {{isset($_GET['sorting']) && $_GET['sorting'] == "name-asc" ? "selected" : ""}}>
                            A-Z
                        </option>
                        <option value="name-desc" {{isset($_GET['sorting']) && $_GET['sorting'] == "name-desc" ? "selected" : ""}}>
                            Z-A
                        </option>
                    </select>

                    Results
                    <select
                            form="advanced-search"
                            class="form-control form-control-sm"
                            id="sorting"
                            name="display"
                            onchange="this.form.submit()">
                        <option value="12" {{isset($_GET['display']) && $_GET['display'] == "12" ? "selected" : ""}}>
                            12
                        </option>
                        <option value="24" {{isset($_GET['display']) && $_GET['display'] == "24" ? "selected" : ""}}>
                            24
                        </option>
                        <option value="36" {{isset($_GET['display']) && $_GET['display'] == "36" ? "selected" : ""}}>
                            36
                        </option>
                    </select>

        </form>
    @endif

    {{-- Print the games --}}

    @if($settings["display_type"] == "grid")
        @foreach($games as $key => $game)

                headerImage()->url !!}"
                     alt="Card image cap">

                    id}}"
                       class="card-title game-title" style="font-size:1.3em;">
                        {!! $game->name !!}

                    @if(Auth::user())
                        @if(Auth::user()->isIn($game->id, "inventory"))
                            @php($icon = App\Icon::find("archive"))

                                {!! $icon->wrap() !!}

                        @endif

                        @if(Auth::user()->isIn($game->id, "library"))
                            @php($icon = App\Icon::find("book"))

                                {!! $icon->wrap() !!}

                        @endif

                            @if(Auth::user()->isIn($game->id, "wishlist"))
                                @php($icon = App\Icon::find("gift"))

                                    {!! $icon->wrap() !!}

                            @endif

                    @endif

                @if(Auth::check() && Auth::user()->checkRole("g2a") && ($price = $game->prices->sortByDesc("created_at")->first()))

                        {!! money($game->newest_g2a_price) !!}

                @endif

        @endforeach
    @elseif($settings["display_type"] == "list")

            @foreach($games as $key => $game)

                        @if(Auth::user() && Auth::user()->isIn($game->id, "inventory"))

                                {!! App\Icon::find("archive")->wrap() !!}

                        @endif

                        @if(Auth::user() && Auth::user()->isIn($game->id, "library"))

                                {!! App\Icon::find("book")->wrap() !!}

                        @endif

                        id}}">{!! $game->name !!}

                        {!! $game->type != "game" ? $game->type : ""!!}

                        @if(Auth::check() && Auth::user()->checkRole("g2a") && ($price = $game->prices->sortByDesc("created_at")->first()))

                            {!! money($price->pivot->price) !!}

                        @endif

            @endforeach

    @endif

@if($games instanceof \Illuminate\Pagination\LengthAwarePaginator )

        {{$games->appends(Request::except("page"))->links("vendor.pagination.bootstrap-4")}}

@endif<file_sep>/app/Game.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Game extends Model
{
    public $fillable = ["steam_id", "type"];

    // Relationships
    public function metacritics()
    {
        return $this->hasOne('App\Metacritic');
    }

    public function g2a()
    {
        return $this->hasOne('App\G2a', 'id', 'g2a_id');
    }

    public function bundles()
    {
        return $this->belongsToMany('App\Bundle')->withPivot("tier", "id");
    }

    public function prices()
    {
        return $this->belongsToMany('App\Store', 'game_store')->withPivot("price")->withTimestamps();
    }

    public function getNewestG2aPriceAttribute(){
        if(($price = $this->prices->sortByDesc("created_at")->first())){
            return $price->pivot->price;
        }
        else{
            return false;
        }
    }

    public function purchases()
    {
        return $this->belongsToMany('App\Purchase');
    }

    public function languages()
    {
        return $this->belongsToMany('App\Language');
    }

    public function developers()
    {
        return $this->belongsToMany('App\Developer');
    }

    public function publishers()
    {
        return $this->belongsToMany('App\Publisher');
    }

    public function categories()
    {
        return $this->belongsToMany('App\Category');
    }

    public function genres()
    {
        return $this->belongsToMany('App\Genre');
    }

    public function movies()
    {
        return $this->hasMany('App\Movie');
    }

    public function screenshots()
    {
        return $this->hasMany('App\Screenshot');
    }

    public function images()
    {
        return $this->hasMany('App\Image');
    }

    public function headerImage(){

        $headerImage = $this->images->where("type","header_image")->first();

        if($headerImage == null){
            $headerImage = new Image();
            $headerImage->url = "../images/empty_banner.gif";
        }
        return $headerImage;
    }

    public function packageContents()
    {
        return $this->hasMany('App\PackageContent', 'package_id');
    }

    public function packages(){
        return Game::where(
            "public", "1")
            ->whereIn("id", PackageContent::where("content_id", $this->id)->pluck("package_id")->toArray())
            ->get();
    }

    public function dlc(){
        return Game::where(
            "public", "1")
            ->where()
            ->get();
    }

}
<file_sep>/app/Helpers/global_helpers.php
<?php

function money($value){
    return "$" . number_format($value, 2, '.', ',');
}

function console($value){
    echo "";
}<file_sep>/resources/views/settings/connections.blade.php
@extends('settings.index')

@section('settings-content')

@endsection
<file_sep>/resources/views/settings/g2a_price_updater.blade.php
@extends('settings.index')

@section('settings-content')

G2a Price Updater

        Number of games: <input id="counter" value="{!! count($games) !!}">

        Skip fetched prices (in hours): <input id="hours" value="0">

    <button class="btn" id="start">Start</button>

                ID
                Name
                GID
                Price

@endsection
<file_sep>/resources/views/games/game_import.blade.php

Game Importer

                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    ×
                </button>

                <input class="form-control" id="keyword" placeholder="Search (ex. Grand Theft Auto V)"
                       autocomplete="off">
                <select id="results" class="form-control" name="game_id">
                    <option>Results</option>
                </select>

                <button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="processImport($('#results').val(), from);">
                    Continue
                </button>

<file_sep>/resources/views/test.blade.php
@extends('main')
@section('title')

@section('content')

            <button class="btn btn-empty" onclick="$('#messenger-users').toggleClass('hidden')">

            </button>

        <messenger-users :conversations="conversations"></messenger-users>

        <messenger-messages :auth="auth"></messenger-messages>

@endsection<file_sep>/resources/views/settings/g2a_auto_matcher.blade.php
@extends('settings.index')

@section('settings-content')

G2a Auto Matcher

        Number of games:
        <input id="counter" value="{!! count($games) !!}">

    <button class="btn" id="start">Start</button>
    <button class="btn" id="stop" style="display:none;">Stop</button>

                ID
                Name
                Type
                GID

@endsection

languages: Vue JavaScript Blade PHP

repo_language: Vue