whoisthisstud

Marketing at Assembled Products Corp

Member Since 2 Years Ago

Bentonville, AR

Experience Points
15,840
Total
Experience

4,160 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
136
Lessons
Completed
Best Reply Awards
1
Best Reply
Awards
  • start your 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-in-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 Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist 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.

  • Community Pillar

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

Level 4
15,840 XP
Feb
24
1 month ago
Activity icon

Started a new Conversation Livewire Image Previews Not Displaying On Demo Site

Temporary images display locally, but not on the demo site.

The images still upload, but the temporary URL's return a 404 error for each image uploaded, and attempting to load the signed URL in a different tab results in a 401.

I'm unsure if my issue is livewire, an error I created, or even possibly this - https://github.com/livewire/livewire/issues/1216 ?

Laravel 8 / Livewire 2 / Forge / DigitalOcean. The demo site is on a sub-domain, and not within a sub-folder. I've updated the upload sizes, the TrustedProxies, and the nginx config updates mentioned in the repo issue, but still have the same issue. I'd prefer not to comment out the abort_unless() line and lose CSRF protection - maybe temporarily for poo-poo's and haha's if requested.

Any and all help appreciated.

VIEW

<div class="w-full" x-data="{ progress: 0, isUploading: false }"
	x-on:livewire-upload-start="isUploading = true"
	x-on:livewire-upload-finish="isUploading = false"
	x-on:livewire-upload-error="isUploading = false"
	x-on:livewire-upload-progress="progress = $event.detail.progress">

	<label class="flex-col mb-2 text-sm font-bold text-gray-700" for="images">
		<div class="flex flex-row flex-no-wrap w-full h-16 sm:h-20 md:h-24 bg-gray-200 focus:outline-none cursor-pointer items-center text-center rounded border @error('images') border-red-600 @else border-gray-200 @enderror overflow-y-hidden overflow-x-scroll mb-3">
		
        		@if( ! empty( $images ) )	
				@foreach( $images as $image )
					@php
						$load = false;
						$ext = ['jpg','jpeg','png','webp','heic','heif'];
						if ( in_array( $image->guessExtension() ,  $ext ) ) {
							 $load = true;
						}
					@endphp
										
					@if($load)
					<div class="flex-none h-16 bg-no-repeat bg-center bg-cover mr-2 {{ $loop->first ? 'ml-4' : '' }}" style="background-image: url({{ $image->temporaryUrl() ?? '' }}); width: 100px;"></div>
					@else
					<div class="block w-16">
						<span class="text-sm text-red-600">
							<span class="uppercase">{{ $image->guessExtension() }}</span> is an invalid filetype. An image is required.
						</span>
					</div>
					@endif
				@endforeach
			@else
			<div class="block w-full">
				<span class="w-full self-center mx-auto @error('images') text-red-600 @else text-gray-700 @enderror text-gray-700 font-bold">Upload Image</span>
				@error('images')
				<p class="w-full text-red-500 mt-1 text-sm font-normal pb-2 hidden md:block">{{ $message }}</p>
				@enderror
			</div>							
			@endif														
		</div>
		<input wire:model="images" class="w-full px-3 py-2 text-base leading-tight border border-gray-200 bg-gray-200 focus:bg-white text-gray-700 rounded shadow appearance-none hidden"
			id="images" name="images" type="file" multiple />
	</label>
        <div wire:loading wire:target="images" class="w-full my-2 text-red-600 text-center font-bold">Uploading...</div>
</div>

CONTROLLER

namespace App\Http\Livewire;

use Image;
use Storage;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Validation\ValidationException;


class XXXXX extends Component
{
    use WithFileUploads;

    public $images = [];
    public $imageList = [];

    [...]

    public function goToStepThree()
	{

		if( empty( $this->images ) ) {
			throw ValidationException::withMessages( ['images' => 'At least one image is required.'] );
		}

		// Get rid of any old images
		if( count( $this->imageList ) > 0 ) {
			foreach( $this->imageList as $oldImage ) {
				Storage::delete( $oldImage );
			}
			$this->reset( 'imageList' );
		}

		// Resize and store each image
		foreach( $this->images as $image ) {
			$this->resizeAndStoreTheImage( $image );
		}

		[...]

	}

    protected function resizeAndStoreTheImage( $image ) 
	{
		// Set the new image's name
	    $filename = time() . '-' . mt_rand( 10000 , 1000000 );
	    $filename_w_ext = $filename . '.' . $image->extension();

		// Save original uploaded image
		$original_image = $image->storeAs( 'ticket-request-images' , $filename_w_ext );

		// Get the original uploaded image's details
		list( $original_image_width, 
			$original_image_height, 
			$original_image_type, 
			$original_image_attr 
		) = getimagesize( Storage::path( $original_image ) );

		// Define new sizes
		$newSizes = [
			'xs' => [
				'size' => 250,
				'quality' => 60
			],
			'md' => [
				'size' => 600,
				'quality' => 70
			],
			'lg' => [
				'size' => 1024,
				'quality' => 80
			],
			'xl' => [
				'size' => 2048,
				'quality' => 90
			],
		];

		
		$thumbs = [];

		while( $this_new_size = current( $newSizes ) ) {

			// Get the size key, i.e. 'xs','md','lg'...
			$key = key( $newSizes );

			// Create a dynamic variable for folder path
			${$key} = Image::make( Storage::path( $original_image ) );

			// If the height or width of image is greater than newSizes size
			if( $original_image_width > $this_new_size['size'] || $original_image_height > $this_new_size['size'] ) {

				// Resize images - constrain to the new size's size on either side
				${$key}->resize( $this_new_size['size'] , $this_new_size['size'] , function ($constraint){

			    	$constraint->aspectRatio();

				})->stream( 'jpeg' , $this_new_size['quality'] );

				// Set the location
				$location = 'ticket-request-images/thumbnails/' . $key . '/' . $filename . '.jpg';

				// Store the resized image
				Storage::put( $location , ${$key} );

				// Push the location to the thumbs array
				array_push( $thumbs , $location );

			}

		    next($newSizes);

		}

		// Add the location to the imageList array
		array_push( $this->imageList, $thumbs );

		// Delete original, non-resized image
		Storage::delete( $original_image );
	}
Nov
23
4 months ago
Activity icon

Replied to Issue With Passing Collection In Livewire

@joakiml,

I ended up with this.

namespace App\Http\Livewire;

use App\Models\Contact;
use Livewire\Component;
use Livewire\WithPagination;

class ContactsTable extends Component
{
    use WithPagination;

    ....

    protected function componentsQuery()
    {
        $query = Contact::query();

        if ( $this->deleted ) {
            $query = $query->withTrashed();
        }

        $query = $query->where( function( $query ) {
                $query->where( 'name' , 'like' , '%' . $this->search . '%' )
                    ->orWhere( 'phone' , 'like' , '%' . $this->search . '%' )
                    ->orWhere( 'email' , 'like' , '%' . $this->search . '%' )
                    ->orWhere( 'message' , 'like' , '%' . $this->search . '%' )
                    ->orWhere( 'ip_address' , 'like' , '%' . $this->search . '%' );
            })
            ->where( 'is_contacted' , '!=' , $this->pending )
            ->orderBy( 'deleted_at' , 'asc' )
            ->orderBy( 'created_at' , $this->sort );

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

    public function render()
    {
        return view( 'livewire.contacts-table' , [
            'contacts' => $this->componentsQuery(),
        ]);
    }

}
Oct
22
5 months ago
Activity icon

Replied to Issue With Passing Collection In Livewire

Thank you, @laracoft. Worked perfectly.

I've never used items() before, and just tried quickly searching the docs for it to no avail. Would you mind explaining what exactly "items()" does?

Thanks.

Activity icon

Started a new Conversation Issue With Passing Collection In Livewire

Dang it... this is what I get for waiting so long to move away from 6.x and try to play catch up with 8.x.

I am attempting to pass paginated results from a livewire component into my view, but continue to get the following error:

Livewire\Exceptions\PublicPropertyTypeNotAllowedException
Livewire component's [contacts-table] public property [contacts] must be of type: [numeric, string, array, null, or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't need to access them.

My LW component

namespace App\Http\Livewire;

use App\Models\Contact;
use Livewire\Component;

class ContactsTable extends Component
{
    public $contacts;
    public $pending = true;
    public $search;


    public function render()
    {
    	$this->contacts = Contact::where('is_contacted','!=',$this->pending)
    		->orderBy('created_at','desc')
    		->paginate(10);

        return view('livewire.contacts-table');
    }
}

And in the livewire blade component...

@forelse($contacts as $contact)
...
@empty
@endforelse

In several video tuts of livewire, I see very similar code (just minus the where and orderBy).

Where am I going wrong? TIA