Laravel 8 from scratch - Notes

It's good to learn the foundation and this is it

It's good to learn the foundation and this is it


title: Post title
slug: post-title
excerpt: Lorem ipsum
date: 2021-05-21

<p> Lorem Ipsum</p>

Parsing

$document = YamlFrontMatter::parseFile(
	resource_path('post/post.html')
)

new post

class Post {
	public function __construct($title, $excerpt, $date, $body, $slug) {
		$this->title = $title;
		$this->excerpt = $excerpt;
		$this->date = $date;
		$this->body = $body;
		$this->slug = $slug;
	}
}

$post = new Post(
	$document->title,
	$document->excerpt,
	$document->date,
	$document->body(),
	$document->slug,
);

Problem : If you looping and opening up a new array use array_map.

//Example problem :
foreach ($posts as $post) {
	$newpost[] = $post;
}
//Example solution 1

$newpost = array_map(function($file) {
	$document = YamlFrontMatter::parseFile(
		resource_path('post/post.html')
	)
	return new Post(
		$document->title,
		$document->excerpt,
		$document->date,
		$document->body(),
		$document->slug,
	);
}

// Example solution 2 - using collection
$newpost = collect($files)
	->map(function($file) {
		$document = YamlFrontMatter::parseFile(
			resource_path($file)
		)
		return new Post(
			$document->title,
			$document->excerpt,
			$document->date,
			$document->body(),
			$document->slug,
		);
	})

public static function all() {
	return collect(File::files(resource_path("posts")))
		->map(fn($file) => YamlFrontMatter::parseFile($file))
		->map(fn($document) => new Post(
			$document->title,
			$document->excerpt,
			$document->date,
			$document->body(),
			$document->slug,
		))
		->sortByDesc('date')
	)
}
# php artisan tinker
cache()->forget('post.all'); # to forget cache
cache('post.all'); 
cache()->get('post.all');
cache(['foo' => 'buzz'], now()->addSeconds(3)); # cache for 3 seconds
cache('foo');
# make a components folder called layout
# to call this use <x-layout></x-layout>

# layout.blade.php
<body>
	{{ $slot }}
</body>

# post.blade.php
<x-layout>
	hello
</x-layout>
$users->pluck('name')
# is the same as 
$users->map(function($user) { $user->name; });
// this will ignore manually input id 
protected $guarded = ['id'];
DB::listen(function($query){
	logger($query->sql, $query->bindings); //Log::info($query);
});

tools : laravel clockwork (debug tools)

With in model

protected $with = ['category', 'author']; // put in model to add it globally
Post::without(['category', 'author'])->first(); // after globally but dont want

New tricks

// eloquent
$currentCategory->is($category); // compare
$category->latest(); // will get the latest
Post::with('category')->get(); // use with to fix n+1 fix

$query->when($filter['search'] ?? false, fn($query, $search) =>
	$query->where('title', 'like', '%'.$search.'%')
	$query->orWhere('body', 'like', '%'.$search.'%')
); // using when eloquent

Category::firstWhere('slug', request('category'));

// php
if (auth()->user()?->username == 'madindo') {
	abort(Response::HTTP_FORBIDDEN);
}

// alpine
<a href="#" x-data="{}" @click.prevent="document.querySelector('#logout-form').submit()">
Log Out</a>
<form id="logout-form" method="POST" action="/logout" class="hidden">
@csrf
</form>

// function
array_filter($numbers, function($number) {
	return $number <= self::MAX_NUMBER_ALLOWED;
});
array_filter(
    $numbers, fn($number) => $number <= self::MAX_NUMBER_ALLOWED
);

Routes

request()→routeIs(’home’)
$request->only('search') // get only search result using array

Blades

php artisan make:component CategoryDropdown
return view('components.category-dropdown', [
	'categories' => Category::all(),
	'currentCategory' => Category::firstWhere('slug', request('category')),
]);
<x-category-dropdown />

Foreign key migration

$table->foreignId('post_id')->constrained()->cascadeOnDelete();

Mailchimp adding to the newsletter

$mailchimp = new \MailchimpMarketing\ApiClient();
$mailchimp->setConfig([
	'apiKey' => config('services.mailchimp.key'),
	'server' => 'us6'
]);
try {
$response = $mailchimp->lists->addListMember('123123', [
	'email_address' => request('email'),
	'status' => 'subscribed'
])
} catch (\Exception $e) {
	throw \Illuminate\Validation\ValidationExeption::withmessages([
		'email' => 'This email could not be added to our newsletter
	])
}
return redirect('/')->with('success', 'You are now signed up');

Invoke

a common pattern when you’re creating a single-function controller

class NewsletterController extends Controller {
	public function __invoke(Newsletter $newsletter) {
		...
	}
}

Service container

// AppServiceProvider.php
public function register() {
	app()->bind(Newsletter::class, function() {
		$client = (new ApiClient)->setConfig([
			'apiKey' => config('services.mailchimp.key'),
			'server' => 'us6'
		]);
		return new MailChimpNewsletter($client)
	});
}

Services/Newsletter.php -> interface
interface Newsletter {
	public function subscribe(string $email, string $list = null);
}

//
class MailchimpNewsletter implements Newsletter {
	public function __construct(protected ApiClient $client) {
		...
	}
	public function subscribe(string$email, $string $list = null) {
		...
	}
}

class ConvertKitNewsletter implements Newsletter {
	public function subscribe(string $email, string $list = null) {
		...
	}
}

good example

$tenant = Tenant::findByDomain($request->hostName());

switch ($newsletterProvider = $tenant->newsletter_provider) {
    case 'campaign_monitor':
        $this->app->register(NewsletterService::class, function () {
            return new CampaignMonitorNewsletterService($tenant->createsend_api_key);
        });
        break;

    case 'mailchimp':
        $this->app->register(NewsletterService::class, function () {
            return new MailchimpNewsletterService(
                $tenant->mailchimp_api_key,
                $tenant->mailchimp_server_prefix
            );
        });
        break;

    default:
        throw new InvalidArgumentException(
            sprintf('Unsupported newsletter service [%s]', $newsletterProvider)
        );
}

Subscribe to You Live What You Learn

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe