Upgrade Guide
Suggest Edit- Support Policy
- Release Strategy
- Upgrading to 14.0 from 13.x
- Updating Dependencies
- Laravel 10.x
- Preserving State
- Route Binding
- Listener
- Automatic HTTP Filtering and Sorting
- Navigation
- Icons
- Logout and Quit Impersonation
- Upgrading to 13.0 from 12.x
- Updating Dependencies
- jQuery
- Select2
- Upgrading to 12.0 from 11.x
- Updating Dependencies
- Laravel 9.x
- Upgrading to 11.0 from 10.x
- Updating Dependencies
- Publish Assets Files
- Icons
- Screen
- Component
- Metrics
- Upgrading to 10.0 from 9.x
- Updating Dependencies
- Menu
- CanSee
- Stimulus
- Turbo
- Compendium
- Collapse
- Upgrading to 9.0 from 8.x
- Updating Dependencies
- Auth
- Upgrading to 8.0 from 7.x
- Updating Dependencies
- TinyMCE Editor
- Settings Model
- Bread Crumbs
- Screen Changes
- Constructor
- Route methods
- Data Spoofing (Async)
- Layouts
- Release Message
- Icons
Support Policy
At Laravel Orchid, we aim to provide our users with the best possible support for our package. To ensure that we can provide efficient support, we will only provide support for the latest major release of our package. This includes bug fixes and security updates.
We recommend that you use the latest version of Laravel Orchid in your projects to take advantage of the latest features, bug fixes, and security updates.
If you have any questions or concerns about our support policy, please do not hesitate to contact us.
Release Strategy
We believe in keeping our package up-to-date and modern, and therefore follow a “release early, release often” approach for major releases. This means that we won’t wait an extended period of time to release a new major version. By releasing major versions more frequently, new features will be available sooner, and upgrading between versions will be more manageable.
We try to document all possible breaking changes. Some of these changes are internal calls, so only some of these changes may actually affect your application.
Upgrading to 14.0 from 13.x
Upgrading Laravel Orchid from version 13.x
to 14.0
can be a straightforward process if done correctly.
Before starting the upgrade process, it is important to backup your existing application and test the upgrade process in a development environment. This will ensure that any unexpected issues can be identified and addressed before affecting the production environment.
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^14.0
Laravel 10.x
Laravel 10 is now required to install or upgrade. Update descriptions for existing projects can be found in the documentation.
Preserving State
One of the main new features of the release is the ability to save the states of public properties between actions on the screen.
Let’s take an example. While viewing the screen in the query
method, we can set public properties that will be accessible in the name/layouts
methods and others.
Now, these public properties will be saved and available for the execution methods.
public $idea;
public function query() : array
{
return [
'idea' => Idea::first()
];
}
public function yourMethod()
{
$this->idea;
// The property is not empty and contains
// the value that was set at the beginning.
}
Route Binding
For a long time, Orchid has been using its own solution for defining route arguments. However, for the vast majority of methods (query/method), the same solution as with Controller is used. This allows you to define:
Route::screen('/posts/{post:slug}', ExampleScreen::class);
Route::screen('/task', ExampleScreen::class)->withTrashed();
It also provides other opportunities that were not explicitly tied to what you’re used to.
Please note that in the past, our tutorials sometimes specified the default model, which sometimes resulted in an empty parameter. However, this now triggers a 404 error.
Listener
Previously, working with Listeners could sometimes confuse users.
Therefore, Listeners no longer have a property that specifies the screen method.
Instead, there is a mandatory default method called handler
.
The current state of the screen is passed as the first argument to this method, and the request
object is passed as the second argument.
namespace App\Orchid\Layouts;
use Illuminate\Http\Request;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Layouts\Listener;
use Orchid\Screen\Repository;
use Orchid\Support\Facades\Layout;
class SubtractListener extends Listener
{
/**
* List of field names for which values will be listened.
*
* @var string[]
*/
protected $targets = [
'minuend',
'subtrahend',
];
/**
* @return Layout[]
*/
protected function layouts(): iterable
{
return [
Layout::rows([
Input::make('minuend')
->title('First argument')
->type('number'),
Input::make('subtrahend')
->title('Second argument')
->type('number'),
Input::make('result')
->readonly()
->canSee($this->query->has('result')),
]),
];
}
/**
* @param \Orchid\Screen\Repository $repository
* @param \Illuminate\Http\Request $request
*
* @return \Orchid\Screen\Repository
*/
public function handle(Repository $repository, Request $request): Repository
{
[$minuend, $subtrahend] = $request->all();
return $repository
->set('minuend', $minuend)
->set('subtrahend', $subtrahend)
->set('result', $minuend - $subtrahend);
}
}
Automatic HTTP Filtering and Sorting
The automatic filters were previously based on the type of data entered by the user, which often led to errors. For example, when the user used a comma to search for text, the filter would sometimes recognize it as an array. Therefore, filters now need to specify their behavior explicitly:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Orchid\Filters\Filterable;
use Orchid\Filters\Types\Like;
use Orchid\Filters\Types\Where;
class Post extends Model
{
use Filterable;
protected $allowedFilters = [
'id' => Where::class,
'content' => Like::class,
];
}
Another important change is that we now obtain the column name as-is. Therefore, you can no longer use dot notation for JSON fields. We are working on finding a more efficient and safer way to handle JSON fields in the future.
Navigation
In version 14.0, the profile drop-down menu has been removed.
Instead, it is suggested to specify the profile information in the main menu or on the screens.
Please make sure to remove any references to the Dashboard::MENU_PROFILE
constant and the registerProfileMenu
method for the service provider from your code.
For example, the following item will no longer work correctly:
public function registerProfileMenu(): array
{
return [
Menu::make('Documentation')
->title('Docs')
->icon('docs')
->url('https://orchid.software/en/docs'),
];
}
Instead, pen your menu items using the registerMenu
method:
public function registerMenu(): array
{
return [
Menu::make('Documentation')
->title('Docs')
->icon('docs')
->url('https://orchid.software/en/docs'),
];
}
All methods that depend on location
no longer need this argument. For example, the addMenuSubElements
method now points directly to the target slug:
use Orchid\Support\Facades\Dashboard;
Dashboard::addMenuSubElements('sub-menu', [
Menu::make('Sub element item 3')->icon('badge')
]);
Icons
In the new version, the icons have been updated to a set from Bootstrap. While replacing all the icons in existing applications can be a challenge, you have the option to continue using the icons from Orchid.
To do this, simply add the following line to your composer.json
file:
"orchid/icons": "^2.0",
And then specify in your configuration file:
'icons' => [
'orc' => \Orchid\IconPack\Path::getFolder(),
],
By doing this, you will continue to use the set of icons from Orchid, which has not been updated for some time due to a lack of a designer.
For the new icons to be displayed as well, add:
'icons' => [
// ...
'bs' => \Orchid\Support\BootstrapIconsPath::getFolder(),
],
Logout and Quit Impersonation
The behavior of the “Logout” and “Quit Impersonation” actions must be explicitly defined by the developer. To do this, you can add button definitions to your profile screen.
Here’s an example of how you can define these buttons:
use Orchid\Screen\Actions\Button;
use Orchid\Access\Impersonation;
public function commandBar(): iterable
{
return [
Button::make('Back to my account')
->canSee(Impersonation::isSwitch())
->icon('bs.people')
->route('platform.switch.logout'),
Button::make('Sign out')
->icon('bs.box-arrow-left')
->route('platform.logout'),
];
}
- The first button, “Back to my account”, is used to exit impersonation and return to the original user account. This button will only be visible if the user is currently impersonating another account.
- The second button, “Sign out”, is used to log out of the platform.
By specifying the behavior of these buttons yourself, you have more control over the exit and quit impersonation actions in your Orchid application.
Upgrading to 13.0 from 12.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^13.0
jQuery
There is no longer a default jQuery package in this release. If you need it, then you can install it separately, for example by adding a reference to it in the configuration file:
'resource' => [
'stylesheets' => [],
'scripts' => [
'https://code.jquery.com/jquery-3.6.0.min.js'
],
],
Select2
Since select2
had a jQuery
dependency, it was also replaced with the tom-select
package. We tried to keep the behavior where possible. But select2
special JS events are no longer available.
Upgrading to 12.0 from 11.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^12.0
Laravel 9.x
Laravel 9 is now required to install or upgrade. Update descriptions for existing projects can be found in the documentation.
Upgrading to 11.0 from 10.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^11.0
Publish Assets Files
Instead of creating a symbolic link to download resources, there is a new command to publish them:
php artisan orchid:publish
Which would place the JS/CSS
files in the public/vendor/orchid
directory. It will also be required to automate making changes to composer.json:
{
"scripts": {
"post-update-cmd": [
"@php artisan orchid:publish --ansi"
]
}
}
Icons
Icons can now be completely replaced and are not forced to load. To continue using them, change the configuration file:
'icons' => [
'orc' => \Orchid\IconPack\Path::getFolder(),
],
Screen
Public screen properties are now auto-filled with values by key from the query()
method. For instance:
class IdeaScreen extends Screen
{
public $name = 'Edit User';
public function query(): array
{
return [
'name' => 'Welcome',
];
}
}
The value of the name
property will be overwritten.
To avoid this, change the visibility of the property to protected
class IdeaScreen extends Screen
{
protected $name = 'Edit User';
public function query(): array
{
return [
'name' => 'Welcome',
];
}
}
Component
Specifying the expected argument name for components is no longer necessary:
// before
TD::make('index')->component(OrderShortInformation::class, 'order', [
'limit' => 100
]);
// after
TD::make('index')->component(OrderShortInformation::class, [
'limit' => 100
]);
Metrics
Instead of a separate class, the short syntax is now applied:
use Orchid\Support\Facades\Layout;
public function query(): array
{
return [
'metrics' => [
'sales' => ['value' => number_format(6851), 'diff' => 10.08],
'total' => number_format(65661),
],
];
}
public function layout(): iterable
{
return [
Layout::metrics([
'Sales Today' => 'metrics.sales',
'Total Earnings' => 'metrics.total',
]),
];
}
Upgrading to 10.0 from 9.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^10.0
Menu
Sections of the menu have been reduced, the system menu has been removed. Constants are now in the class Orchid\Platform\Dashboard
.
use Orchid\Platform\Dashboard;
Dashboard::MENU_MAIN;
Dashboard::MENU_PROFILE;
Menus are now Field
classes and have a unified syntax. Before:
ItemMenu::label('Example screen')
->icon('monitor')
->route('platform.example')
->title('Navigation')
->badge(function () {
return 6;
});
After:
use Orchid\Screen\Actions\Menu;
Menu::make('Example screen')
->icon('monitor')
->route('platform.example')
->title('Navigation')
->badge(function () {
return 6;
});
As you can see, the update should be very soft. But the differences will also be, for example, the writing of nested elements will be more visual:
Before:
ItemMenu::label('Dropdown menu')
->slug('example-menu')
->icon('code')
->withChildren(),
ItemMenu::label('Sub element item 1')
->place('example-menu')
->icon('bag'),
ItemMenu::label('Sub element item 2')
->place('example-menu')
->icon('heart'),
After:
Menu::make('Dropdown menu')
->icon('code')
->list([
Menu::make('Sub element item 1')->icon('bag'),
Menu::make('Sub element item 2')->icon('heart'),
]),
The default for sorting has been changed from 1000 to 0:
Menu::make('Example screen')
->icon('monitor')
->route('platform.example')
->title('Navigation')
->sort(2),
This is also true for nested elements:
Menu::make('Dropdown menu')
->icon('code')
->list([
Menu::make('Sub element item 1')->icon('bag')->sort(2),
Menu::make('Sub element item 2')->icon('heart')->sort(0),
]),
For dynamic definition, you need to add a slug method in which to pass a unique string:
Menu::make('Dropdown menu')
->slug('sub-menu')
->icon('code')
->list([
Menu::make('Sub element item 1')->icon('bag'),
Menu::make('Sub element item 2')->icon('heart'),
]),
And then add new items in our own packages like:
Dashboard::addMenuSubElements(Dashboard::MENU_MAIN, 'sub-menu', [
Menu::make('Sub element item 3')->icon('badge')
]);
Warning. If the menu is used deferred, then you need to follow the loading order
CanSee
Now Fields/Layouts/TD
and have a common trait. Without any restrictions. Now you can do this:
Input::make()->canSee(false);
TD::make()->canSee(false);
Layout::rows([])->canSee(false);
But now the definition inside the layer is different
// before
public function canSee(Repository $query): bool
{
return ...;
}
// after
public function isSee(): bool
{
return ...;
}
Stimulus
The Stimulus framework has been updated to version 2.0. Backward compatibility was retained, but the controller names got rid of the prefixes:
<!-- before: -->
<div data-controller="fields--checkbox">
<!-- after: -->
<div data-controller="checkbox">
Turbo
The Turbolinks library has been updated to Turbo for more details here: https://turbo.hotwire.dev/
If you used your own js scripts, then it is recommended to read their changes. For example:
// before
document.addEventListener("turbolinks:load", function() {
// ...
})
// after
document.addEventListener("turbo:load", function() {
// ...
})
Compendium
The Compendium
class has been removed. Recommend using a newer Legend
.
Collapse
The Collapse
class has been removed.
Upgrading to 9.0 from 8.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^9.0
Auth
The Laravel team has introduced new products Jetstream and Fortify, which replace the earlier laravel/ui. To ensure compatibility with various options, the dependency on laravel/ui ha
s been removed. And with it, the ability to recover your password.
New products provide two-factor user authentication, as well as a view of the last active sessions. In order not to compete with them, the same features were removed from the package.
Although migrations have been removed, the data stored in the database will not be removed automatically. To dismiss them, you need to execute the following SQL
code:
ALTER TABLE "users"
DROP COLUMN "last_login"
DROP COLUMN "uses_two_factor_auth"
DROP COLUMN "two_factor_secret_code"
DROP COLUMN "two_factor_recovery_code";
DELETE FROM migrations
WHERE migration = '2020_06_07_184338_added_columns_for_2fa';
After that, you need to remove the column data from your user model.
If you copied migration 2020_06_07_184338_added_columns_for_2fa
in project – don’t forget delete it.
Upgrading to 8.0 from 7.x
Updating Dependencies
In your composer.json
file, update the orchid/platform
dependency to ^8.0
TinyMCE Editor
The HTML
editor has been removed from the standard distribution. The code has been moved to a separate repository.
Settings Model
The settings model has also been removed. Data stored in the database will not be deleted automatically.
To remove them, you need to execute the following SQL
code:
If you copied migration 2015_12_02_181214_create_table_settings
in project – don’t forget delete it.
DROP TABLE settings;
DELETE FROM migrations
WHERE migration = '2015_12_02_181214_create_table_settings';
The source code is available for installation as a separate package.
Bread Crumbs
Package davejamesmiller/laravel-breadcrumbs
is replaced with tabuna/breadcrumbs
and should be installed automatically when the dependencies are updated.
Note: It may be necessary to remove the boot cache files in the
bootstrap/cache
directory.
The syntax of the new package allows you to display breadcrumbs right in the route definition:
Route::screen('example', ExampleScreen::class)
->name('platform.example')
->breadcrumbs(function (Trail $trail) {
return $trail->parent('platform.index')->push(__('Example screen'));
});
Alternatively, you can continue to use a separate file for them. To do this, you need to download it to the service provider:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
require base_path('routes/breadcrumbs.php');
}
}
If you used full class names, then you need to replace them with similar ones:
use Tabuna\Breadcrumbs\Breadcrumbs;
use Tabuna\Breadcrumbs\Trail;
Screen Changes
Constructor
Passing a Request
object and calling the parent class is no longer necessary. Before:
class PublicationScreen extends Screen
{
public function __construct(Request $request, Locator $locator)
{
$this->request = $request;
$this->locator = $locator;
}
}
The definition now looks like this:
class PublicationScreen extends Screen
{
public function __construct(Locator $locator)
{
$this->locator = $locator;
}
}
Route methods
Methods not used have been removed. It is no longer possible to access screens via the PUT|PATCH|DELETE
methods, the call must use GET|POSTS
to receive/send data.
Method | URI | Name
-----------------+--------------------------------------+--------------
GET|HEAD|POST | dashboard/idea/{method?} | platform.idea
Now, screen methods awaiting a model, if not present, will implement an empty model as well as controllers. More.
Data Spoofing (Async)
The {argument?}
Expectation has been removed from the address bar.
Now a separate route is used for the call:
$this->router
->post('async/{screen}/{method?}/{template?}', [AsyncController::class, 'load'])
->name('async');
Layouts
Each layer now inherits from the class Orchid\Screen\Layout
, rather than from Orchid\Screen\Layouts\Base
.
To declare layers via short syntax, the Orchid\Support\Facades\Layout
facade should now be used instead of the Orchid\Screen\Layout
class.
It was:
use Orchid\Screen\Layout;
Layout::row([
// ...
]);
Became:
use Orchid\Support\Facades\Layout;
Layout::row([
// ...
]);
Release Message
A system message informed users that a new version of the package was released. But they have no way to update without the help of a developer.
This was more annoying than keeping the software up to date. Therefore, it was removed, if you used it (By default only on the first screen), then you should remove its call as well as the blade
template. Screen call example:
return [
'status' => Dashboard::checkUpdate(),
];
Using a template in the screen:
Layout::view('platform::partials.update');
Icons
The icon display has been changed from font
to SVG
format.
Now the ->icon
methods do not accept the css
value to be set, but the file name.
In most cases, you only need to remove the icon-
prefix.