{"id":25582501,"url":"https://github.com/andanteproject/timestampable-bundle","last_synced_at":"2025-04-12T18:20:26.268Z","repository":{"id":56947639,"uuid":"341196207","full_name":"andanteproject/timestampable-bundle","owner":"andanteproject","description":"A Symfony Bundle to handle create and update dates with Doctrine Entities","archived":false,"fork":false,"pushed_at":"2024-06-14T08:53:25.000Z","size":47,"stargazers_count":7,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T12:37:48.206Z","etag":null,"topics":["doctrine","doctrine-orm","symfony","symfony-bundle","timestamp","timestamps"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andanteproject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-22T12:39:58.000Z","updated_at":"2025-03-18T11:24:30.000Z","dependencies_parsed_at":"2024-06-14T09:58:34.156Z","dependency_job_id":"be57da86-47c4-47a6-b506-3902b30f8e84","html_url":"https://github.com/andanteproject/timestampable-bundle","commit_stats":{"total_commits":10,"total_committers":4,"mean_commits":2.5,"dds":0.6,"last_synced_commit":"db9f6ce8a04d68747a4b7c2b8bff23b597354d5e"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Ftimestampable-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Ftimestampable-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Ftimestampable-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Ftimestampable-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andanteproject","download_url":"https://codeload.github.com/andanteproject/timestampable-bundle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248610638,"owners_count":21132978,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["doctrine","doctrine-orm","symfony","symfony-bundle","timestamp","timestamps"],"created_at":"2025-02-21T05:16:43.183Z","updated_at":"2025-04-12T18:20:26.241Z","avatar_url":"https://github.com/andanteproject.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Andante Project Logo](https://github.com/andanteproject/timestampable-bundle/blob/main/andanteproject-logo.png?raw=true)\n# Timestampable Bundle \n#### Symfony Bundle - [AndanteProject](https://github.com/andanteproject)\n[![Latest Version](https://img.shields.io/github/release/andanteproject/timestampable-bundle.svg)](https://github.com/andanteproject/timestampable-bundle/releases)\n![Github actions](https://github.com/andanteproject/timestampable-bundle/actions/workflows/workflow.yml/badge.svg?branch=main)\n![Framework](https://img.shields.io/badge/Symfony-4.x|5.x|6.x|7.x-informational?Style=flat\u0026logo=symfony)\n![Php8](https://img.shields.io/badge/PHP-%208.x-informational?style=flat\u0026logo=php)\n![PhpStan](https://img.shields.io/badge/PHPStan-Level%208-syccess?style=flat\u0026logo=php) \n\nA Symfony Bundle to handle entities createdAt and updatedAt dates with Doctrine. 🕰 \n\n## Requirements\nSymfony 4.x-7.x and PHP 8.2.\n\n## Install\nVia [Composer](https://getcomposer.org/):\n```bash\n$ composer require andanteproject/timestampable-bundle\n```\n\n## Features\n- No configuration required to be ready to go but fully customizabile;\n- `createdAt` and `updatedAt` properties are `?\\DateTimeImmutable`;\n- Uses [Symfony Clock](https://symfony.com/doc/current/components/clock.html);\n- Does not override your `createdAt` and `updatedAt` values when you set them explicitly;\n- No annotation/attributes required;\n- Works like magic ✨.\n\n## Basic usage\nAfter [install](#install), make sure you have the bundle registered in your symfony bundles list (`config/bundles.php`):\n```php\nreturn [\n    /// bundles...\n    Andante\\TimestampableBundle\\AndanteTimestampableBundle::class =\u003e ['all' =\u003e true],\n    /// bundles...\n];\n```\nThis should have been done automagically if you are using [Symfony Flex](https://flex.symfony.com). Otherwise, just register it by yourself.\n\n\nLet's suppose we have a `App\\Entity\\Article` doctrine entity we want to track created and update dates.\nAll you have to do is to implement `Andante\\TimestampableBundle\\Timestampable\\TimestampableInterface` and use `Andante\\TimestampableBundle\\Timestampable\\TimestampableTrait` trait.\n\n```php\n\u003c?php\n\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Andante\\TimestampableBundle\\Timestampable\\TimestampableInterface;\nuse Andante\\TimestampableBundle\\Timestampable\\TimestampableTrait;\n\n/**\n * @ORM\\Entity()\n */\nclass Article implements TimestampableInterface // \u003c-- implement this\n{\n    use TimestampableTrait; // \u003c-- add this\n\n    /**\n     * @ORM\\Id\n     * @ORM\\GeneratedValue\n     * @ORM\\Column(type=\"integer\")\n     */\n    private ?int $id = null;\n\n    /**\n     * @ORM\\Column(type=\"string\")\n     */\n    private string $title;\n    \n    public function __construct(string $title)\n    {\n        $this-\u003etitle = $title;\n    }\n    \n    // ...\n    // Some others beautiful properties and methods ...\n    // ...\n}\n```\nMake sure to update you database schema following your doctrine workflow (`bin/console doctrine:schema:update --force` if you are a badass devil guy or with a [migration](https://www.doctrine-project.org/projects/doctrine-migrations/en/3.0/reference/introduction.html) if you choosed the be a better developer!).\n\nYou shoud see a new columns named `created_at` and `updated_at` ([can i change this?](#configuration-completely-optional)) or something similar based on your [doctrine naming strategy](https://www.doctrine-project.org/projects/doctrine-orm/en/2.8/reference/namingstrategy.html). \n\n#### Congrats! You're done! 🎉\n\nRemember that `TimestampableInterface` and `TimestampableTrait` are shortcut to use `CreatedAtTimestampableInterface`+`CreatedAtTimestampableTrait` and `UpdatedAtTimestampableInterface`+`UpdatedAtTimestampableTrait` at the same time!\nIf you need to track only **create date** or **update date** you can use these more specific interfaces!\n\n| To keep track of | Implement interface | Use this Trait | \n| --- | --- | --- |\n| **Create date** | `Andante\\TimestampableBundle\\Timestampable\\CreatedAtTimestampableInterface` | `Andante\\TimestampableBundle\\Timestampable\\CreatedAtTimestampableTrait` |\n| **Update date** | `Andante\\TimestampableBundle\\Timestampable\\UpdatedAtTimestampableInterface` | `Andante\\TimestampableBundle\\Timestampable\\UpdatedAtTimestampableTrait` |\n| **Both create and update dates** | `Andante\\TimestampableBundle\\Timestampable\\TimestampableInterface` | `Andante\\TimestampableBundle\\Timestampable\\TimestampableTrait` |\n\n## Usage with no trait\n```php\n\u003c?php\n\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Andante\\TimestampableBundle\\Timestampable\\TimestampableInterface;\n\n/**\n * @ORM\\Entity()\n */\nclass Article implements TimestampableInterface // \u003c-- implement this\n{\n    // No trait needed\n    \n    /**\n     * @ORM\\Id\n     * @ORM\\GeneratedValue\n     * @ORM\\Column(type=\"integer\")\n     */\n    private ?int $id = null;\n\n    /**\n     * @ORM\\Column(type=\"string\")\n     */\n    private string $title;\n    \n    // DO NOT use ORM annotations to map these properties. See bundle configuration section for more info \n    private ?\\DateTimeImmutable $createdAt = null; \n    private ?\\DateTimeImmutable $updatedAt = null; \n    \n    public function __construct(string $title)\n    {\n        $this-\u003etitle = $title;\n    }\n    \n    public function setCreatedAt(\\DateTimeImmutable $dateTime): void\n    {\n        $this-\u003ecreatedAt = $dateTime;\n    }\n\n    public function getCreatedAt(): ?\\DateTimeImmutable\n    {\n        return $this-\u003ecreatedAt;\n    }\n    \n    public function setUpdatedAt(\\DateTimeImmutable $dateTime): void\n    {\n        $this-\u003eupdatedAt = $dateTime;\n    }\n\n    public function getUpdatedAt(): ?\\DateTimeImmutable\n    {\n        return $this-\u003eupdatedAt;\n    }\n}\n```\nThis allows you to, for instance, to have **a different name** for your properties (E.g. `created` instead of `createdAt` and `updated` instead of `updatedAt`).\nBut you will need to explicit this in [bundle configuration](#configuration-completely-optional).\n\n## Configuration (completely optional)\nThis bundle is build thinking how to save you time and follow best practices as close as possible.\n\nThis means you can even ignore to have a `andante_timestampable.yml` config file in your application.\n\nHowever, for whatever reason (legacy code?), use the bundle configuration to change most of the behaviors as your needs.\n```yaml\nandante_timestampable:\n  default:\n    created_at_property_name: createdAt # default: createdAt\n                                        # The property to be used by default as createdAt date inside entities \n                                        # implementing CreatedAtTimestampableInterface or TimestampableInterface\n    updated_at_property_name: updatedAt # default: updatedAt\n                                        # The property to be used by default as updatedAt date inside entities \n                                        # implementing UpdatedAtTimestampableInterface or TimestampableInterface\n\n    created_at_column_name: created_at # default: null\n                                       # Column name to be used on database for create date. \n                                       # If set to NULL will use your default doctrine naming strategy\n    updated_at_column_name: updated_at # default: null\n                                       # Column name to be used on database for update date. \n                                       # If set to NULL will use your default doctrine naming strategy\n  entity: # You can use per-entity configuration to override default config\n    Andante\\TimestampableBundle\\Tests\\Fixtures\\Entity\\Organization:\n      created_at_property_name: createdAt\n    Andante\\TimestampableBundle\\Tests\\Fixtures\\Entity\\Address:\n      created_at_property_name: created\n      updated_at_property_name: updated\n      created_at_column_name: created_date\n      updated_at_column_name: updated_date\n```\n\nBuilt with love ❤️ by [AndanteProject](https://github.com/andanteproject) team.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandanteproject%2Ftimestampable-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandanteproject%2Ftimestampable-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandanteproject%2Ftimestampable-bundle/lists"}