If you created a foreign key in your database which should have been nullable, you have to create a database migration to fix that.
To make your foreign key nullable, you first need to delete the Foreign Key constraint, then change the field to be nullable and then create the Foreign Key constraint again.
<?php
return new class extends Migration {
public function up(): void
{
Schema::table('retailers', function (Blueprint $table) {
$table->dropForeign('retailers_import_id_foreign');
$table->unsignedBigInteger('import_id')
->nullable(true)
->change();
$table->foreign('import_id')
->references('id')
->on('import_files')
->nullOnDelete()
->cascadeOnUpdate();
});
}
};
Setting up the related testdata when creating Pest tests always keeps me searching for the syntax. Therefore, here a little reminder to self with links to the appropriate info in the Laravel documentation.
// belongsToMany: using the pivot table. NOTE the array as first argument!
$user = User::factory()
->hasAttached([$tag], [<pivot fields>], 'roles')
->create();
In order to get info about your clients browser, you need to install browscap.
ERROR: get_browser(): browscap ini directive not set
NOTE: you get this same error for different reasons! Check your logfiles to figure out what is the real reason for this error.
Reasons I encountered:
Browscap was not installed
To install Browscap on my Ubuntu (Docker image), I used the following site browscap.org.
It comes down to:
download the ini file
update (the correct! => fpm) php.ini file to load browscap
restart the webserver
In the terminal (or in your Dockerfile):
# install browscap to get browser information of the client
curl https://browscap.org/stream?q=PHP_BrowsCapINI --output ${PHPDIR}/mods-available/php_browscap.ini
# add it to php.ini under the [browscap] directive
sed -i "s|;browscap = extra/browscap.ini.*|browscap = \"${PHPDIR}/mods-available/php_browscap.ini\"|g" ${PHPDIR}/fpm/php.ini
Browscap ini file was not included in php.ini
You can check whether PHP found the browscap file by
ensuring you entered the correct path to the file in the step above
ensuring the webserver has read permissions for the file
place phpinfo() on a page and search for browscap. It should be mentioned there
browscap mentioned in phpinfo()
Calling get_browser() with the wrong arguments
This is a funky one as the ini directive is set.
A look at the laravel log helped: get_browser(): HTTP_USER_AGENT variable is not set, cannot determine user agent name
I used get_browser(null, true) as I found in an online example, but it really needs the user agent as the first argument.
I fixed it by using: `
get_browser($request->userAgent(), true)
Note that I use Laravel, hence the $request->userAgent(). You can replace this with $_SERVER['HTTP_USER_AGENT'] just as well.
Other useful links
If this didn’t work out, you might info about your usecase somewhere on these pages:
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();
What if you have a birthdate and you want to order the records by number of days until the next birthday?
That is what this query does. It takes into account that the birthdate is in the past and you want to get the next birthday given the current date.
SELECT
birthday
, TIMESTAMPDIFF(day, birthday, CURDATE())
,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
FROM users
order by 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
) asc
It’s based off of this answer on StackOverflow: https://stackoverflow.com/a/51407757
The difference is that it takes also works for people having their birthday today and ordering the records having NULL values for birthday at the end.
So people without their birthday are places last, where normally the NULL records are ordered first.
Execute the following queries to have your ‘created_at’ column the current timestamp upon creation and your ‘updated_at’ the current timestamp upon modification.
// set the default values
DB::statement("ALTER TABLE $table CHANGE created_at created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP")
DB::statement("ALTER TABLE $table CHANGE updated_at updated_at TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP");
Whenever I posted a specific form, I got a 502 error.
I only got it to work when I disabled (as in: rebuild Docker image to not contain) xdebug.
When I posted the form, there was this warning: PHP Warning: Unknown: Input variables exceeded 1000.
A quick search learned that I could set the PHP option max_input_vars to 3000. This made the whole thing working again so I could focus on why this big form has more than 1000 input vars….
; file xdebug.ini
;comment all to disable xdebug
;zend_extension="xdebug.so"
;xdebug.mode=debug,coverage
;xdebug.client_host=host.docker.internal
;xdebug.client_port=9003
;xdebug.start_with_request=trigger
; set PHP directive to allow for maximum 3000 input vars
; PHP Input Vars is a PHP security measure designed to limit the number
; of post variables you can use to execute a function. It defines the
; number of variables your server can use when running a function.
max_input_vars = 3000
I’ve been debugging for days to get my Ionic app working with the Laravel API backend.
The issue: logging in worked fine, but every subsequent API request failed with a 401.
The reason (I guess): the Ionic/capacitor app works with a referrer of capacitor://localhost. I think this messes up the cookie that is set to maintain the session.
So I had to switch over to something without cookies. Having already spend days on the issues, I went to work with JWT as I’ve done so before.