DanielRoenfeldt

DanielRoenfeldt

Member Since 6 Months Ago

Viborg

Experience Points
12,120
Total
Experience

2,880 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
113
Lessons
Completed
Best Reply Awards
0
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.

Level 3
12,120 XP
Aug
15
1 month ago
Activity icon

Replied to Asyncrhonous Component Instance Inside Parent Component

Outstanding! I ❤️ this community!

Aug
14
1 month ago
Activity icon

Replied to Asyncrhonous Component Instance Inside Parent Component

Brilliant! I never thought pushing a "programatically-created" component into an existing list could consist in such a simple and straightforward object-driven approach! It's so funny that all I was doing, was trying to re-invent the wheel.

Now if only I could figure out how to have the new comment getting visutally "pushed" as the first one, that is, on top of the existing ones, that would be perfect :) Any suggestions?

In any case, you, sir, are a legend!

Activity icon

Replied to Asyncrhonous Component Instance Inside Parent Component

Yes, that's exactly what I'm trying to achieve. But what do you exactly mean by "update your comments"? Could you provide me with an example of how that would be done? And please take into account that the new comment is supposed to be "built" through (or via) the <comment-item> component. Or am I misunderstanding the way this is supposed to work? :) Thanks so much!

Activity icon

Replied to Asyncrhonous Component Instance Inside Parent Component

Any ideas on how could I instantiate a component programatically, in an asynchronous way, inside another component?

I would highly appreciate any help with this one!

Aug
13
1 month ago
Activity icon

Started a new Conversation Asyncrhonous Component Instance Inside Parent Component

I've got a <comments-list></comments-list> component which loops through a Laravel Collection object of existing comments that are associated with a BlogPost model. I'm then instantiating each "comment" entity into its own element driven by a <comment-item></comment-item> component.

My intention is to provide visitors with the capability of writing comments, which (once sent through via axios and then validated through a Laravel Cotroller method) would finally appear into the list of the existing comments, as new <comment-item></comment-item> items that get appeded to the <comments-list></comments-list> element.

I've been following this guide which explains how a Vue Component can be programatically created.

From my limited understanding, a major problem with that approach is, the programatically-created <comment-item></comment-item> element is getting instantiated and mounted along with its <comments-list></comments-list> container, instead of it being created upon a successful response from the axios call.

In any case, here's my code - let me know if there's anything that doesn't quite make sense. Note that I haven't added any axios-processing in here, just so that I can illustrate my use-case scenario as cleanly as possible.

// resources/assets/js/app.js

window.Vue = require('vue')

Vue.component('comment-item', require('./components/CommentItem').default);
Vue.component( 'comments-list', require('./components/CommentsList').default );

const app = new Vue({
  el: '#app'
});
<!-- resources/views/blogposts/view.blade.php -->

@section('comments')

  <!-- ... -->
  
  <!-- $comments is the Eloquent Collection of "comments" -->
  <comments-list
        :comments-collection="{{ $comments }}"
  ></comments-list>

  <!-- ... -->
<!-- resources/assets/js/components/CommentsList.vue -->

<template>
  <div ref="commentsWrapper" class="comments-list">
  	
    <comment-item
        v-for="comment in comments"
        :key="comment.id"
        		
        :avatar="comment.user.avatar"
        :name="comment.user.name"
    >
    <template slot="the_body">{{ comment.body }}</template>
        </comment-item>
        	
        <!-- Just for testing -->
        <button @click="pushDemoComment">Push new Comment asynchronously</button>
    </div>
</template>

<script>
    import CommentItem from "./CommentItem";
    
    import Vue from 'vue';
        let ComponentClass = Vue.extend(CommentItem);
        const newComment = new ComponentClass({
            propsData: {
                avatar: 'path/to/image.jpg',
                name: 'Some Name',
            }
        });
        
        newComment.$slots.the_body = ['Lorem ipsum some random text in here...'];
        newComment.$mount();
	
	
        export default {
            name: "CommentsList",
            
            props: {
                commentsCollection: { type: Array, required: true }
            },
            
            methods: {
                pushDemoComment() {
                    console.log('Demo comment pushed!');
                    this.$refs.commentsWrapper.prepend( newComment.$el );
            }
        },
        	
        components: {
            'comment-item': CommentItem,
        }
    }
</script>
<!-- resources/assets/js/components/CommentItem.vue -->

<template>
    <div class="comment-item">
        <div class="avatar">
            <img :src="handleAvatar" :alt="name">
        </div>
        	
        <span class="name" v-text="name"></span>
        
        <slot name="the_body"></div>
    </div>
</template>

<script>
    export default {
        name: "CommentItem",
        
        props: {
            avatar: { type: String, required: true },
            name: { type: String, required: true },
        },
        
        methods: {
            handleAvatar() {
                // ... some avatar handling logic ...
                		
                return '../' + this.avatar;
            }
        },
        
        components: {
            'comment-item': CommentItem,
        }
    }
</script>
Aug
05
1 month ago
Activity icon

Replied to How To Use DiffForHumans() In Vue

Heads up: if you're trying to use @kkhicher1 's solution in Laravel 6.x, there's a caveat: it only works on Laravel 7+. The CastsAttributes interface wasn't implemented before Laravel 7.

Jul
16
2 months ago
Activity icon

Replied to How Do You FTP Into Your Forge Server?

@bradfields Brilliant! I can confirm that it works flawlessly with Transmit.

Jun
23
3 months ago
Activity icon

Replied to Help Converting CURL Request Into Guzzle Request

Alright, that seems to have solved my problem, as in, I'm not getting the 401 Unauthorized error anymore. But let me get this straight: the two strings representing the user's first and last name, they should be sent as part of the 'body' parameter of the request, like so:

$response = $client->get("https://xxxxxxx.xx.auth0.com/api/v2/users/{$userId}", [
	'headers' => [
		"Authorization" => "Bearer {$temp_token}",
		"Cache-Control" => "no-cache",
		"Accept" => "application/json",
	],
	'body' => "{ \"given_name\": $request->firstName, \"family_name\": $request->lastName }"
]);

Is my assumption correct? Because if it is, then the data is not being pushed to the Auth0 server. I'm a bit confused here...

PS: I totally forgot about including PHP variables within strings within curly braces, so thank you for helping me write a more efficient code! :)

Activity icon

Started a new Conversation Help Converting CURL Request Into Guzzle Request

Given this cURL-driven request:

$user_id = "auth0|xxxxxxxxxxxxxxxxxxxx";
$temp_token = "xxxxxxxxxxxxxxx..........xxxxxxxxxxxxxx";

$curl = curl_init();
		
curl_setopt_array($curl, array(
	CURLOPT_URL => "https://xxxxxxx.xx.auth0.com/api/v2/users/" . $user_id,
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_ENCODING => "",
	CURLOPT_MAXREDIRS => 10,
	CURLOPT_TIMEOUT => 30,
	CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
	CURLOPT_CUSTOMREQUEST => "PATCH",
	CURLOPT_POSTFIELDS => "{ \"given_name\": $request->firstName, \"family_name\": $request->lastName }",
	CURLOPT_HTTPHEADER => array(
		"authorization: Bearer " . $temp_token,
		"cache-control: no-cache",
		"content-type: application/json"
	),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
	echo "cURL Error #:" . $err;
} else {
	echo $response;
}

I've been trying to convert it into a Guzzle-driven request, like so:

$headers = [
	"Authorization" => "Bearer " . $temp_token,
	"Cache-Control" => "no-cache",
	"Accept" => "application/json",
];

$g_uri = "https://xxxxxxx.xx.auth0.com/api/v2/users/" . $userId;

$client = new Client();
$g_request = $client->get($g_uri);

$g_request->getCurlOptions()->set(CURLOPT_RETURNTRANSFER, true);
$g_request->getCurlOptions()->set(CURLOPT_ENCODING, "");
$g_request->getCurlOptions()->set(CURLOPT_MAXREDIRS, 10);
$g_request->getCurlOptions()->set(CURLOPT_TIMEOUT, 30);
$g_request->getCurlOptions()->set(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
$g_request->getCurlOptions()->set(CURLOPT_CUSTOMREQUEST, "PATCH");
$g_request->getCurlOptions()->set(CURLOPT_POSTFIELDS, "{ \"given_name\": $request->firstName, \"family_name\": $request->lastName }");
$g_request->getCurlOptions()->set(CURLOPT_HTTPHEADER, $headers);

$g_response = $g_request->send();

echo $g_response;

But it's throwing back a 401 Unauthorized exception, unlike the original cURL request. Is there a better way of handling this?

FYI: I'm using Laravel 6.x.

Many thanks.

May
18
4 months ago
Activity icon

Replied to How Can I Install The Material-UI Pickers Package In Laravel 6?

I'm totally going with Flatpickr. Thank you so much @wingly :)

Activity icon

Replied to How Can I Install The Material-UI Pickers Package In Laravel 6?

Yeah that looks like something I could totallly use... if it wasn't for that rather steep price, since the Date Picker component seems to be included only in the "Pro" package :)

Activity icon

Replied to How Can I Install The Material-UI Pickers Package In Laravel 6?

That makes total sense. I was just hoping I'd be able to use it, without fully realizing it's only built for React. Oh well... But thanks for clarifying things out for me :)

Activity icon

Replied to How Can I Install The Material-UI Pickers Package In Laravel 6?

Unfortunately my project is not a SPA. But I went ahead and tried to install the package nevertheless, based on your instructions. Here's the output I got in the Terminal after I ran the npm i @material-ui/pickers command:

npm WARN @material-ui/[email protected] requires a peer of @material-ui/[email protected]^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @material-ui/[email protected] requires a peer of [email protected]^16.8.4 but none is installed. You must install peer dependencies yourself.
npm WARN @material-ui/[email protected] requires a peer of [email protected]^16.8.4 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]>=16.6.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]>=16.6.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]>=16.8 but none is installed. You must install peer dependencies yourself.

Any thoughts on this?

May
16
4 months ago
Activity icon

Started a new Conversation How Can I Install The Material-UI Pickers Package In Laravel 6?

It's probably a stupid question (since this package appears to be built for React) but is there any way of installing and making use of Material-UI Pickers in Laravel 6?

I'd really like to include this awesome package in my L6-driven project.

Any help would be greatly appreciated.

May
15
4 months ago
Apr
23
5 months ago
Activity icon

Replied to Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

I must be really tired. It's such a simple approach, yet it never crossed my mind. Once again, thanks so much for your help @wingly. No more noob questions from me, at least not today 😊

Have a great day (evening/night) my friend. Stay safe 🙏

Activity icon

Replied to Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

That does help indeed. Thank you for that. But what if I'm storing the file under a much deeper folder structure, for instance

Storage::disk('local')->put('uploads/testprofiles/main-pictures/' . $filename_to_store, (string) $resized );

I'd then need to append the same uploads/testprofiles/main-pictures/path each and every time I'd need to get the URI of the stored images in my view files, right?

In other words,

<img src="{{ Storage::url('uploads/testprofiles/main-pictures/') . $testprofile->main_picture }}" alt="...">

Unless there's a better way of writing the path, either in the controller, or in the views, it seems to me a bit un-optimized way of using them.

Sorry for keeping on asking noob questions... 🤓

Activity icon

Replied to Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

@wingly Sir, you are a legend. Got it working on the first try (not a blind copy/paste of your code, I promise 😀 )

I was just wondering though, what's the purpose of using Storage::disk('local')when saving the processed image? How could I then get ahold of the newly-created image in a .blade file? I've already created a symlink with php artisan storage:link, can I just use the asset() helper method for that purpose?

Activity icon

Replied to Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

Okay, getting there :)

I created an additional validator function, just for the image, so that the conditional will return false in case the image is the wrong format/filesize. Here's the updated store() method:

/**
   * Store a newly created TestProfile in storage.
   *
   * @param Request $request
   *
   * @return Application|RedirectResponse|Redirector
   */
  public function store(Request $request)
  {
  if( request()->hasFile('main_picture') ) {
      
      $this->validateMainImage(); // will return false if the image is not the correct format/filesize
      
      $extension = request()->file('main_picture')->getClientOriginalExtension(); // get file extension
      $filename_to_store = time() . '_' . Str::random(40) . '.' . $extension; // filename to store
      
      // "Make" the resized image
      $resized = Image::make( request()->file('main_picture') )
                      ->resize(300, 300, function( $constraint ) {
                        $constraint->aspectRatio(); // preserve image's aspect ratio
                      });
      
      $save_resized = $resized->save('uploads/testprofiles/main_picture/' . $filename_to_store);
      
      $filename_resized = $save_resized->basename;
      
      
      $request['main_picture'] = $filename_resized;
    }
  
    TestProfile::create( $this->validateTestProfile() );
    
    return redirect( route('testprofiles.index') );
  }

  /* ... 
      ...
     ... */

protected function validateMainImage() {
    return request()->validate([
      'main_picture' => 'required|image|mimes:jpeg,jpg,png,gif|max:1024',
    ]);
  }

Now, the only thing that's left, is saving the proper filename of the image in the database, as it's still getting saved as a temporary system path, e.g. /private/var/tmp/phpPGy8PH

Activity icon

Replied to Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

Agreed, that was totally wrong :)

But now that I moved the conditional out of the validateTestProfile() function, into the store() method of the controller, right before TestProfile::create( $this->validateTestProfile() );, nothing seems to have changed. The validation still doesn't seem to kick in.

Activity icon

Started a new Conversation Mission Impossible ? [Laravel 6 + InterventionImage + Validation]

Hey everyone, this is my first post on Laracasts so bear with me :)

I'm trying to figure out how to safely validate a file (image) upload during the creation of a new model instance. I need to make use of the InterventionImage library, so that the image is manipulated (cropped) when the new model instance is created.

