{"id":22342516,"url":"https://github.com/botble/data-synchronize","last_synced_at":"2025-07-30T01:32:44.054Z","repository":{"id":233508651,"uuid":"787338528","full_name":"botble/data-synchronize","owner":"botble","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-06T07:33:41.000Z","size":322,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-06T08:35:17.830Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/botble.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2024-04-16T10:36:36.000Z","updated_at":"2025-07-06T07:32:54.000Z","dependencies_parsed_at":"2024-07-10T12:29:02.483Z","dependency_job_id":"6a5c7084-118b-4840-8695-f9019bc64f37","html_url":"https://github.com/botble/data-synchronize","commit_stats":null,"previous_names":["botble/data-synchronize"],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/botble/data-synchronize","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botble%2Fdata-synchronize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botble%2Fdata-synchronize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botble%2Fdata-synchronize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botble%2Fdata-synchronize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/botble","download_url":"https://codeload.github.com/botble/data-synchronize/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botble%2Fdata-synchronize/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267792737,"owners_count":24144931,"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","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-04T08:12:56.759Z","updated_at":"2025-07-30T01:32:39.033Z","avatar_url":"https://github.com/botble.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Data Synchronize\n\n## Usage\n\n### Exporter\n\nThere are two ways to create an exporter.\n\n![Exporter](./art/exporter.png)\n\n#### Create an exporter using the command\n\nYou can use the `php artisan data-synchronize:make:exporter` command to create an exporter.\n\n```bash\nphp artisan data-synchronize:make:exporter PostExporter\n```\n\n#### Manually create an exporter\n\nThis is how an exporter should look like, below is an example of a `PostExporter` class.\n\n```php\n\u003c?php\n\nnamespace Botble\\Blog\\Exporters;\n\nuse Botble\\Blog\\Models\\Post;\nuse Botble\\DataSynchronize\\Exporter\\ExportColumn;\nuse Botble\\DataSynchronize\\Exporter\\Exporter;\nuse Illuminate\\Support\\Collection;\n\nclass PostExporter extends Exporter\n{\n    public function label(): string\n    {\n        return 'Posts';\n    }\n\n    public function columns(): array\n    {\n        return [\n            ExportColumn::make('name'),\n            ExportColumn::make('description'),\n            ExportColumn::make('created_at'),\n        ];\n    }\n\n    public function collection(): Collection\n    {\n        return Post::all();\n    }\n}\n```\n\nThis is how to use the exporter in a controller.\n\n```php\n\u003c?php\n\nnamespace Botble\\Blog\\Http\\Controllers;\n\nuse Botble\\DataSynchronize\\Exporter\\Exporter;\nuse Botble\\DataSynchronize\\Http\\Controllers\\ExportController;\nuse Botble\\Blog\\Exporters\\PostExporter;\n\nclass ExportPostController extends ExportController\n{\n    protected function getExporter(): Exporter\n    {\n        return PostExporter::make();\n    }\n}\n```\n\nAnd then register the route in your routes file.\n\n```php\nuse Botble\\Base\\Facades\\AdminHelper;\nuse Illuminate\\Support\\Facades\\Route;\nuse Botble\\Blog\\Http\\Controllers\\ExportPostController;\n\nAdminHelper::registerRoutes(function () {\n    Route::prefix('tools/data-synchronize')-\u003ename('tools.data-synchronize.')-\u003egroup(function () {\n        Route::group(['prefix' =\u003e 'export/posts', 'as' =\u003e 'export.posts.', 'permission' =\u003e 'posts.export'], function () {\n            Route::get('/', [ExportPostController::class, 'index'])-\u003ename('index');\n            Route::post('/', [ExportPostController::class, 'store'])-\u003ename('store');\n        });\n    });\n});\n```\n\nEach exporter route should have a permission to access it. You can use the `permission` key in the route group to define\nthe permission.\n\nIn above route definition, the permission is `posts.export` key and it parent is `tools.data-synchronize`. You can\ndefine the permission in the `permissions.php` of your plugin.\n\n```php\nreturn [\n    [\n        'name' =\u003e 'Export Posts',\n        'flag' =\u003e 'posts.export',\n        'parent_flag' =\u003e 'tools.data-synchronize',\n    ],\n];\n```\n\nNow you can navigate to `http://your-domain/tools/data-synchronize/export/posts` to export posts.\n\n#### Add exporter to Export/Import Data panel section\n\n![Panel Section](./art/panel-section-1.png)\n\nTo add the exporter to the Export/Import Data panel section, you can use the `beforeRendering` method of\nthe `PanelSectionManager` class to register the exporter into the panel section.\n\n```php\nuse Botble\\Base\\Facades\\PanelSectionManager;\nuse Botble\\Base\\PanelSections\\PanelSectionItem;\nuse Botble\\DataSynchronize\\PanelSections\\ExportPanelSection;\n\npublic function boot(): void\n{\n    // ...\n\n    PanelSectionManager::setGroupId('data-synchronize')-\u003ebeforeRendering(function () {\n        PanelSectionManager::default()\n            -\u003eregisterItem(\n                ExportPanelSection::class,\n                fn () =\u003e PanelSectionItem::make('posts')\n                    -\u003esetTitle('Posts')\n                    -\u003ewithDescription('Export post data to CSV or Excel file.')\n                    -\u003ewithPriority(120)\n                    -\u003ewithRoute('tools.data-synchronize.export.posts.index')\n                    -\u003ewithPermission('posts.export')\n            );\n    });\n    \n    // ...\n}\n```\n\nYou can see the exporter in the **Export/Import Data** panel section.\n\n![Panel Section](./art/panel-section-2.png)\n\n### Importer\n\nThere are two ways to create an importer.\n\n![Importer](./art/importer.png)\n\n#### Create an importer using the command\n\nYou can use the `php artisan data-synchronize:make:importer` command to create an importer.\n\n```bash\nphp artisan data-synchronize:make:importer PostImporter\n```\n\n#### Manually create an importer\n\nThis is how an importer should look like, below is an example of a `PostImporter` class.\n\n```php\n\u003c?php\n\nnamespace Botble\\Blog\\Importers;\n\nuse Botble\\Blog\\Models\\Post;\nuse Botble\\DataSynchronize\\Importer\\ImportColumn;\nuse Botble\\DataSynchronize\\Importer\\Importer;\n\nclass PostImporter extends Importer\n{\n    public function chunkSize(): int\n    {\n        return 1000;\n    }\n\n    public function label(): string\n    {\n        return 'Posts';\n    }\n    \n    public function getValidateUrl(): string\n    {\n        return route('tools.data-synchronize.import.posts.validate');\n    }\n\n    public function getImportUrl(): string\n    {\n        return route('tools.data-synchronize.import.posts.store');\n    }\n\n    public function getDownloadExampleUrl(): ?string\n    {\n        return route('tools.data-synchronize.import.posts.download-example');\n    }\n\n    public function columns(): array\n    {\n        return [\n            ImportColumn::make('name')-\u003erules(['required', 'string']),\n            ImportColumn::make('description')-\u003erules(['required', 'string']),\n            ImportColumn::make('created_at')-\u003erules(['required', 'string']),\n        ];\n    }\n    \n    public function examples(): array\n    {\n        return [\n            [\n                'name' =\u003e 'Post 1',\n                'description' =\u003e 'Description 1',\n                'created_at' =\u003e '2021-01-01 00:00:00',\n            ],\n            [\n                'name' =\u003e 'Post 2',\n                'description' =\u003e 'Description 2',\n                'created_at' =\u003e '2021-01-02 00:00:00',\n            ],\n        ];\n    }\n\n    public function handle(array $data): int\n    {\n        $total = 0;\n        \n        foreach ($data as $item) {\n            Post::create($item);\n            $total++;\n        }\n        \n        return $total;\n    }\n}\n```\n\nThis is how to use the importer in a controller.\n\n```php\n\u003c?php\n\nnamespace Botble\\Blog\\Http\\Controllers;\n\nuse Botble\\DataSynchronize\\Http\\Controllers\\ImportController;\nuse Botble\\DataSynchronize\\Importer\\Importer;\n\nclass ImportPostController extends ImportController\n{\n    protected function getImporter(): Importer\n    {\n        return PostImporter::make();\n    }\n}\n```\n\nAnd then register the route in your routes file.\n\n```php\nuse Botble\\Base\\Facades\\AdminHelper;\n\nAdminHelper::registerRoutes(function () {\n    Route::prefix('tools/data-synchronize')-\u003ename('tools.data-synchronize.')-\u003egroup(function () {\n        Route::group(['prefix' =\u003e 'import/posts', 'as' =\u003e 'import.posts.', 'permission' =\u003e 'posts.import'], function () {\n            Route::get('/', [ImportPostController::class, 'index'])-\u003ename('index');\n            Route::post('', [ImportPostController::class, 'store'])-\u003ename('store');\n            Route::post('validate', [ImportPostController::class, 'validateData'])-\u003ename('validate');\n            Route::get('download-example', [ImportPostController::class, 'downloadExample'])-\u003ename('download-example');\n        });\n    });\n});\n```\n\nEach importer route should have a permission to access it. You can use the `permission` key in the route group to define the permission.\n\nIn above route definition, the permission is `posts.import` key and it parent is `tools.data-synchronize`. You can define the permission in the `permissions.php` of your plugin.\n\n```php\nreturn [\n    [\n        'name' =\u003e 'Import Posts',\n        'flag' =\u003e 'posts.import',\n        'parent_flag' =\u003e 'tools.data-synchronize',\n    ],\n];\n```\n\nNow you can navigate to `http://your-domain/tools/data-synchronize/import/posts` to import posts.\n\n#### Add importer to Export/Import Data panel section\n\nTo add the importer to the Export/Import Data panel section, you can use the `beforeRendering` method of the `PanelSectionManager` class to register the importer into the panel section.\n\n```php\nuse Botble\\Base\\Facades\\PanelSectionManager;\nuse Botble\\Base\\PanelSections\\PanelSectionItem;\nuse Botble\\DataSynchronize\\PanelSections\\ImportPanelSection;\n\npublic function boot(): void\n{\n    // ...\n\n    PanelSectionManager::setGroupId('data-synchronize')-\u003ebeforeRendering(function () {\n        PanelSectionManager::default()\n            -\u003eregisterItem(\n                ImportPanelSection::class,\n                fn () =\u003e PanelSectionItem::make('posts')\n                    -\u003esetTitle('Posts')\n                    -\u003ewithDescription('Import post data from CSV or Excel file.')\n                    -\u003ewithPriority(120)\n                    -\u003ewithRoute('tools.data-synchronize.import.posts.index')\n                    -\u003ewithPermission('posts.import')\n            );\n    });\n    \n    // ...\n}\n```\n\nYou can see the importer in the **Export/Import Data** panel section.\n\n### Import/Export data from command line\n\n\u003cimg width=\"1136\" alt=\"Screenshot 2024-07-23 at 20 31 23\" src=\"https://github.com/user-attachments/assets/5c85f3a6-3e07-427c-92be-9732d468719f\"\u003e\n\n\u003cimg width=\"1136\" alt=\"Screenshot 2024-07-24 at 04 30 45\" src=\"https://github.com/user-attachments/assets/a5ee3f49-d47b-4faf-a76d-16fa3b2dd457\"\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotble%2Fdata-synchronize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbotble%2Fdata-synchronize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotble%2Fdata-synchronize/lists"}