Open your settings in PHPStorm and go to Tools > File Watchers
Add a new Custom File Watcher and use the following information:
Name: pint
File type: PHP
Program: $ProjectFileDir$/vendor/bin/pint
Arguments: $FileRelativePath$
Output paths to refresh: $FileRelativePath$
Working directory: $ProjectFileDir$
In this post I will show you how to change an existing field in your Laravel application to change to enum.
I have a field status which was kept in line by having class constants defining the value for this field. But I really missed the database keeping the value in line though.
Changing the class constants to a PHP 8 enum and changing the database field to enum had some caveats so if you want to change your datatype to enum as well, follow along.
I use the trait EnumEnhancements
for the enum as this provides very handy helper methods:
ImportStatus::valueArray()
: an array with the values of the enumImportStatus::valueList()
: a string with the values of the enum: ‘pending, validating, importing, …’
<?php
declare(strict_types=1);
namespace App\Models\Enums;
use Othyn\PhpEnumEnhancements\Traits\EnumEnhancements;
enum ImportStatus: string
{
use EnumEnhancements;
case PENDING = 'pending';
case VALIDATING = 'validating';
case VALIDATION_FAILED = 'validation_failed';
case VALIDATED = 'validated';
case CREATING_IMPORT_JOBS = 'creating_import_jobs';
case IMPORT_JOBS_CREATED = 'import_jobs_created';
case IMPORTING = 'importing';
case IMPORTED = 'imported';
case FAILED = 'failed';
case CANCELLED = 'cancelled';
case FINISHED = 'finished';
}
NOTE: changing an existing field to an enum in your database requires you to do this with a DB statement. You cannot use a query builder for this or you’ll get the following error :
Unknown column type "enum" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.
I change the existing column from a string to an enum in 4 steps:
<?php
declare(strict_types=1);
use App\Models\Enums\ImportStatus;
use App\Models\ImportFile;
use Illuminate\Database\Migrations\Migration;
return new class () extends Migration {
public function up(): void
{
// 1. Get the current status for each row
$importFiles = DB::table('posts')->get(['id', 'status']);
// 2. Set all statuses to NULL
DB::table('posts')->update(['status' => null]);
// 3. Change the column to an enum
$this->changeStatusToEnum();
// 4. Set the status for each row to the value we got in step 1
foreach ($products as $product) {
$validStatuses = collect(ImportStatus::valueArray());
$currentStatus = strtolower($product->status ?? '');
$currentStatus = $currentStatus === 'success'
? ImportStatus::FINISHED->value
: $currentStatus;
$newStatus = $validStatuses->contains($currentStatus)
? $currentStatus
: ImportStatus::PENDING->value;
// update the status, if one fails set the status to
// the default value
Post::where('id', $post->id)
->update(['status' => $newStatus]);
}
}
private function changeStatusToEnum(): void
{
// note: enums cannot be changed with migrations.
// It has to be done with a DB statement
$validEnumValues = ImportStatus::valueList("', '");
$defaultValue = ImportStatus::PENDING->value;
$query = "ALTER TABLE posts";
$query .= "MODIFY COLUMN status enum('{$validEnumValues}') ";
$query .= "DEFAULT '{$defaultValue}'";
DB::statement($query);
}
};
A little drawback is that I can no longer refer to the values as ImportStatus::validating
as that is now returning an enum
instead of a string.
To get the value of an enum
you have to call the value
property on it: ImportStatus::validating->value
So change your codebase by replacing ImportStatus::validating
to ImportStatus::validating->value
You might want to order your users by ‘days until their birthday’.
People having their birthday come first, people with no birthday registered (NULL values), come last.
// in User model
public static function getByBirthday()
{
return User::query()
->select('user.*')
->selectRaw(
'365.25 -
(
case
WHEN TIMESTAMPDIFF(day, birthday, CURDATE()) = 0 THEN 364.25
WHEN birthday IS NULL THEN 0
ELSE TIMESTAMPDIFF(day, birthday, CURDATE())
end
mod 365.25
) AS days_till_birthday'
)
->orderBy('days_till_birthday');
}
// use it in your code like
$usersByBirthday = User::getByBirthday()->get();
When you want to assert that a variable has a specific value, you can use assert.
Note
1. that you return the value in the execute script
part
2. !! that you don’t add the curly braces in the assert
value.
For me, it turned out the stateful
property in config/sanctum.php
was not filled correctly.
After setting it to the default as shown below, it started working.
// file config/sanctum.php
...
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
...
Did this not fix your problem?
Check this post which might help: https://stackoverflow.com/a/69858100
When you want your tests to be able to run whenever you want, you should use values which are random.
In Postman, click on the name of Collection and then open the ‘Pre-request Script’ tab.
There, add the following:
// get a random number between a minimum and a maximum
// gives you current datetime with milliseconds like 2022810_171012_174
postman.setGlobalVariable("getCurrentDate", () => {
const date=new Date();
return String(date.getFullYear())
+ String(date.getMonth()+1)
+ String(date.getDate())
+ '_'
+ String(date.getHours() < 10 ? "0"+date.getHours() : date.getHours())
+ String(date.getMinutes() < 10 ? "0"+date.getMinutes() : date.getMinutes())
+ String(date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds())
+ '_'
+ String(date.getMilliseconds())
})
You can now use this function in your tests. This enables you to make your strings (like emailaddresses) random by adding the current datetime to it.
To use it, open your test, click on the ‘Pre-request Script’ tab and add the following.
var currentDate = eval(pm.globals.get("getCurrentDate"))();
var randomEmail = `postman-${currentDate}@pauledenburg.com`;
pm.environment.set("randomEmail", randomEmail);
You can now use the generated value in the body of your POST-request by referencing it as {{randomEmail}}
First of all: do check the Gulp documentation on this: https://gulpjs.com/docs/en/getting-started/async-completion#using-async-await
I had the following gulpfile.js
:
# file gulpfile.js
function build() {
return series(
clean,
parallel(
images,
tracker,
fonts
),
clean_busters
);
}
exports.build = build;
When running gulp build
I got the following errors:
$ gulp build
[11:17:33] Using gulpfile ./gulpfile.js
[11:17:46] The following tasks did not complete: build
[11:17:46] Did you forget to signal async completion?
I fixed it by making the build()
function async: async build()
.
Then my gulpfile.js
looked like the following (note the extra parentheses at the end!)
# file gulpfile.js
async function build() {
return series(
clean,
parallel(
images,
tracker,
fonts
),
clean_busters
)();
}
exports.build = build;
This shows you how to enable logging so you can write stuff like $app->log->debug('this will show up in the error_log');
.
<?php --- snip %< --- $app = new \Slim\Slim(array( 'log.enabled' => true, 'log.level' => \Slim\Log::DEBUG )); $app->log->debug('this will show up in your error-log'); --- >% /snip ---
[opt-in]
I spend a lot of time figuring out why I kept getting a ‘404 Not Found’ when I wanted to renew my SSL Certificate with certbot.
Long story short: invalid ipv6 DNS Mapping.
I got it working by removing the ipv6 DNS entry. I’ll be fixing it in a proper way when there is more time available.
But there were other gotcha’s as well:
[opt-in]
Want to run a CLI command on Docker while debugging it with XDebug in an IDE like PHPStorm?
Then you need to have your environment in order.
First, create the path mappings in PHPStorm by creating a server in Settings / Preferences | Languages & Frameworks | PHP | Servers.
Continue reading