This guide will help you upgrade from Earhart v1.x to v2.0.
Version 2.0 includes breaking changes that improve type safety, fix critical bugs, and streamline the API. Most applications will only need to make 2-3 small changes.
Estimated upgrade time: 10-15 minutes for most applications
- Update
config/services.phpconfiguration key - Update
getUsersInOrganisation()calls (if used) - Update
createMagicLink()calls (if used) - Update
UserDataproperty access (if accessing directly)
File: config/services.php
Change:
// OLD
'propelauth' => [
'redirect_url' => env('PROPELAUTH_CALLBACK_URL'),
// ...
],
// NEW
'propelauth' => [
'redirect' => env('PROPELAUTH_CALLBACK_URL'),
// ...
],Why: Aligns with PropelAuth's API naming conventions.
If you use: getUsersInOrganisation()
OLD:
$usersData = $earhart->getUsersInOrganisation($orgId);
echo "Total: " . $usersData->total_users;
foreach ($usersData->users as $user) {
echo $user->email;
}NEW:
$users = $earhart->getUsersInOrganisation($orgId);
echo "Total: " . count($users);
foreach ($users as $user) {
echo $user->email;
}If you need pagination metadata:
$result = $earhart->organisations()->getOrganisationUsers($orgId, pageSize: 50);
echo "Total: " . $result->totalItems;
echo "Page: " . $result->currentPage;
echo "Has more: " . ($result->hasMoreResults ? 'yes' : 'no');
foreach ($result->items as $user) {
echo $user->email;
}
// Get next page if available
if ($result->hasMoreResults) {
$nextPage = $result->nextPage();
}If you use: createMagicLink()
OLD:
$link = $earhart->createMagicLink(
userId: $user->userId,
redirectUrl: 'https://example.com/dashboard',
expiresInHours: 24
);NEW:
$link = $earhart->createMagicLink(
email: $user->email, // Changed from userId to email
redirectUrl: 'https://example.com/dashboard',
expiresInHours: 24,
createIfNotExists: false // New parameter
);Why: PropelAuth API uses email for magic link generation, not user ID.
If you access UserData properties directly (most applications don't):
OLD:
$user = $earhart->getUser($userId);
echo $user->first_name;
echo $user->last_name;
echo $user->email_confirmed;
echo $user->created_at->format('Y-m-d');NEW:
$user = $earhart->getUser($userId);
echo $user->firstName; // camelCase
echo $user->lastName; // camelCase
echo $user->emailConfirmed; // camelCase
echo $user->createdAt->format('Y-m-d'); // camelCaseComplete property mapping:
| Old (v1.x) | New (v2.0) |
|---|---|
user_id |
userId |
email_confirmed |
emailConfirmed |
first_name |
firstName |
last_name |
lastName |
picture_url |
pictureUrl |
has_password |
hasPassword |
mfa_enabled |
mfaEnabled |
can_create_orgs |
canCreateOrgs |
created_at |
createdAt |
last_active_at |
lastActiveAt |
update_password_required |
updatePasswordRequired |
Note: If you only use API methods like createUser(), updateUser(), etc., you likely don't need to change anything here. The API methods already accept camelCase parameters.
You can now use PHP's camelCase conventions throughout:
// This now works correctly:
$user = $earhart->createUser(
email: 'user@example.com',
firstName: 'John', // camelCase - automatically converted
lastName: 'Doe', // camelCase - automatically converted
emailConfirmed: true, // camelCase - automatically converted
);
// Access properties in camelCase:
echo $user->firstName; // "John"
echo $user->emailConfirmed; // trueEarhart automatically converts between PHP's camelCase and PropelAuth's snake_case API.
Methods now return properly typed objects:
// getUsersInOrganisation() returns array<UserData>
$users = $earhart->getUsersInOrganisation($orgId);
// IDE autocomplete works correctly now
// queryOrganisations() items are already OrganisationData objects
$result = $earhart->organisations()->queryOrganisations();
foreach ($result->items as $org) {
echo $org->displayName; // Proper type hints
}- Fixed double-wrapping bugs in
getUsersInOrganisation()andgetOrganisations() - Fixed systematic parameter naming issues across 20+ API methods
- Improved error messages for type mismatches
After upgrading, test these core flows:
$userId = $earhart->createUser(
email: 'test@example.com',
password: 'SecurePass123!',
firstName: 'Test',
lastName: 'User'
);
$user = $earhart->getUser($userId);
assert($user->firstName === 'Test');$users = $earhart->getUsersInOrganisation($orgId);
assert(is_array($users));
assert($users[0] instanceof \LittleGreenMan\Earhart\PropelAuth\UserData);$link = $earhart->createMagicLink(
email: 'user@example.com',
redirectUrl: 'https://example.com'
);
assert(str_starts_with($link, 'https://'));If you encounter issues during the upgrade:
- Check the CHANGELOG: See
CHANGELOG.mdfor detailed technical notes - Review API docs: See
docs/USING_PROPEL_API.mdfor updated examples - Run tests: Ensure your application tests pass after changes
- GitHub Issues: Report bugs or ask questions at the package repository
If you need to temporarily revert to v1.x:
composer require little-green-man/earhart:^1.6Then undo the configuration changes above.
Congratulations! You're now running Earhart v2.0 with improved type safety and automatic case conversion.