Riotsmurf

Riotsmurf

Member Since 2 Years Ago

Experience Points 1,520
Experience Level 1

3,480 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 10
Lessons
Completed
Best Reply Awards 0
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

11 Oct
9 months ago

Riotsmurf started a new conversation Need With Axios Call To Passport API

I am trying to use the api i made inside vuejs when a user is logged in. (but also use the api outside the app) and i keep getting the 401 unauthorized error. I have followed a few guides and i cannot get it to work.

This is the Kernel.php:

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
//             \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
        ],

        'api' => [
//            'throttle:60,1',
            'bindings',
        ],
    ];

As you can see i added the CreateFreshApiTokens::class to it.

config/auth.php:

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],

routes/api.php:

Route::prefix('/samples')->group(function(){
        Route::get("/" ,"Api\[email protected]");
        Route::get("/{sample_id}" ,"Api\[email protected]");
        Route::post("/" ,"Api\[email protected]");

        Route::get("/tests" ,"Api\[email protected]");
        Route::post("/tests" ,"Api\[email protected]");

        Route::get("/tests/analytes" ,"Api\[email protected]");
        Route::post("/tests/analytes" ,"Api\[email protected]");
    });

inside the controller _construct i am using $this->middleware('auth:api');

and this is my ajax:

axios.get('/api/v1/samples/5020122', {

                    params: {
                        get: "test",
                        find: "test"
                    }
                }).then(response => {
                    console.log(response);
                });

And its giving me a 401 response. I don't get it. Any ideas/questions would be super helpful.

01 Jun
1 year ago

Riotsmurf started a new conversation UUID Generation With Method UpdateOrCreate()

I am using a uuid generation class to make my uuids in the mysql db. How would i use updateOrCreate with that? Or should i just use find/save for updating or creating?

09 Apr
1 year ago

Riotsmurf started a new conversation Using Oauth To Login From Another App.

I am trying to learn a bit more about oauth. And i know google, facebook lets users log into other websites using their credentials. I want to do the same thing in my 2 apps. I have an app called Belit and an app called ConAn. I want users to log into ConAn using Belit's credentials. Does anyone have some good links to help me learn how to use it like this? I couldn't figure this out from the laravels docs site and i couldn't find a video here. Help and links would be appreciated.

08 Jan
1 year ago

Riotsmurf started a new conversation How To Properly Use 2-database Relationships?

Hello, I can't seem to figure out how to have a table in one database have a relationship with another table in a different database.

like Customer uses the 'directory' database.

namespace App\Models;

use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Customer extends Model
{
    use SoftDeletes;

    protected $connection = 'directory';
    public $fillable = [
        'id',
        'customer_type_id',
        'user_id'
    ];

    public function owners(){
        return $this->hasMany(User::class)->whereHas('roles', function($query){ $query->where('name', 'owner');});
    }
   public function employees(){
        return $this->hasMany(User::class)->whereHas('roles', function($query){ $query->where('name', 'employee');});
    }
}

Then in the User::class just uses the default 'mysql' database

namespace App;

use App\Models\Customer_form;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable, SoftDeletes;

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

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

    protected static function boot() {

        // create an event to happen on deleting
        static::deleting(function($user)  {
            $user->roles()->detach();
        });
    }

    public function roles()
    {
        return $this
            ->belongsToMany("App\Role")
            ->withPivot('id','can_read', 'can_create', 'can_update', 'can_delete');
    }

    public function customer(){

        return $this->belongsTo(App\Models\Customer::class, "customer_id", "id")->with("primaryName");
    }
}

Then i am calling this relationship in my controller like so:

$customerUsers = Customer::has('owners')->with('owners')->with('employees')->get();

Then it gives me an error like its trying to query just one of the databases looking for a table that doesn't exist in THAT database( "directory" )

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'directory.role_user' doesn't exist (SQL: select * from `customers` where exists (select * from `users` where `customers`.`id` = `users`.`customer_id` and exists (select * from `roles` inner join `role_user` on `roles`.`id` = `role_user`.`role_id` where `users`.`id` = `role_user`.`user_id` and `name` = owner)) and `customers`.`deleted_at` is null) ◀

Any idea what i am missing? Or can you not do cross-database relations?

24 Oct
1 year ago

Riotsmurf left a reply on Using Vuetifyjs V-data-table And Passing Data To It.

