This page is dedicated to all developers who want to contribute to Kimai. You are the best!
All you need is:
- PHP >= 7.1
- PHP extension:
PDO-SQLite
enabled
Optional requirement:
- a MySQL/MariaDB instance
- PHP extension:
PDO-MySQL
enabled
You could even test PostgreSQL and tell us how it works!
If you want to make changes to CSS / Javascripts, you need:
Please install Yarn for your OS and then:
yarn install
To rebuild all assets you have to execute:
yarn run dev
or
yarn run prod
You can find more information at:
- https://symfony.com/doc/current/frontend/encore/installation.html
- https://symfony.com/doc/current/frontend.html
If you want to run Kimai in a subdirectory, you have to rebuild the frontend assets with a different webpack configuration.
Edit the file webpack.config.js and change .setPublicPath('/build/')
to your needs.
After that re-compile the assets (see above).
You can run unit and integration tests with built-in commands like that:
bin/console kimai:test-unit
bin/console kimai:test-integration
You can run the code sniffer with a built-in command like that:
bin/console kimai:phpcs
You can also automatically fix the violations by running:
bin/console kimai:phpcs --fix
Be aware that this command will modify all files with violations in the directories src/
and tests/
, so its a good idea to commit first.
Our code-styles are configured in .php_cs.dist.
We try to keep the number of language files small, in order to make it easier to identify the location of application messages and to unify the codebase.
- If you add a new key, you have to add it in every language file
- Its very likely that you want to edit the file
messages
as it holds 90% of our application translations
The files in translations/
as a quick overview:
AvanzuAdminTheme
is only meant for translating strings from the original themeexceptions
only holds translations of error pages and exception handlersflashmessages
hold all success and error messages, that will be shown as results from action calls after page reloadmessages
holds most of the visible application translations (like all the static UI elements and form translations)pagerfanta
includes the translations for the pagination componentsidebar
holds all the translations of the right sidebarvalidators
only hold translations related to violations/validation of submitted form data (or API calls)
If you want to add your own entries in the navigation bar, you can subscribe to these events:
App\EventConfigureMainMenuEvent::CONFIGURE
App\ConfigureAdminMenuEvent::CONFIGURE
And that's how to use it:
use App\Event\ConfigureMainMenuEvent;
use App\Event\ConfigureAdminMenuEvent;
use Avanzu\AdminThemeBundle\Model\MenuItemModel;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ConfigureMainMenuEvent::CONFIGURE => ['onMainMenuConfigure', 100],
ConfigureAdminMenuEvent::CONFIGURE => ['onAdminMenuConfigure', 100],
];
}
public function onMainMenuConfigure(ConfigureMainMenuEvent $event)
{
$event->getMenu()->addItem(
new MenuItemModel('timesheet', 'menu.timesheet', 'timesheet', [], 'fa fa-clock-o')
);
}
public function onAdminMenuConfigure(ConfigureAdminMenuEvent $event)
{
$event->getAdminMenu()->addChild(
new MenuItemModel('timesheet_admin', 'menu.admin_timesheet', 'admin_timesheet', [], 'fa fa-clock-o')
);
}
}
For more details check the official menu subscriber.
We use twig globals to render the control sidebar tabs, so adding one is as easy as adding a new config entry:
twig:
globals:
kimai_context:
control_sidebar:
# these are the official tabs
settings:
icon: gears
controller: 'App\Controller\SidebarController::settingsAction'
home:
icon: question-circle-o
template: sidebar/home.html.twig
You have to define the icon
(font-awesome without the fa-
prefix) to be used and one of controller
action or template
.
Both follow the default naming syntax and you can easily link your bundle here instead of the app controller or templates.
You should NOT add them in config/packages/kimai.yaml
but in your own bundle config, otherwise they might get lost in a Kimai update.
An invoice renderer is a controller action that receives an instanceof App\Model\InvoiceModel
and returns a HTML response.
This HTML response is the preview inside for the invoice screen.
Adding invoice renderer can be achieved by adding keys to the configuration kimai.invoice.renderer
like this:
kimai:
invoice:
renderer:
default: 'App\Controller\InvoiceController::invoiceAction'
The name of the renderer must be unique, please prefix it with your vendor or bundle name and make sure it only contains character as it will be stored in a database column.
An invoice calculator is a class extending App\Invoice\CalculatorInterface
and is responsible for calculating
invoice rates, taxes and such.
Adding invoice calculator can be achieved by adding keys to the configuration kimai.invoice.calculator
like this:
kimai:
invoice:
calculator:
default: 'App\Invoice\DefaultCalculator'
The name of the calculator must be unique, please prefix it with your vendor or bundle name and make sure it only contains character as it will be stored in a database column.
An invoice-number generator is a class extending App\Invoice\NumberGeneratorInterface
and its only task is to generate
a number for the invoice. In most cases you do not want to mix multiple invoice-number generators througout your invoice templates.
Adding invoice-number generator can be achieved by adding keys to the configuration kimai.invoice.number_generator
like this:
kimai:
invoice:
number_generator:
default: 'App\Invoice\DateNumberGenerator'
The name of the number generator must be unique, please prefix it with your vendor or bundle name and make sure it only contains character as it will be stored in a database column.
A timesheet calculator will be called on stopped timesheet records. It can rewrite all values but will normally take care
of the columns begin
, end
, duration
and rate
but could also be used to apply a default description
.
Timesheet calculator need to implement the interface App\Timesheet\CalculatorInterface
and will be automatically tagged
as timesheet.calculator
in the service container. They will be found and used only if you add them to the service container.
You can apply several rules in the config file kimai.yaml for the existing
DurationCalculator
and RateCalculator
implementations. Please read the configurations chapter to find out more.
The configuration for "rounding rules" can be fetched from the container parameter kimai.timesheet.rounding
.
The configuration for "hourly-rates multiplication factors" can be fetched from the container parameter kimai.timesheet.rates
.