ThePoet444

ThePoet444

Member Since 5 Years Ago

Experience Points
67,050
Total
Experience

2,950 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
819
Lessons
Completed
Best Reply Awards
1
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.

Level 14
67,050 XP
19 Sep
3 days ago

ThePoet444 left a reply on All Policies Returns True On One Page Only

Well since I don't know where the problem lies, I don't know what code to post. If anyone can give me some insight, I'll gladly post more relevant code.

ThePoet444 left a reply on All Policies Returns True On One Page Only

To make this even more interesting, I can add {{dd(Auth::user()->can('noPermissionsFound'))}} and it returns true. So something is making just the forum index page have all policies return true. I'm not sure where to begin, I'll post on Riari's github to see if it's something there, but this one has me really confused.

ThePoet444 left a reply on All Policies Returns True On One Page Only

partial.nav

...
    </div>

        <div class="nav nav-pills ml-auto">
            @can('admin')<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="/permissions">Permissions Admin</a>@endcan
            @can('admin')<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="/telescope">Errors Page</a>@endcan
            @auth<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="{{route('profile', Auth::user()->id)}}">Profile</a>@endauth
        </div>

        <div class="nav nav-pills ml-2">
            @auth<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="https://github.com/ThePoet444/RebelSquadronsSite">Report Bugs</a>@endauth
            @guest<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="{{route('login')}}">Login</a>@endguest
            @guest<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="{{route('register')}}">Register</a>@endguest
            @auth<a class="nav-link rsbtn rsbtn-main rsText-main-white mr-1" href="{{route('logout')}}">Logout</a>@endauth
        </div>
...

No matter where I am on my site, those checks work. Be they the can, guest, or auth. they all work. EXCEPT on one page. the url '/forum'

This page, I had to modify a bit to fit with my existing layout.