Now i reread what i posted and the table example i shared is actually 2 tables which will have 2 different sets of data, but they both need to be present. So i put them inside tabs to make it pretty and easy to look at. Even though the html is a little confusing. (its a work in progress) If you would like me to provide another example, i can.

Riotsmurf started a new conversation Using Vuetifyjs V-data-table And Passing Data To It.

Hello! I am having a problem deciding how i should use vuetify's awesome components and passing data to them from laravel.

Right now i am making a table the just lists active mods on the server. This is the HTML:

        <v-data-table v-bind:items='{{$mods->users}}'>
                    <template>
                        <tr>
                            <th>customer_id</th>
                            <th>name</th>
                            <th>email</th>
                            <th>deactivate/activate</th>
                        </tr>
                    </template>
                    <template slot="items">

                    </template>
                </v-data-table>

Now if you have used vuetifyjs before then you know this is not the correct way of passing data to the table. From what it looks like vuetify expects us to make a template. Then we can pass props to the table like in this example:

<template>
    <v-card>
        <v-card-title>
            <div class="title">Results</div>
            <v-spacer></v-spacer>
            <v-text-field
                    append-icon="search"
                    label="Search"
                    single-line
                    hide-details
                    v-model="search"
            ></v-text-field>
        </v-card-title>
        <v-tabs dark v-model="activeTab">
            <v-tabs-bar class="green darken-2">
                <v-tabs-item class="" href="#officialResults">Official Results</v-tabs-item>
                <v-tabs-item class="" href="#rndResults">RnD Results</v-tabs-item>
                <v-tabs-slider class="green lighten-4"></v-tabs-slider>
            </v-tabs-bar>
            <v-tabs-items>
                <v-tabs-content id="officialResults">
                    <v-data-table
                        v-bind:headers="headers"
                        v-bind:items="items"
                        v-bind:search="search"
                    >
                        <!--Hidden on mobile-->
                        <template slot="headers" scope="props">
                            <tr>
                                <th class="hidden-sm-and-down">Public/Private</th>
                                <th class="hidden-xs-only">Test date</th>
                                <th class="hidden-md-and-down">Lot#</th>
                                <th class="">QA#</th>
                                <th class="hidden-xs-only">Strain</th>
                                <th class="">Type</th>
                                <th class="hidden-xs-only">Canna. total</th>
                                <th class="">Pass/Fail</th>
                            </tr>
                        </template>calcurves
                        <template slot="items" scope="props">
                            <td class="text-xs-center text-md-center text-lg-center hidden-sm-and-down">
                                <v-switch v-bind:label="`${props.item.public ? 'Public' : 'Private'}`" v-model="props.item.public"></v-switch>
                            </td>
                            <td class="text-xs-center text-md-center text-lg-center hidden-xs-only">{{ props.item.test_date }}</td>
                            <td class="text-xs-center text-md-center text-lg-center hidden-md-and-down">{{ props.item.lot }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.qa }}</td>
                            <td class="text-xs-center text-md-center text-lg-center hidden-xs-only">{{ props.item.strain }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.type }}</td>
                            <td class="text-xs-center text-md-center text-lg-center hidden-xs-only">{{ props.item.canna_total }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.passfail }}</td>
                        </template>
                        <template slot="pageText" scope="{ pageStart, pageStop }">
                            From {{ pageStart }} to {{ pageStop }}
                        </template>
                    </v-data-table>
                </v-tabs-content>
                <v-tabs-content id="rndResults">
                    <v-data-table
                            v-bind:headers="headers"
                            v-bind:items="items"
                            v-bind:search="search">
                        <template slot="items" scope="props">
                            <td class="text-xs-center text-md-center text-lg-center">
                                <v-switch v-bind:label="`${props.item.public ? 'Public' : 'Private'}`" v-model="props.item.public"></v-switch>
                            </td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.test_date }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.lot }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.qa }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.strain }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.type }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.canna_total }}</td>
                            <td class="text-xs-center text-md-center text-lg-center">{{ props.item.passfail }}</td>
                        </template>
                        <template slot="pageText" scope="{ pageStart, pageStop }">
                            From {{ pageStart }} to {{ pageStop }}
                        </template>
                    </v-data-table>
                </v-tabs-content>
            </v-tabs-items>
        </v-tabs>
    </v-card>