Here's my model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class TestProfile extends Model
{

  protected $fillable = [
    'name',
    'main_picture',
  ];
	
}

And this is my controller:


namespace App\Http\Controllers;

use App\TestProfile;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use Intervention\Image\Facades\Image;

class TestProfileController extends Controller
{
  
  /**
   * Display a listing of the TestProfiles.
   *
   * @return View
   */
  public function index()
  {
    $testprofiles = TestProfile::latest()->get();
    
    return view('testprofiles.index', ['testprofiles' => $testprofiles]);
  }
  
  
  /**
   * Display the specified TestProfile.
   *
   * @param TestProfile $testprofile
   *
   * @return View
   */
  public function show(TestProfile $testprofile)
  {
    return view('testprofiles.show', compact('testprofile'));
  }
  
  
  /**
   * Show the form for creating a new TestProfile.
   *
   * @return View
   */
  public function create()
  {
    return view('testprofiles.create');
  }
  
  
  /**
   * Store a newly created TestProfile in storage.
   *
   * @param Request $request
   *
   * @return Application|RedirectResponse|Redirector
   */
  public function store(Request $request)
  {
    TestProfile::create( $this->validateTestProfile() );
    
    return redirect( route('testprofiles.index') );
  }
  
  
  /**
   * Show the form for editing the specified TestProfile.
   *
   * @param TestProfile $testprofile
   *
   * @return View
   */
  public function edit(TestProfile $testprofile)
  {
    return view( 'testprofiles.edit', compact('testprofile') );
  }
  
  
  /**
   * Update the specified TestProfile in storage.
   *
   * @param Request         $request
   * @param TestProfile $testprofile
   *
   * @return Application|RedirectResponse|Redirector
   */
  public function update(Request $request, TestProfile $testprofile)
  {
    $testprofile->update( $this->validateTestProfile() );
    
    return redirect( route('testprofiles.show', $testprofile) );
  }
  
  
  /**
   * Remove the specified TestProfile from storage.
   *
   * @param TestProfile  $testprofile
   *
   * @return Response
   */
  public function destroy(TestProfile $testprofile)
  {
    //
  }
  
  
  /*   ---------------------
    UTILITIES
  ---------------------- */
  /**
   * Validates the input data. Useful for creating as well as updating a TestProfile.
   *
   * @return array
   */
  protected function validateTestProfile() {
    
    if( request()->hasFile('main_picture') ) {
      
      $extension = request()->file('main_picture')->getClientOriginalExtension(); // get file extension
      $filename_to_store = time() . '_' . Str::random(40) . '.' . $extension; // filename to store
      
      // "Make" the resized image
      $resized = Image::make( request()->file('main_picture') )
                      ->resize(300, 300, function( $constraint ) {
                        $constraint->aspectRatio(); // preserve image's aspect ratio
                      });
      
      $save_resized = $resized->save('uploads/testprofiles/main_picture/' . $filename_to_store);
      
      $filename_resized = $save_resized->basename;
      
      
      $request['main_picture'] = $filename_resized;
    }
    
    return request()->validate([
      'name' => 'required',
      'main_picture' => 'required|image|mimes:jpeg,jpg,png,gif|max:1024',
    ]);
  }
}


With my current setup, I'm getting an Unsupported Image Type exception from InterventionImage if I chose anything else other than an image (for example a .PDF file). However, if I chose an actual image file, the store() method within the controller is successfully executed, and the TestProfile instance gets created. My understanding is, that the validation doesn't work.

The second problem that I'm having with this approach, is that the main_image field of the TestProfile model instance in the database gets saved as a temporary system path, for example /private/var/tmp/phpPGy8PH.

I've been trying to figure this one out for a couple days now, and it's getting really frustrating. If anyone could help me out, I'd highly appreciate it.

Apr
21
5 months ago
Activity icon

Commented on Reduce Duplication

I don't seem to be able to figure out how would the validation techniques be adapted for a file input, for instance a featured image of the Article instance. Any thoughts? Thanks a lot.

Apr
15
5 months ago
Activity icon

Commented on CSRF Attacks, With Examples

The 419 HTTP status/response code is indeed not a part of RFC 2016 IETF specification. However, it is used by Laravel, as well as other libraries, as an alternative to the 401 HTTP response code. It simply provides a way for differentianting from unauthorized clients being denied access to specific resources provided by the server.

Activity icon

Commented on CSRF Attacks, With Examples

@jeromefitzpatrick If I'm not mistaken, the token is unique as it gets re-generated for each active user session. That's probably the reason why you referred to getting it as being the hard part, right? :)

Apr
04
5 months ago
Activity icon

Replied to Logout Event

@ienderli Still working, 4 years later :) Your anwer saved me probably several hours of looking for solutions!