forum.master (modified from Riari/laravel-forum-frontend

@extends('layouts.app')

@section('title')
    @if (isset($thread))
        {{ $thread->title }} -
    @endif
    @if (isset($category))
        {{ $category->title }} -
    @endif
    {{ trans('forum::general.home_title') }}
@stop

@section('content')
    <div class="container">
        @include ('forum::partials.breadcrumbs')
        @include ('forum::partials.alerts')

        @yield('forum_content')
    </div>
@stop

@section('scripts')
    <script>
        var toggle = $('input[type=checkbox][data-toggle-all]');
        var checkboxes = $('table tbody input[type=checkbox]');
        var actions = $('[data-actions]');
        var forms = $('[data-actions-form]');
        var confirmString = "{{ trans('forum::general.generic_confirm') }}";

        function setToggleStates() {
            checkboxes.prop('checked', toggle.is(':checked')).change();
        }

        function setSelectionStates() {
            checkboxes.each(function() {
                var tr = $(this).parents('tr');

                $(this).is(':checked') ? tr.addClass('active') : tr.removeClass('active');

                checkboxes.filter(':checked').length ? $('[data-bulk-actions]').removeClass('hidden') : $('[data-bulk-actions]').addClass('hidden');
            });
        }

        function setActionStates() {
            forms.each(function() {
                var form = $(this);
                var method = form.find('input[name=_method]');
                var selected = form.find('select[name=action] option:selected');
                var depends = form.find('[data-depends]');

                selected.each(function() {
                    if ($(this).attr('data-method')) {
                        method.val($(this).data('method'));
                    } else {
                        method.val('patch');
                    }
                });

                depends.each(function() {
                    (selected.val() == $(this).data('depends')) ? $(this).removeClass('hidden') : $(this).addClass('hidden');
                });
            });
        }

        setToggleStates();
        setSelectionStates();
        setActionStates();

        toggle.click(setToggleStates);
        checkboxes.change(setSelectionStates);
        actions.change(setActionStates);

        forms.submit(function() {
            var action = $(this).find('[data-actions]').find(':selected');

            if (action.is('[data-confirm]')) {
                return confirm(confirmString);
            }

            return true;
        });

        $('form[data-confirm]').submit(function() {
            return confirm(confirmString);
        });
    </script>
@stop

@section('footer')
    @yield('forum_footer')
@stop

category.index which gets loaded after the forum.master

{{-- $category is passed as NULL to the master layout view to prevent it from showing in the breadcrumbs --}}
@extends ('forum::master', ['category' => null])

@section ('forum_content')
    @can ('manageForumCategories')
        @include ('forum::category.partials.form-create')
    @endcan

    <h2>{{ trans('forum::general.index') }}</h2>

    @foreach ($categories as $category)
        <table class="table table-index">
            <thead>
            <tr>
                <th>{{ trans_choice('forum::categories.category', 1) }}</th>
                <th class="col-md-2">{{ trans_choice('forum::threads.thread', 2) }}</th>
                <th class="col-md-2">{{ trans_choice('forum::posts.post', 2) }}</th>
                <th class="col-md-2">{{ trans('forum::threads.newest') }}</th>
                <th class="col-md-2">{{ trans('forum::posts.last') }}</th>
            </tr>
            </thead>
            <tbody>
            <tr class="category">
                @include ('forum::category.partials.list', ['titleClass' => 'lead'])
            </tr>
            @if (!$category->children->isEmpty())
                <tr>
                    <th colspan="5">{{ trans('forum::categories.subcategories') }}</th>
                </tr>
                @foreach ($category->children as $subcategory)
                    @include ('forum::category.partials.list', ['category' => $subcategory])
                @endforeach
            @endif
            </tbody>
        </table>
    @endforeach
@stop

Now, when I go to this page (url('forum') ), all policy checks return true. Which means I can see all the links I'm not supposed to. If I navigate off the main forum page, either deeper into the forum, or into the site itself, all policy checks work as intended.

ThePoet444 left a reply on All Policies Returns True On One Page Only

I'm not using any custom middleware, basically just what riari has out of the box. I modified the front end to work with my layout, but even then nothing I changed dealt with policy checking. I'm not sure what code I need to post at this point, but I'll happily post anything. This one is rather baffling.

ThePoet444 started a new conversation All Policies Returns True On One Page Only

I go to my main forum index page, and I can see all the admin links. Yet clicking any other page, forum category,post, non-forum link, etc., those admin links disappear and all returns well. It's just on one page where all blade policy checks return true. It's rather annoying trying to troubleshoot. I'm not sure what the cause can be. If I dd() in blade with a user->can() check, everything returns true on the forum index page, but navigating away returns the answer it's supposed to give.

I setup a test user with no permissions or roles, I can't access any of the admin links. So permissions are working as expected for the site as a whole. I go to the forum page and all the permissions in the blade files return true. I can't access the page, so the backend php seems to be working as intended. This appears to be a blade/front end issue.

I'll gladly post whatever code I need to, but I'm not really sure where to start here.

Laravel 5.8

packages used:

Spatie/Laravel-permission
Riari/Laravel-forum
Riari/Laravelforum-frontend
11 Sep
1 week ago

ThePoet444 left a reply on Laracasts Coupons Codes?

If history is one to go by, it is unlikely that a coupon will be valid for a lifetime subscription.

21 Aug
1 month ago

ThePoet444 left a reply on Upgrade Laravel 5.3 To 5.8

Also, some of your packages might need to be updated as well. In your error the package elibyy/tcpdf-laravel is what is throwing the error. That version of the package needs laravel 5.3 to work.

14 Aug
1 month ago

ThePoet444 left a reply on Testing That A User Can Edit Profile

@mariohbrino chaning the fillable field to an empty guarded field makes no difference. I still get the same response to the test. Even if I specify everything in the fillable field.

@p4rz1val A good thought, however it made no change.

Let me know if you need me to post any other data. I'm scratching my brain on this one.

ThePoet444 left a reply on Testing That A User Can Edit Profile

That's the point of the test though, to see if someone who passes an id through can get an edit through.

The profile table has a lot of info in it other than name. passing the quote through is just a random field I picked that's quick to view on the site.

ThePoet444 left a reply on Testing That A User Can Edit Profile

@tray2 if I just return true in the authorize method, the test still fails with the redirect. Manual browser testing remains fine.

@jasonfrye I have getRouteKeyName() set to the user_id in the profile model for simplicity sake. Since I will never get a profile without a user, and since the user is tied into everything it just makes things easier code wise. For me anyway.

ThePoet444 started a new conversation Testing That A User Can Edit Profile

Simple enough situation, a user can edit their own profile. Run it through a browser test, works like a charm. Make a test for it... well now we have something interesting.

/** @test */
    function auth_user_can_edit_own_profile()
    {
        $user = factory('App\User')->create();
        $user->setProfile();  //this just makes an empty profile so a 1-1 relation exists
        $this->actingAs($user);
        $response = $this->post('profile/'.$user->id.'/update',[
            'quote'=>'Hello World',
        ]);
        $response->assertSee('Hello World');
    }

I get a failure. what displays on the screen is a redirect to the main page. O.o Nothing in my code should make that happen.

I believe it has something to do with my form request's authorize() method. However, I fail to see how. I have tried using $this->withoutExceptionHandling() in my test with no change.

storeProfile form request:

public function authorize()
    {
        $profile = $this->route('profile');
        if ($this->user()->can('edit profile') || $this->user()->id == $profile->user_id)
        {
            return true;
        }
        return false;
    }


Profile Controller update:

public function update(storeProfile $request, Profile $profile)
    {
        $profile->update($request->except('name'));
        $profile->save();

        if($profile->user->name != $request->input('name'))
        {
            $profile->user()->update(['name' => $request->input('name')]);
            //TODO event to track name changes
        }

        return redirect()->action('[email protected]',['id' => $profile->user_id]);
    }

Any insights to this would be really helpful, but I truly don't understand what is happening. Thank you all for taking the time to read and help!

12 Aug
1 month ago

ThePoet444 left a reply on Prevent Specific Migration During Test

I forgot I could check the environment. Thank you. For some reason it didn't like that code.. I had to wrap the entire migration in if(!App::environment('testing')) {} Still it got me where I needed to go. Thank you!

ThePoet444 started a new conversation Prevent Specific Migration During Test

I have a couple of migrations that basically import data from our old DB that is horribly constructed to a new DB that is slightly less horrible. Probably should be a seeder now that I think about it.. but anyway. I don't need these migrations to run during my tests, the others I need. Is there a command, or a flag I can set somewhere that will prevent certain migrations from run during tests? I've googled a bit and haven't found anything useful.

I understand if this isn't really a needed thing. If this isn't possible I'll try and rewrite them as seeders.

21 Jul
2 months ago

ThePoet444 started a new conversation Testing Password Rehashing

I currently have an event listener tied to Laravel's Attempting class. This works when going to the site to login. Now I want to be a good developer and get tests down. I have a test made that passes. I am not certain however this is the proper way to test it. I would also like to make sure that passwords are not stored in plain text at any time. I am new to testing so I would like to know if this is correct test to use.

<?php

namespace Tests\Unit;

use Illuminate\Auth\Events\Attempting;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PasswordTest extends TestCase
{
    use RefreshDatabase;
   

    /** @test */
    function user_is_able_to_login_with_old_rs_password()
    {
        $user = factory('App\User')->create(['password' => '<old badly used hash>']);

        $response = $this->post('/login',[
            'email' => $user->email,
            'password' => 'secret'
        ]);

        $response->assertRedirect('/');
    }

    /** @test */
    function user_password_changed_to_new_hash()
    {
        Event::fake();

        $user = factory('App\User')->create(['password' => '<old badly hashed pass>']);

        $this->post('/login',[
            'email' => $user->email,
            'password' => 'secret'
        ]);
        Event::assertDispatched(Attempting::class);

        $pw = 'secret';

        $this->assertTrue(Hash::check($pw, $user->password));
        $this->post('/logout');
        $this->post('/login',[
            'email' => $user->email,
            'password' => $pw
        ]);

        $this->assertFalse(Hash::check($pw, $pw));
    }

}

This test does return green.. but I have doubts. I would love any tips or tricks so I can improve.

13 Jul
2 months ago

ThePoet444 left a reply on Laravel Collective / Html

The package is still being maintained, but honestly for the amount it helps, you can write standard html forms just as easy. I still use it, but I'm slowly rewriting everything to ditch it. It's one of those nice ot have type of packages.. but eh.. in the grand scheme.. not really needed. Tis all my opinion anyway.

13 Jun
3 months ago

ThePoet444 started a new conversation Testing Login Listener With Password Rehash Tips

I figure it's time I start to learn testing. With that in mind, I've went and stumped myself. I have a listener that catches for the auth attempting event. Basically, if the user is logging in, it checks the DB for the old hashing pattern and just uses the credentials to rehash into the proper bcrypt (or whatever newer hashing) laravel has. This works, as I can test actually logging in. However, on some very rare occasions, and for reasons I can't track down, sometimes it stores the password as plain text. This is very very very bad. So.. testing is required. I'm going to go back and rewatch all the testing videos I can find on here, but having a starting point would be helpful.

Questions I have are:

What keywords should I be searching for so I can learn to test listeners and password changes in the DB? What types of things should I be aware of when writing tests for this? What fringe test cases would you recommend I test for?

Thanks everyone!

For reference, here is my listener:

AuthAttemptListener.php

public function handle(Attempting $event)
    {
        $user = User::where('password', crypt(stripslashes($event->credentials['password']), 'secret_phrase'))->first();

        if ($user) {
            $user->password = Hash::make($event->credentials['password']);
            $user->save();
        }
    }
30 May
3 months ago

ThePoet444 left a reply on Database Schema Overthinking

Thank you for your response!

I wasn't worried about the relationships, I was more concerned if simplifying the three units into one table was a wise thing. All three share the same common setup with minor differences, so I was thinking to make things easier to have one table and one model. Having 3 models that share the same commonality might cause me to reuse code. Which was my rational for avoiding it. Still, in the end it might make things easier to have 3 tables/models.

29 May
3 months ago

ThePoet444 left a reply on Simple Foreign Key Didnt Work . Laravel 5.8

I generally put foreign keys in their own migration after I make the needed tables. Probably not the best way but it's a bit easier to handle.

ThePoet444 left a reply on Simple Foreign Key Didnt Work . Laravel 5.8

Have your roles table migrated first. Otherwise it'll try and create a foreign key on a non existent table

28 May
3 months ago

ThePoet444 started a new conversation Database Schema Overthinking

ok, I've tried typing this out numerous times trying to see if I can simplify things, but I'm giving up.

Background info: I have a roleplay/roster setup. It contains Fleets,Wings, and Squadrons. (Pseudo military). A Fleet, may/may not have wings, a fleet may have squads. Squads must belong to either a fleet or a wing. Wings are optional. all three units share some common factors. ID,Name,Title,Description,CO,XO,SO (Commanding officer, second, third). Wings and Squads will have a parent. and a squad will have a number of slots for total users. As silly as it sounds, a under can be all three at once in all three units. I'll have RBAC setup so it won't matter. This is mainly for record keeping/roleplay information.

Since a user can be in multiple units and spots, I have a positions table setup to record the user id, the unit id, and any other relevant info.

Questions I have are (in no order):

  1. Will this work?
  2. Should I split the units up into 3 separate tables (fleets, wings, squads), with 3 different models to govern them?
  3. Is there an easier way to do this?

Thank you for any help you can provide!

table users {
  id bigint [pk]
  name varchar [not null]
}

table units {
  id bigint [pk]
  name varchar [not null]
  title varchar [null]
  description text [null]
  co integer [null, ref: > users.id]
  xo integer [null, ref: > users.id]
  so integer [null, ref: > users.id]
  type enum [not null]  //fleet,wing,squad
  spots integer [null]
  unit_id bigint [null, ref: > units.id]
}

table positions {
  id bigint [pk]
  user_id bigint [not null, ref: > users.id]
  unit_id bigint [not null, ref: > units.id]
  title varchar [null]
  spot integer [null]
}
01 Mar
6 months ago

ThePoet444 left a reply on List Of Users Online

I have finally solved this, and while I know it's not pretty, it works finally. In case anyone else comes across this and is curious. My lack of vue and javascript knowledge is probably showing, but here's some working code. I welcome any tips and tricks on refactoring this. However, as ugly as it is.. it works how I need it to. A users is online, doesn't blink when changing pages and causing a page refresh, and logs out when they close the browser. I call it a win.

onlineUsers (event)

class onlineUsers implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @param $user
     */
    public function __construct($user)
    {
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('onlineUsers');
    }
}