</template>
<script>
    export default {
        data () {
            return {
                //tab "variables"
                activeTab: null,
                // table "variables"
                test: 0,
                max25chars: (v) => v.length <= 25 || 'Input too long!',
                tmp: '',
                search: '',
                pagination: {},
                headers: [
                    {
                        text:  'Public/Private',
                        classes:'hidden-sm',
                        align: 'center',
                        sortable: false,
                        value: 'public'
                    },
                    { text: 'Test Date', class:'hidden-sm', align: 'center', value: 'test_date' },
                    { text: 'Lot#', class:'hidden-sm', align: 'center', value: 'lot' },
                    { text: 'QA#', class:'hidden-sm', align: 'center', value: 'qa' },
                    { text: 'Strain Name', class:'hidden-sm', align: 'center', value: 'strain' },
                    { text: 'Sample Type', class:'hidden-sm', align: 'center', value: 'type' },
                    { text: 'Canna. Total', class:'hidden-sm', align: 'center', value: 'canna_total' },
                    { text: 'Pass/Fail', class:'hidden-sm', align: 'center', value: 'passfail' }
                ],
                items: [
                {
                    value: false,
                    public: false,
                    test_date: '10/06',
                    lot: 1234567890123456,
                    qa: '1234567890123456',
                    strain: 'Blue Dream',
                    type: 'Flower',
                    canna_total: '14%',
                    passfail: 'Pass'
                },{
                    value: false,
                    public: false,
                    test_date: '10/06',
                    lot: 1234567890123456,
                    qa: '1234567890123456',
                    strain: 'Blue Dream',
                    type: 'Flower',
                    canna_total: '14%',
                    passfail: 'Pass'
                },{
                    value: false,
                    public: false,
                    test_date: '10/06',
                    lot: 1234567890123456,
                    qa: '1234567890123456',
                    strain: 'Blue Dream',
                    type: 'Flower',
                    canna_total: '14%',
                    passfail: 'Pass'
                },{
                    value: false,
                    public: false,
                    test_date: '10/06',
                    lot: 1234567890123456,
                    qa: '1234567890123456',
                    strain: 'Blue Dream',
                    type: 'Flower',
                    canna_total: '14%',
                    passfail: 'Pass'
                },
            ]
        }
        },

    }
</script>

This table works perfectly -> now my blade looks like this:

@extends('layouts.app')
@section('content')
    <sample-result-table></sample-result-table>
@endsection

The javascript looks like this(just in case you were wondering):

window.Vue = require('vue');
import Vuetify from 'vuetify';
Vue.use(Vuetify);

Vue.component('nav-bar', require('./components/navbar.vue'));
Vue.component('nav-bar-admin', require('./components/navbarAdmin.vue'));
Vue.component('log-in', require('./components/login.vue'));
Vue.component('register', require('./components/register.vue'));
Vue.component('error-messages', require('./components/errorMessages.vue'));
Vue.component('success-message', require('./components/successMessage.vue'));
Vue.component('notice-message', require('./components/noticeMessage.vue'));
Vue.component('warning-message', require('./components/warningMessage.vue'));
Vue.component('fail-message', require('./components/failMessage.vue'));
Vue.component('sample-result-table', require('./components/resultsTable.vue'));

var app = new Vue({
    el: '#app',
    data: {
        windowSize: {
            x: 0,
            y: 0
        }
    },
    mounted () {
        this.onResize()
    },
    watch: {
        windowSize(){
            console.log(this.windowSize);
        }
    },
    methods: {
        onResize () {
            this.windowSize = { x: window.innerWidth, y: window.innerHeight }
        }
    }
});

This way later when i have real data, i can set up some props for the data and use this prop anywhere in my app because i will use it more than once. However the active mods table will only ever be used in one place(that we know of so far). but i WANT TO USE THE v-data-table because it brings in the easy sorting. What i am wondering is how can i avoid making a template every time i want a table and pass {{ $dataVariable }} to it. Specifically to the v-data-table tag. It errors out when i use the example i provided at the top of this long post.

13 Sep
1 year ago

Riotsmurf left a reply on Component Events In Vue

@andonovn Thank you very much for coming back and explaining this. Helped a lot.

11 Sep
1 year ago

Riotsmurf left a reply on Component Events In Vue

@andonovn What if i wanted it to override the templates testMethod() with the new Vue({methods:{ testMethod(){ console.log('Some different than normal stuff'); } }})

08 Sep
1 year ago

Riotsmurf started a new conversation Component Events In Vue

I am having a problem binding events to elements in my vue component. I will give an example of my issue and maybe someone can help me out.

I have a file called test.vue and it has

<template>
  <div class="box">
    <div class="button" v-on:click="testMethod">Do something</div>
     <div class="box">
         <div class="columns">
             <div class="column">Column 1</div>
             <div class="column">Column 2</div>
             <div class="column">Column 3</div>
             <div class="column">Column 4</div>
             <div class="column">Column 5</div>
         </div>
       </div>
  </div>    
</template>

I have a javascript file called test.js that has

window.Vue = require('vue');

(function(){

    Vue.component('my-test', require('./components/test.vue'));
    new Vue({
        el: '#test',
        created: function() {
            console.log('Starting the testarino');
        }
        methods :{
            testMethod: function(){
               console.log("I did something yay!!");
            }
        }
    });
}());

my blade template looks like this

{{--Extend base layout--}}
@extends('layouts.app')

{{--Links and scripts--}}
@section('scripts')
  <script src="{{asset('js/test.js')}}" ></script>
@endsection

{{--Content--}}
@section('content')
  <div id="test">
    <my-test></my-test>
  </div>
@endsection

When i load the page i get this error in the console

[Vue warn]: Property or method "testMethod" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

found in

---> <MyTest> at /var/www/html/resources/assets/js/components/test.vue
       <Root>
warn @ test.js:951
warnNonPresent @ test.js:2106
get @ test.js:2147
render @ test.js:404
Vue._render @ test.js:4600
updateComponent @ test.js:3010
get @ test.js:3353
Watcher @ test.js:3342
mountComponent @ test.js:3014
Vue$3.$mount @ test.js:8335
Vue$3.$mount @ test.js:10538
init @ test.js:3973
createComponent @ test.js:5619
createElm @ test.js:5562
createChildren @ test.js:5690
createElm @ test.js:5595
patch @ test.js:6078
Vue._update @ test.js:2886
updateComponent @ test.js:3010
get @ test.js:3353
Watcher @ test.js:3342
mountComponent @ test.js:3014
Vue$3.$mount @ test.js:8335
Vue$3.$mount @ test.js:10538
Vue._init @ test.js:4708
Vue$3 @ test.js:4793
(anonymous) @ test.js:92
module.exports @ test.js:105
__webpack_require__ @ test.js:20
(anonymous) @ test.js:10592
__webpack_require__ @ test.js:20
(anonymous) @ test.js:66
(anonymous) @ test.js:69
test.js:951 [Vue warn]: Invalid handler for event "click": got undefined

found in

---> <MyTest> at /var/www/html/resources/assets/js/components/test.vue
       <Root>
27 Jun
2 years ago

Riotsmurf left a reply on SMTP Mail Fail

If you don't get the solution, i recommend switching to mailgun.

Riotsmurf started a new conversation Validation Of An Array And Custom Message. Help Me!

I want to validate an array of emails and then tell the user which of those emails failed the validation.

How would i grab the index of the failed email? I tried something like this: but failed(I knew it would)

private function validator($data)
    {
        $rules = [
              'custom' => [
                'to.*' =>[
                  'email' => $data['to']['*'] . " is not a valid email.",
                  'required' => "This requires an email address to send."
                ],
                'bcc.*' => [
                  'email' => $data['bcc']['*'] . " is not a valid email."
                ],
              ],
              'content' => 'min:4',
          ];

          return Validator::make($data, $rules);
    }

I want to know how i can get the index where the little * is in $data['bcc'] and $data['to'].

If i have to make a custom validator that loops through and validates each email individually then fine, but i would like something short and easy here if possible.

15 Jun
2 years ago

Riotsmurf left a reply on Lumen Not Seeing Js Folder/files In Public. But Can See Css.

RaphaelBronsveld: Omfg. My brain is dead. Thanks! I cannot believe i did that.

Riotsmurf started a new conversation Lumen Not Seeing Js Folder/files In Public. But Can See Css.