I had a middleware that runs to update a users last seen column in the DB, so I just hijacked that and dispatched this event there. Not the best place I know, but it works for now.. 


APP.JS

let app = new Vue({
    el: '#app',
    data: {
        onlineUsers: [],
        usersToRemove: [],
    },

    mounted() {
        window.Echo.join('onlineUsers')
            .here(onlineUsers => ([this.onlineUsers = onlineUsers, this.usersToRemove = onlineUsers]))
            .joining(user => this.join(user))
            .leaving(user => this.leave(user))
            .listen('onlineUsers', (user) => {
                this.usersToRemove = this.usersToRemove.push(user)
            })
    },

    methods: {
        join(user) {
            if(this.onlineUsers.some(u => (u.id === user.id)) === false) {
                this.onlineUsers.push(user);
            }
            this.usersToRemove = this.usersToRemove.filter(u => (u.i === user.id));
        },

        leave(user) {
            let removeUser = user;
            if(this.usersToRemove.some(r => (r.id === user.id)) === false) {
                this.usersToRemove.push(user);
            }
            setTimeout(user => {this.removeUser(removeUser)}, 1000);


        },

        removeUser(user) {
            let userToRemove = this.usersToRemove.find(u => u.id === user.id);
            if (userToRemove) {
                this.onlineUsers = this.onlineUsers.filter(u => u.id !== user.id);
                this.usersToRemove = this.usersToRemove.filter(u => u.i === user.id);
            }
        }
    }
});

25 Feb
6 months ago

ThePoet444 left a reply on List Of Users Online

Awesome thank you for the code snippet. Thankfully the code itself does not work, but it's a starting point that I can learn from. I had no idea that function existed. Thank you again. :)

ThePoet444 left a reply on List Of Users Online

I can't find anything on google so I'm probably not searching correctly. Can someone shoot me a link to an example so I can learn more please?

22 Feb
7 months ago

ThePoet444 started a new conversation List Of Users Online

I currently have a list of all users using the site. I am using laravel echo server. Everything works as it should. The questions I have are this:

  1. is this the correct way to do it?
  2. The user will "blink" when they go to a new page of the site. While I understand why this happens and it is indeed normal, I'm curious if there is a way I can prevent it. IE, user 2 will go from main page to a news article and user 1 will see user 2 "blink" because of the page shift.
\app.js

let app = new Vue({
    el: '#app',
    data: {
        onlineUsers: []
    },
    mounted() {
        window.Echo.join('onlineUsers')
            .here(onlineUsers => (this.onlineUsers = onlineUsers))
            .joining(user => this.onlineUsers.push(user))
            .leaving(user => (this.onlineUsers = this.onlineUsers.filter(u => (u.id !== user.id))))
    }
});



//blade
<div>
    <h4>Users Online</h4>

    <ul>
        <li class="linone" v-for="user in onlineUsers" v-text="user.name"></li>
    </ul>
</div>
08 Feb
7 months ago

ThePoet444 left a reply on Need Help Fixing Duplicate Queries

That.. that is amazing.. You stare at the same code for so long you overlook stuff. Over all this is amazing and it works fine. Just needed to move the take(5) to the outside so I could get the 5 latest from each category. Thank you very much! I can't believe I missed this :/ Thank you again!

ThePoet444 started a new conversation Need Help Fixing Duplicate Queries

Using debugbar I've found a query run a couple times and according to the backtrace it's from the same spots. So I've kinda figured out why it happens, but now I'm confused at how to prevent it.. and Jeffrey's video on memoisation is helping, but I think my application of the info is wrong. According to debugbar the query run is this: select * fromrankswhereranks.id= 1 limit 1 Which I know is caused by my test user not having a rank (Think pseudo military captain, major, etc). I'm trying to get all the news posts, with the author the rank with it. Unfortunately, i'm trying to code around an existing DB and not everyone has a history of rank changes. so I need to code around relationships returning null. In most cases I'll be getting a user's rank with their name so I created these helpers below to try and limit the queries needed for that info.

A user will have a history of rank changes, either up or down I just need the latest one for this purpose. In a users profile I'll be listing all their rank changes, but that's not an issue and beyond the scope of my post.

So this code all kinda works.. I've managed to eliminate a lot of duplicate queries and managed to eager load what I can.. however, this one query just doesn't want to go away.

User
id, name

protected $rankDetail = [];
protected $nameWithRank = [];

public function rank()
    {
        return $this->belongsToMany(Rank::class, 'rank_history', 'user_id','rank_id')
                    ->withPivot(['reason', 'promoter','created_at','updated_at'])
                    ->withTimestamps()
                    ->orderBy('rank_history.created_at', 'desc')
                    ->using(RankHistory::class);
    }

public function rank_detail($detail)
    {
        if(empty($this->rankDetail[$this->id][$detail]))
        {
            if(is_null($this->rank->first()))
            {
                $this->rankDetail[$this->id][$detail] = Rank::find(1)->$detail;
                return $this->rankDetail[$this->id][$detail];
            }
            $this->rankDetail[$this->id][$detail] = $this->rank->first()->$detail;
        }

        return $this->rankDetail[$this->id][$detail];
    }

    public function with_rank($detail)
    {
        if(empty($this->nameWithRank[$this->id][$detail]))
        {
            $this->nameWithRank[$this->id][$detail] = $this->rank_detail($detail) .' '. $this->name;
        }
        return $this->nameWithRank[$this->id][$detail];
    }



rank
id, name, abbr

public function user()
    {
        return $this->belongsToMany(User::class, 'rank_history', 'rank_id','user_id')
            ->withPivot(['reason', 'promoter','created_at','updated_at'])
            ->withTimestamps()
            ->orderBy('rank_history.created_at', 'desc')
            ->using(RankHistory::class);
    }

That's the basic of my latest round of testing. As mentioned above, I'm trying to get a lit of news posts and their author.

controller:

if(! $this->categories)
        {
            $this->categories = Category::all();
        }

foreach($this->categories as $cat){
            $news[$cat->id]=News::where('category_id',$cat->id)
                ->where('published_at', '<', Carbon::now())
                ->orderBy('published_at', 'desc')
                ->with('user','user.rank')
                ->take(5)->get();
        }

//
blade:

<ul class="nav nav-tabs navbarCustom bg-trans d-flex justify-content-between" role="tablist" id="newsTab">
                    @foreach($categories as $cat)
                        @if($loop->first)
                            <li class="nav-item"><a class="nav-link" id="cat{{$cat->id}}-tab" href="#cat{{ $cat->id }}" data-toggle="tab" aria-selected="true" aria-controls="cat{{$cat->id}}" role="tab">{{ $cat->name }}</a></li>
                        @else
                            <li class="nav-item"><a class="nav-link" id="cat{{$cat->id}}-tab" href="#cat{{ $cat->id }}" data-toggle="tab" aria-selected="false" aria-controls="cat{{$cat->id}}" role="tab">{{ $cat->name }}</a></li>
                        @endif
                    @endforeach
                </ul>
                <div id="newsContent" class="tab-content">
                    @foreach($categories as $cat)
                        @if($loop->first)
                            <div class="tab-pane fade show active" id="cat{{$cat->id}}" aria-labelledby="cat{{$cat->id}}-tab" role="tabpanel">
                        @else
                            <div class="tab-pane fade" id="cat{{$cat->id}}" aria-labelledby="cat{{$cat->id}}-tab" role="tabpanel">
                        @endif
                            <div class="card card-body panel">
                                <div class="cat{{$cat->id}}a">
                                    @forelse($news[$cat->id] as $post)
                                        <div class="rs-outline mb-2">
                                            <span class="m-1 d-flex justify-content-between">
                                                <a href="{{ route('news.show', $post->id ) }}"><h5 class="card-title">{{$post->title}}</h5></a>
                                                published by: {{$post->user->with_rank('abbr')}}
                                            </span>
                                            <span class="m-1 d-flex justify-content-between">
                                                <h6 class="card-subtitle mb-2 text-muted">{{$post->blurb}}</h6>
                                                date: {{$post->publishedDate()}} ({{$post->published_at->diffForHumans()}})
                                            </span>
                                        </div>
                                    @empty
                                        <div><p>Sorry no {{$cat->name}} yet.</p></div>
                                    @endforelse
                                </div>
                            </div>
                        </div>
                    @endforeach
                </div>

Where am I going wrong and how do I fix it? Thanks in advance for any help!

21 Dec
9 months ago

ThePoet444 left a reply on OK So Tabs Have Been Outlawed...

While Idon't have a concrete answer I might have a partial solution. The issue, if I can understand it correctly, is when navigating using the arrow keys, you have to hit the keys 4 times (or two depending) just to get past the place where a tab character should be. Basically, if there are 4 spaces (or 2) the arrow key should skip past all the spaces and go to the beginning of the proper code. I don't have much experience so I can't answer this, the only possible solution I can give you is try using control+ arrow key. This usually skips to the next word. It might be a solution it might not, but hopefully this post clears up what you're trying to do. IF I can read all this correctly.

08 Sep
1 year ago

ThePoet444 left a reply on Laravel 5.7 Dusk Login Testing Fails With Wrong Credentials

This test passes:

public function testBasicExample()
    {
        $user = factory(User::class)->create([
            'email' => '[email protected]',
        ]);

        $this->assertDatabaseHas('users', ['email' => $user->email]);

    }

This test failed with a "credentials do not match our records"

public function testBasicExample()
    {
        $user = factory(User::class)->create([
            'email' => '[email protected]',
        ]);

        $this->assertDatabaseHas('users', ['email' => $user->email]);

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                ->type('email', $user->email)
                ->type('password', 'secret')
                ->press('Login')
                ->assertPathIs('/');
        });
    }

ThePoet444 left a reply on Laravel 5.7 Dusk Login Testing Fails With Wrong Credentials

ok, I stand corrected, the users tabel gets generated, but I get a credentials don't match.. so the factory isn't saving the user to the DB. despite it's set to create().

ThePoet444 left a reply on Laravel 5.7 Dusk Login Testing Fails With Wrong Credentials

Yes, I forgot to comment out the DB Hash check... but still, at it's core it's still just the basic login test from the docs which is failing.

User factory from the Docs:

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => 'y$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
        'remember_token' => str_random(10),
        'verified' => 1,
    ];
});

and

login test from the docs:

<?php

namespace Tests\Browser;

use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class LoginTest extends DuskTestCase
{
    use DatabaseMigrations;
    //rs password: ['password' => 'RSCsduKYaEaZ2']

    /**
     * A basic browser test example.
     *
     * @return void
     */

    /** @test */
    public function login_test()
    {
        $user = factory(User::class)->create(['email' => '[email protected]',]);

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                ->type('email', $user->email)
                ->type('password', 'secret')
                ->press('Login')
                ->assertPathIs('/')
        });
    }
}

and I get a failure, because after login it's supposed to redirect to the home page ('/'). No joy. The screenshot generated on failure tells me the credentials don't match the records.. which means the user factory isn't persisting for dusk tests. Is this intended or did I miss a step somewhere?

Also if I add my own env file and tell dusk to use sqlite, it appears the user table doesn't even get migrated in. Which makes me wonder if I missed a step somewhere, or this is a bug. I've reread the docs a few times to see if I missed anything, but at this point I'm drawing a blank.

06 Sep
1 year ago

ThePoet444 started a new conversation Laravel 5.7 Dusk Login Testing Fails With Wrong Credentials

I am writing code to transition users from our current php crypt(), to bcrypt. Which according to other tests i've written, seems to work. So now I'm checking the front end and started to write tests for Dusk finally. Following the example in the (Laravel Docs)[https://laravel.com/docs/master/dusk#getting-started] it keeps failing and giving me a screenshot with the error of "These credentials do not match our records". Which makes sense since the DB is empty... but when using DB Migrations and a user factory set to create.. you would think it should pass then. Anyone know where I goofed? the User factory is the same from the docs.

LoginTest:

<?php

namespace Tests\Browser;

use App\User;
use Illuminate\Support\Facades\Hash;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class LoginTest extends DuskTestCase
{
    use DatabaseMigrations;

    /**
     * A basic browser test example.
     *
     * @return void
     */

    /** @test */
    public function a_users_pass_will_convert_from_current_rs_hash_to_new_hash()
    {
        $user = factory(User::class)->create();

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                ->type('email', $user->email)
                ->type('password', 'secret')
                ->press('Login')
                ->assertPathIs('/')
                ->assertSee('Logout');
        });

        $this->assertTrue(Hash::check('secret', $user->password));
    }
}


10 Jun
1 year ago

ThePoet444 left a reply on Restricting A Post Category With Permissions/roles

I think for now I'm just going to add a "special" column to the categories and then do an if statement but it just doesn't feel right to me.

$categories = Category::where('special', '=', null)->pluck('name', 'id')

if (user->can('post_special') {
    $categories = Category::all()->pluck('name', 'id')
}

Is there a better way than this?

ThePoet444 started a new conversation Restricting A Post Category With Permissions/roles

I have no code for this, I'm still trying to brainstorm. I'd like the ability for news posts to have certain categories. A couple of them are special that I only want certain people to be able to use them. I'm not exactly sure how to go about doing this.

Post
//id,user_id,Category_id,title,body,published_at
    public function category()
    {
        return $this->hasMany(Category::class);
    }

Category
//id,name
    public function news()
    {
        return $this->belongsTo(News::class);
    }

Should I just leave it, and check after validation before save? If category is foo, make it bar.. or something like that.. Should I have a permission column in the category field then check against then when making an array for the post form? If I go this route, what would be the best practice for this? if (user->can('post_special') {category::all() }else{ ? } Am I missing something completely obvious? If someone can point me in a direction to see example code, or important keywords I could use that would magnificent. Thank you all!

23 Aug
2 years ago

ThePoet444 started a new conversation Pivot Table As Main Focus

ok, using laravel 5.4, I have 3 models. Team, User, and positions. User can belong to many teams, teams can have many users. Both can have many positions.

Teams:
ID
name
slots  //max number of users on said team

user:
id
name

positions:
id
team_id
user_id
slot
title  //nullable field 

I was originally calling Positions and then eager loading both team and user. Then after thought, I realized positions was just a pivot table with a fancy name. So then I adjusted my relationship code to this:

team:
public function user()
    {
        return $this->belongsToMany(User::class, 'positions')
            ->withPivot('slot', 'title')
            ->withTimeStamps();
    }

So now I have to display a team with all it's users in their correct spot and display empty spaces.

team controller:
public function show(team $team)
    {
        $positions = Position::where('team_id', $team->id)->orderBy('slot', 'asc')->get()->keyBy('slot');

        return view('team.show', [
            'team' => $team,
            'positions' => $positions
        ]);
    }


team/show.blade:
 @for($i=1; $i<=$team->slots; $i++)
    @if((!empty($positions[$i])) && ($positions[$i]->slot == $i))
        <tr>
            <td>{{$i}}</td>
            <td>{{$positions[$i]->user->name}}</td>
            <td>{{$positions[$i]->title ?: ''}}</td>
        </tr>
    @else
        <tr>
            <td>{{$i}}</td>
            <td></td>
            <td></td>
        </tr>
    @endif 
@endfor 

I can't help but think that I'm either over complicating this, or there's a better way. If what I'm doing is fine, why do I keep looking over it thinking that it's wrong? It works, and displays everything how I want, but still. I wonder what improvements I could make.

I tried making a Positions model that extended Pivot instead of model, but I realized I couldn't call it like a regular model (I can in laravel 5.5 though). So for now positions is just a regular model that belongsto bot User and Team.

PS. Thank goodness for StackEdit so I know my code is formatted correctly without constantly editing.

07 Aug
2 years ago

ThePoet444 left a reply on Listing Of Positions With Partial User List And Empty Spots Or How I Have Loop Issues.

after walking away and them coming back I've found a solution. Not sure it's the best thing though.

Show.blade

@for($i=1; $i<=$team->slots; $i++)
    @if((!empty($positions[$i])) && ($positions[$i]->slot == $i))
            <tr><td>{{$i}}</td><td>{{$positions[$i]->command ?: ''}}</td><td>pilot name</td><td>{{$positions[$i]->title ?: ''}}</td></tr>
    @else
            <tr><td>{{$i}}</td><td></td><td>tbd</td><td></td></tr>
    @endif
@endfor 

in my controller:

$positions = Position::where('team_id', $team->id)->orderBy('slot', 'asc')->get()->keyBy('slot');

This the best I can hope for with a positions array that'll always be changing?

ThePoet444 started a new conversation Listing Of Positions With Partial User List And Empty Spots Or How I Have Loop Issues.

ok, sorry for the title confusion, I couldn't think of anything better. I'm sure I'm over complicating this, but here goes.

I have a team. Team has a name, random unimportant details, and a number of total positions.

I have a permissions table, (Which will be changed to a polymorphic entity later but for now...), Positions has the user_id, team_id, slot position and some extra info.

Basically I want to make a table list.. of positions 1 though team->slot. Simple for loop does that handily. The issue I have is, I may have users in team slot 1 and team slot 5. So how do I loop through all the positions and still list the empty spots so people can apply to them?

I'm probably missing some obvious and basic PHP stuff... or I've completely over thought this and made it more complicated.

I fail at looping it seems. I've tried various for/foreach, and while loops. Haven't found the right combo to get it working. Help please. Where am I over thinking this?

output desired

<table>
<tr><td>1</td><td>(User name or tbd if none)</td></tr>
<tr><td>2</td><td>(User name or tbd if none)</td></tr>
<tr><td>3</td><td>(User name or tbd if none)</td></tr>
<tr><td>4<td><td>(User name or tbd if none)</td></tr>
....
<tr><td>12</td><td>(User or tbd if none)</td></tr>
</table>

Current relevant blade code. It's not the right loop code, and this is where I'm stuck really.

<table class="table">
                        <tr><th>Postion</th><th>Command</th><th>Pilot</th><th>Title</th></tr>
                            @for($i=1; $i<=$team->slots; $i++)  
                                @for ($j=0; $j<$positions->count(); $j++)
                                    @if($positions[$j]->slot == $i)
                                        <tr><td>{{$i}}</td><td>{{$positions[$j]->command ?: ''}}</td><td>pilot name</td><td>{{$positions[$j]->title ?: ''}}</td></tr>
                                    @else
                                        <tr><td>{{$i}}</td><td></td><td>tbd</td><td></td></tr>
                                    @endif
                                @endfor
                            @endfor
                    </table>

Controller

 public function show(Team $team)
    {
        $positions = Position::where('team_id', $team->id)->orderBy('slot', 'asc')->get();
        return view('team.show', [
            'team' => $team,
            'positions' => $positions
        ]);
    }

Models are quite simple. Teams haveMany positions, positions belongTo Teams & belongsTo User.

05 Aug
2 years ago

ThePoet444 left a reply on How Many Of You Are Agree With The Idea That We Need Laracast Mobile App ?

Yeah with phones the way they are today, if you can run netflix on it, you can download chrome and watch laracasts from the site. No need for a mobile app.

26 Jun
2 years ago

ThePoet444 left a reply on Laravel - Is It Possible To Learn It In A Few Weeks?

I taught myself procedural PHP over the past 10 years or so, and knew nothing of MVC or OOP or any other fancy terms.. after a couple of weeks and following along to the videos here (and googling random errors) I'm a lot more comfortable building things. The hard part for me is not trying to do everything at once, but to break things down feature by feature. Start with User authorization, then move on to the next feature that's important... then the next, etc. It'll be a lot easier to test (Something else I need to get better at learning), and easier to expand in the future. With practice, dedication, and work, it can be done. :) (I'm still beginner/hobbiest level of knowledge by every way that matters)

13 Jun
2 years ago

ThePoet444 left a reply on Npm Run Dev.. Or Webpack Broke.. It's Not Doing Anything But Outputting Mix-manifest.json

Figured it out.. duplicate configs with plugins in the webpack.mix.js file was making it choke. Derp. At least it's fixed now.

ThePoet444 started a new conversation Npm Run Dev.. Or Webpack Broke.. It's Not Doing Anything But Outputting Mix-manifest.json

So I'm sure I broke something, but what I have no idea. In a search for trying to fix this myself. I have updated both Node and NPM to the latest stable versions. I have deleted the node_modules folder and rerun npm install. Still no joy. Below is my package.json, webpack.mix.js file, and the output from the terminal. I am currently running laravel 5.4 on homestead. It's not creating the output files in the public folder. Can anyone help shed some light on my next troubleshooting steps please? my google-fu and searching have come up with nothing useful. Thanks all!

Node -v : 8.0.0 (Was previously version 6.something when it broke) NPM -v: 5.0.3

output from terminal:

> npm run development


> @ development /home/vagrant/Code/l5bp
> cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

 10% building modules 0/1 modules 1 active ...modules/laravel-mix/src/mock-entry 10% building modules 1/2 modules 1 active ...modules/laravel-mix/src/mock-entry 95% emitting                             

 DONE  Compiled successfully in 112ms                                   15:21:59

            Asset       Size  Chunks             Chunk Names
mix-manifest.json  298 bytes          [emitted]  

webpack.mix.js:

const { mix } = require('laravel-mix');
const WebpackRTLPlugin = require('webpack-rtl-plugin');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */
mix.webpackConfig( {
    plugins: [
        new ImageminPlugin( {
//          disable: process.env.NODE_ENV !== 'production', // Disable during development
            pngquant: {
                quality: '95-100',
            },
            test: /\.(jpe?g|png|gif|svg)$/i,
        } ),
    ],
} );

mix.sass('resources/assets/sass/frontend/app.scss', 'public/css/frontend.css')
    .sass('resources/assets/sass/backend/app.scss', 'public/css/backend.css')
    .js([
        'resources/assets/js/frontend/app.js',
        'resources/assets/js/plugin/sweetalert/sweetalert.min.js',
        'resources/assets/js/plugins.js'
    ], 'public/js/frontend.js')
    .js([
        'resources/assets/js/backend/app.js',
        'resources/assets/js/plugin/sweetalert/sweetalert.min.js',
        'resources/assets/js/plugins.js'
    ], 'public/js/backend.js')
    .styles([
        'node_modules/jquery-ui-bundle/jquery-ui.css',
        'node_modules/jquery-ui-bundle/jquery-ui.theme.css',
        'node_modules/jquery-ui-timepicker-addon/dist/jquery-ui-timepicker-addon.css'
    ],'public/css/vendor.css')
    .copy('node_modules/jquery-ui-bundle/images/','public/images/')
    .copy( 'resources/assets/images', 'public/images', false )
    .webpackConfig({
        plugins: [
            new WebpackRTLPlugin('/css/[name].rtl.css')
        ]
    });

if(mix.config.inProduction){
    mix.version();
}

package.json:

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
    "axios": "^0.15.3",
    "bootstrap-sass": "^3.3.7",
    "cross-env": "^3.2.3",
    "font-awesome": "^4.7.0",
    "jquery": "^3.1.1",
    "laravel-mix": "0.*",
    "lodash": "^4.17.4",
    "vue": "^2.1.10",
    "webpack-rtl-plugin": "^1.5.0",
    "jquery-ui-bundle": "^1.11.4",
    "ckeditor": "^4.6.2",
    "fittext.js": "^1.2.0",
    "imagemin-webpack-plugin": "^1.4.4",
    "jquery-ui-timepicker-addon": "^1.6.3",
    "moment": "^2.18.1"
  },
  "babel": {
    "presets": [
      "es2015"
    ]
  }
}
03 Jun
2 years ago

ThePoet444 left a reply on Validating Name Registration Against Another List Of Names

ok, well now I feel like a dope. It helps if you actually seed the table. Not only that, I did need to reverse the returns. If the name does appear in the table it needs to return false to the validator.

I still don't know why it's an array though.. that's just.. weird. It works now though, so mystery for a later date. Back to writing tests.

Thank you!

ThePoet444 left a reply on Validating Name Registration Against Another List Of Names

... that.. is a very good question.. to which I have no answer. dd() returns the name from the input... but trying to use it as a string results in an array to string conversion error.. so I just have it explode and then dd shows me it's an array. However.. it still didn't change anything. A valid name still fails...

Now to trace back and find out why $value is an array.. unless it has something to do with the validator class itself... now I really don't know...

ThePoet444 started a new conversation Validating Name Registration Against Another List Of Names

ok. I have a table with just a list of names that are not valid for my site. Think Star Wars. You can't register calling yourself Darth Vader or any other popular name there. So I setup a custom validator, all nice and dandy. The problem is, no matter what it always fails and kicks the registration out. Even if a name isn't on the "banned names" list. The validator itself is setup correctly because it's being called.. but no matter what it's coming back as a failed validation. Where have I made a mistake? Also, if I reverse the returns, since I think I might have to.. but doing so makes everything valid, even if the new registration name is in the banned names list.

tl;dr:

Currently, registering with the name Darth Vader returns with the proper error of this name is not valid for our site.. however registering with Fred Rogers also fails with an invalid name, despite it not being in a banned names list. Halp?

App/Validator/CustomValidator.php

<?php

namespace App\Validator;

use DB;

class CustomValidator
{
    public function validateBannedNames($attribute, $value, $parameters, $validator)
    {
        $items = is_array($value) ? $value : explode(' ', $value);

        foreach ($items as $item) {
            if (DB::Table('banned_names')->where('name', 'LIKE', "%$item%")->exists()) {
                return true;
            }
        }

        return false;
    }
}
28 May
2 years ago

ThePoet444 left a reply on Role/permission In Vue

I currently have a global in my layout's head section, a kin to what Jeff did with the user object. Though, to be honest this feel wrong to me. I don't think the user object and/or what permissions he has should be displayed for the world to see when you view source. However, I shall wait for further developments in the series before I go looking at better ways.

Thank you for putting me on a better track though.

24 May
2 years ago

ThePoet444 started a new conversation Role/permission In Vue

Following along with the Let's build a forum episodes, Jeff leaves a space in the bootstrap.js file for the vue.prototype for other admin abilities. I already have a roles/permissions setup and was wondering how to make that info available to the front end JS? I have been trying to think about this, and was wondering since we're adding the user to the window.. is there a way I can eager load the roles/permissions through that? If so, how would I go about checking if they have the right roles or not? I can't really use user->hasRole('admin'). A google search has lead me in circles so I'm not using the correct terms (or just not understanding). Any help would be wonderful :) Thanks in advance everyone!

The code in question for bootstrap.js is:

Vue.prototype.authorize = function (handler) {
    // Additional admin privileges here.
    let user = window.App.user;
    return user ? handler(user) : false;
};
07 May
2 years ago

ThePoet444 left a reply on Vue Global Component Called Inside Another Won't Render

I figured out my issue. I asked this over at stack overflow and posted the updated answer there.

Stack Overflow question

06 May
2 years ago

ThePoet444 started a new conversation Vue Global Component Called Inside Another Won't Render

I am adding tinymce to my project. I have made it into a global component. This works fine. Does what it's supposed to and everything is great. Now, when following along to Jeff's latest "build a forum with TDD" series.. I got to thinking I can just add in that component to the reply component and use it there too! Yeah.. no. I'm a vue nub, so I'm sure I'm missing something obvious. Can anyone help? I even decided to call the global as a child component too.. no joy there either.

Vue debugging tools on chrome says it's there... but the editor won't render. So I'm a bit confused. I've tried adding <slot> to various places too, that made no change. Any help would be greatly appreciated!

Thanks all!

Code below-

app.js:

Vue.component('flash', require('./components/Flash.vue'));
Vue.component('reply', require('./components/Reply.vue'));
Vue.component('tinymce-editor',require('./components/Tinymce.vue'));

const app = new Vue({
    el: '#app',
});

Tinymce.vue:

<template>
    <textarea name="body" class="form-control" id="tinymce" v-text="body" rows="5"></textarea>
</template>

<script>
    export default {
        name: 'tinymce-editor',
        props: {
            body: {
                default: 'Something to say, have you?'
            }
        },

        mounted: function() {
            const self = this;
            tinymce.init({
                menubar: false,
                path_absolute: "/",
                selector: "#tinymce",
                entity_encoding: "raw",
                toolbar_items_size: "small",
                style_formats: [
                    {"title": "Bold", "icon": "bold", "format": "bold"},
                    {"title": "Italic", "icon": "italic", "format": "italic"},
                    {"title": "Underline", "icon": "underline", "format": "underline"},
                    {"title": "Strikethrough", "icon": "strikethrough", "format": "strikethrough"},
                    {"title": "Superscript", "icon": "superscript", "format": "superscript"},
                    {"title": "Subscript", "icon": "subscript", "format": "subscript"},
                    {"title": "Code", "icon": "code", "format": "code"}
                ],
                plugins: 'advlist anchor autolink autoresize code colorpicker hr image link lists preview searchreplace spellchecker textcolor wordcount',
                block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;",
                toolbar1: "undo redo | formatselect | bullist numlist | link unlink | uploadimg image",
                toolbar2: "styleselect fontsizeselect | forecolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | outdent indent | removeformat",
                init_instance_callback: function(editor) {

                    // init tinymce
                    editor.on('init', function () {
                        tinymce.activeEditor.setContent(self.value);
                    });
                }
            });
        },
        update: function(newVal, oldVal) {
            // set val and trigger event
            $(this.el).val(newVal).trigger('keyup');
        }
    }
</script>

Reply.vue:

<script>
    import Favorite from './Favorite.vue';
    import Tinymce from './Tinymce.vue';
    export default {
        name: 'Reply',
        props: ['attributes'],

        components: {
            'favorite': Favorite,
            'tinymce-editor': Tinymce
        },

        data() {
            return {
                editing: false,
                body: this.attributes.body
            };
        },

        methods: {
            update() {
                axios.patch('/replies/' + this.attributes.id, {
                    body: this.body
                });

                this.editing = false;

                flash('Updated!');
            },

            destroy() {
                axios.delete('/replies/' + this.attributes.id);

                $(this.$el).fadeOut(300, () => {
                    flash('Your reply has been deleted.');
                });
            }
        }
    }
</script>

reply.blade.php:

<reply :attributes="{{ $reply }}" inline-template v-cloak>
    <div id="reply-{{$reply->id}}" class="panel panel-default">
        <div class="panel-heading">
            <div class="level">
                <h5 class="flex">
                    <a href="{{ route('profile',$reply->owner->name) }}">
                        {{ $reply->owner->name }}
                    </a> said {{ $reply->created_at->diffForHumans() }}...
                </h5>

                <favorite :reply="{{$reply}}"></favorite>
            </div>
        </div>
        <div class="panel-body">
            <div v-if="editing">
                <div class="form-group">
                    <tinymce-editor body="{{ $reply->body }}"><slot></slot></tinymce-editor>
                </div>
                <button class="btn btn-xs btn-primary" @click="update">Update</button>
                <button class="btn btn-xs btn-link" @click="editing = false">Cancel</button>
            </div>

            <div v-else v-html="body"></div>
        </div>
        @can('update', $reply)
            <div class="panel-footer level">
                <button class="btn btn-xs btn-success mr-1" @click="editing = true">Edit</button>
                <button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
            </div>
        @endcan
    </div>
</reply>
03 May
2 years ago

ThePoet444 started a new conversation Vue2 Compoent Only Appears Once.

I'm using tinymce and I've made it into a sub component. I'm working on Jeff's current build a forum with TDD series.. so using his base reply.vue. When I first load the page, and click edit, the tinymce editor appears and I can update and things work fantastic. However, after saving, or clicking cancel, and then click edit again, the tinymce editor no longer shows. I'm a complete nub with vue, but so far loving this. Can someone point out where I'm going wrong?

app.js:

Vue.component('reply', require('./components/Reply.vue'));
Vue.component('tinymce', require('./components/Tinymce.vue')); //tested both with and without. No difference made

const app = new Vue({
    el: '#app'
});

Tinymce.vue:

<template>
    <textarea :value="value" id="tinymce" @input="updateValue($event.target.value)"></textarea>
</template>

<script>
    export default {
        name: 'tinymce',
        props: ['value'],
        methods: {
            updateValue(value) {
                console.log(value);
                this.$emit('input', value.trim());
            }
        },

        mounted: function(){
            let component = this;
            tinymce.init({
                target: this.$el.children[0],
                path_absolute: "/",
                selector: "#tinymce",
                entity_encoding: "raw",
                plugins: 'advlist anchor autolink autoresize code colorpicker hr image link lists preview searchreplace spellchecker textcolor wordcount',
                toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link",
                relative_urls: false,
                setup: function (editor) {
                    editor.on('Change', function (e) {
                        component.updateValue(editor.getContent());
                    })
                }
            });
        }
    }
</script>

Reply.vue:

<script>
    import Tinymce from './Tinymce.vue'
    export default {
        name: 'Reply',
        props: ['attributes'],

        data() {
            return {
                editing: false,
                body: this.attributes.body
            };
        },
        components: {
            'tinymce': Tinymce
        },

        methods: {
            update() {
                axios.patch('/replies/' + this.attributes.id, {
                    body: this.body
                });

                this.editing = false;

                flash('Updated!');
            },

            destroy() {
                axios.delete('/replies/' + this.attributes.id);

                $(this.$el).fadeOut(300, () => {
                    flash('Your reply has been deleted.');
                });
            }
        }
    }
</script>

reply.blade.php:

<reply :attributes="{{ $reply }}" inline-template v-cloak>
    <div id="reply-{{$reply->id}}" class="panel panel-default">
        <div class="panel-heading">
            <div class="level">
                <h5 class="flex">
                    <a href="{{ route('profile',$reply->owner->name) }}">
                        {{ $reply->owner->name }}
                    </a> said {{ $reply->created_at->diffForHumans() }}...
                </h5>

                <div>
                    <form method="POST" action="/replies/{{$reply->id}}/favorites">
                        {{csrf_field()}}
                        <button type="submit" class="btn btn-primary" {{ $reply->isFavorited() ? 'disabled' : '' }}>
                            {{ $reply->favorites_count }} {{str_plural('Favorite', $reply->favorites_count)}}
                        </button>
                    </form>
                </div>
            </div>
        </div>
        <div class="panel-body">
            <div v-if="editing">
                <div class="form-group">
                    <tinymce v-model="body"></tinymce>
                </div>
                <button class="btn btn-xs btn-primary" @click="update">Update</button>
                <button class="btn btn-xs btn-link" @click="editing = false">Cancel</button>
            </div>

            <div v-else v-html="body"></div>
        </div>
        @can('update', $reply)
            <div class="panel-footer level">
                <button class="btn btn-xs mr-1" @click="editing = true">Edit</button>
                <button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
            </div>
        @endcan
    </div>
</reply>
16 Apr
2 years ago

ThePoet444 started a new conversation Images And Image Maps

I am currently using the Intervention/image package, and it's fantastic. Ultimately I'm going to dynamically make users custom pseudo-millitary uniforms. Each uniform has a base image, and then we'll have ranks, and ribbons, and other bits and bobs all on the uniform. I can handle all that fine (Haven't written the code yet, but I saw the insert() function and have used that easily in testing for other things).

What I would like to do now, is have an image map generated so when someone hovers over a ribbon it'll give the name of it, and then have that be a link to the medal itself with more information. I have done this in spaghetti PHP, but man it's ugly. Is there a package that will help, or maybe something in intervention/image that I missed? Or is an Image map going a bit to complicated and there's an easier solution. I have tried google.. but not much is coming up that's helpful. Thanks in advance for your help!

12 Nov
2 years ago

ThePoet444 started a new conversation Polymophism, An Edit Form, And My Sanity

Greetings great and powerful hive mind!

I have coded myself into a corner that I can not get out of. I'm sure I over thought this but I figure I would give it a shot. I'm currently making a pseudo military game site. We are organizing users into Squadrons. a squad will have x number of spots. Not all of them filled. So I'm utilizing a positions table to keep track of which user is in which squad and which position. Then I realized that Each squad would be in a Wing and each wing would be in a fleet. Fleet and Wings have the same exact code, except Wings have a parent Fleet ID. So, I thought, why not make the positions table a polymorphic one and combine all of them! Since Wings and Fleets will have the same exact code basically. Each will have a possible Commanding officer, Executive Officer, and possible Second Officer. For ease, all three positions are nullable. A user can belong to any number of squads/wings/fleets. A user could also be "acting" as a CO/XO/SO. This is decided by a nice checkbox on the edit form.

Now I can populate the edit form just fine with eager loaded positions table and get all the special spots of CO/XO/SO. What I can't do however, is figure out how to save it all. Do I, detach all three possible positions, then attach? Do I, sync it all? Do I, loop through each of the three special positions, and edit each one manually (even if it's null?)?

I was originally thinking that I could store the CO/XO/SO in a field under the fleet table, which would work fine. I was just thinking in the future when I wanted to get each users positions for their profile. I wouldn't have to eager load half a dozen models. Plus doing it the polymorphic way I was trying to learn something. I kept seeing posts and videos for saving and creating.. nothing for editing however. Unless my google-fu is horrible which is possible.

Not sure what code you'd need to see where I'm going with this, but I can post what's needed.

Thanks everyone!