I have a public folder with css and js folders in it. Inside the css folder is a bulma.css file. In the js folder there is a searchInit.js file. When i try to bring these in via link/script tags it just ignores the js ones.

My html looks like this:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>{{ config('app.name', 'Conan: ') }} @yield('title')</title>

    <!-- Styles -->
    <link href="/css/bulma.css" rel="stylesheet" type="text/css" />

    {{-- <link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.2/css/bulma.css" rel="stylesheet" type="text/css" /> --}}

    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

    @yield('css_links')

</head>

<body>

    <div id="app">
       
        @include('partials/header')

        <div class="columns">

            <div class="column is-one-quarter">
           
                @yield('sidebar')

            </div>
            
            <div class="column is-three-quarters">

                @yield('content')

            </div>

        </div>

        @include('partials/footer')

    </div>


    <script href="/js/list.js" type="text/javascript"></script>
    <script href="/js/searchInit.js" type="text/javascript"></script>
</body>

</html>

When i load the page this is what the src looks like: http://i.imgur.com/08b9v48.png

What i don't understand is why is it ignoring the js folder/files. Even when i move a js file into the css folder, it still doesn't see it. I have no way of diagnosing this problem because i never had it before and i have not found my problem through the googlez.

14 Jun
2 years ago

Riotsmurf left a reply on Am I Doing This Right?

Snapey: Hmm i see what you mean.

We had a database idea at first but then felt like we didn't want to store this information because its just requirements that are set by the state. We felt like the law does not change enough, and if it did it would not be a big deal to go into the FlowerMixTypeTest class and set the $requiredTests variable to what it would require. Then commit, push, and merge. Would you consider this bad still?

I suppose it would be about which is faster/easier for the system. Whether it is easier to store and update this information in the database, or less time to change 1 class.

Riotsmurf left a reply on Am I Doing This Right?

jlrdw: This is a select, not a checkbox or radio button. there are 6 parent types. VegetationType, ExtractType, TopicalType etc. I am not going to force the users to select "Flower" or "Flower Mix" and then check a radio button to pick vegetation because it leaves too much room for user error. This does not answer my question.

13 Jun
2 years ago

Riotsmurf started a new conversation Am I Breaking The O. Rule In S.O.L.I.D. ?

I am creating business logic in my Laravel project. I am creating an order and adding samples to the order. Each sample( depending on its type ) has a set of tests that it requires by law so i made this.

So i use getTestCollection() to return tests a product type needs.

<?php

namespace App\TestLogic;

class Product
{

    private $type;
    private $typeFactory;

    //Set base test as potency. Potency->id = 6
    public $tests = [
            "Foreign Matter" => 0,
            "Microbial" => 0,
            "Moisture" => 0,
            "Mycotoxin" => 0,
            "Pesticide Residue" => 0,
            "Potency" => 0,
            "Residual Solvent" => 0,
            "Terpenes" => 0,
            "Water Activity" => 0
    ];

    public function __construct(ProductTypeFactory $typeFactory)
    {
        $this->typeFactory = $typeFactory;
    }
    /**
     * Gets a collection of tests based on the type of this product
     * @return Array Array of tests required by type.
     */
    public function getTestCollection()
    {
        $classType = str_replace(' ', '',$this->type);
        $productType = $this->typeFactory->getProductTestType($classType);

        return $productType->getTestCollection($this);
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    public function getType()
    {
        return $this->type;
    }
}

There are some types that require the same set of tests like, Flower and Flower Mix. So i made this.

<?php

namespace App\TestLogic;

class VegetationType implements IproductTypeTest
{
    protected $requiredTests = [
            "Moisture" => 1,
            "Water Activity" => 1,
            "Potency" => 1,
            "Foreign Matter" => 1,
            "Microbial" => 1
            // "Mycotoxins"
    ];

    public function getTestCollection(Product $product)
    {
        foreach ($this->requiredTests as $key => $rTest) {
                $product->tests[$key]+=$rTest;
        }
        return $product->tests;
    }
}

And my Flower, Flower Mix classes extend this. So now they are empty like this.

<?php

namespace App\TestLogic;

class FlowerMixTypeTest extends VegetationType
{
}

<?php

namespace App\TestLogic;

class FlowerTypeTest extends VegetationType
{
}

Should VegitationType be a trait and not a class? This is my first go at this and i have a feeling its a little weird...