├── src
├── Exceptions
│ └── FragmentFileNotFound.php
├── Commands
│ └── ImportFragments.php
├── Exporter.php
└── Importer.php
├── .editorconfig
├── LICENSE.md
├── composer.json
├── CHANGELOG.md
└── README.md
/src/Exceptions/FragmentFileNotFound.php:
--------------------------------------------------------------------------------
1 |
4 |
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spatie/fragment-importer",
3 | "description": "Import fragments with excel files",
4 | "keywords": [
5 | "spatie",
6 | "fragment-importer"
7 | ],
8 | "homepage": "https://github.com/spatie/fragment-importer",
9 | "license": "MIT",
10 | "authors": [
11 | {
12 | "name": "Freek Van der Herten",
13 | "email": "freek@spatie.be",
14 | "homepage": "https://spatie.be",
15 | "role": "Developer"
16 | }
17 | ],
18 | "require": {
19 | "php" : "^7.0",
20 | "illuminate/console": "^5.2",
21 | "maatwebsite/excel": "^2.1",
22 | "illuminate/support": "^5.2"
23 | },
24 | "require-dev": {
25 | "phpunit/phpunit": "^5.7",
26 | "spatie/laravel-translation-loader": "^1.0",
27 | "orchestra/testbench": "^3.2"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "Spatie\\FragmentImporter\\": "src"
32 | }
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "Spatie\\FragmentImporter\\Test\\": "tests"
37 | }
38 | },
39 | "scripts": {
40 | "test": "vendor/bin/phpunit"
41 | },
42 | "minimum-stability": "dev",
43 | "prefer-stable": true
44 | }
45 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All Notable changes to `fragment-importer` will be documented in this file
4 |
5 | ## 3.2.0 - 2017-03-09
6 | - make output more verbose
7 |
8 | ## 3.1.1 - 2016-01-26
9 | - fix deps
10 |
11 | ## 3.0.1 - 2016-01-25
12 | - fix deps
13 |
14 | ## 3.0.0 - 2016-10-10
15 | - make compatible with `laravel-translation-loader`
16 |
17 | ## 2.0.6 - 2016-09-22
18 | - Fixed an issue that would create duplicates when updating fragments
19 | - Internal refactors & integration tests
20 |
21 | ## 2.0.5 - 2016-08-23
22 | - L5.3
23 |
24 | ## 2.0.4 - 2016-08-11
25 | - Stability improvements
26 |
27 | ## 2.0.3 - 2016-06-17
28 |
29 | - Restore importer
30 |
31 | ## 2.0.2 - 2016-06-15
32 |
33 | **This version is bugged, do not use**
34 |
35 | - Bugfixes
36 |
37 | ## 2.0.1 - 2016-06-15
38 |
39 | - Replaced translation api with `spatie/laravel-translatable`'s
40 | - Separated Excel load from import
41 |
42 | ## 1.0.6 - 2016-03-01
43 |
44 | - Import all languages set in `app.locales`
45 |
46 | ## 1.0.5 - 2016-03-01
47 |
48 | - Export all languages set in `app.locales`
49 |
50 | ## 1.0.4 - 2016-02-18
51 |
52 | - Added some margin for errors when Excel rows are empty
53 |
54 |
55 | ## 1.0.3 - 2016-02-04
56 |
57 | - Fixed syntax error
58 |
59 | ## 1.0.2 - 2016-02-04
60 |
61 | ### this version is broken, do not use
62 |
63 | - Set draft column to false by default
64 |
65 | ## 1.0.1 - 2016-02-02
66 |
67 | - Remove usages of fragment repository
68 |
69 | ## 1.0.0 - 2016-02-02
70 |
71 | - Initial release
72 |
--------------------------------------------------------------------------------
/src/Commands/ImportFragments.php:
--------------------------------------------------------------------------------
1 | option('update')) {
21 | Artisan::call('backup:run', ['--only-db' => true]);
22 | $this->comment('Database dumped');
23 | $importer->updateExistingFragments();
24 | }
25 |
26 | Cache::flush();
27 | $this->comment('Cache cleared');
28 |
29 | $latestExcelFile = $this->getLatestFragmentExcel();
30 |
31 | $this->comment("Importing fragments from {$latestExcelFile}");
32 | $importer->import($latestExcelFile);
33 |
34 | $this->info($this->getImportMessage($importer));
35 | }
36 |
37 | public function getLatestFragmentExcel() : string
38 | {
39 | $directory = database_path('seeds/data');
40 |
41 | $files = collect(glob("{$directory}/fragments*.xlsx"));
42 |
43 | if ($files->isEmpty()) {
44 | throw new \Exception("could not find any fragment files in directory `{$directory}`");
45 | }
46 |
47 | return $files->last();
48 | }
49 |
50 | protected function getImportMessage($importer): string
51 | {
52 | $newFragments = $importer->getNewFragments()->implode('key', ', ');
53 |
54 | if ($this->option('update')) {
55 | return 'Imported all fragments'.($newFragments ? " including new fragments: {$newFragments}" : '.');
56 | }
57 |
58 | if ($newFragments) {
59 | return "Imported only the following new fragments: {$newFragments}";
60 | }
61 |
62 | return 'No new fragments imported.';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Exporter.php:
--------------------------------------------------------------------------------
1 | generateExcel();
17 | }
18 |
19 | public function generateExcel()
20 | {
21 | Excel::create('fragments '.date('Y-m-d H:i:s'), function ($excel) {
22 | $this->addSheet($excel, 'fragments', $this->getVisibleFragments());
23 | $this->addSheet($excel, 'hidden', $this->getHiddenFragments());
24 | })->download('xlsx');
25 | }
26 |
27 | protected function addSheet(LaravelExcelWriter $excel, string $name, Collection $fragments)
28 | {
29 | $excel->sheet($name, function ($sheet) use ($fragments) {
30 | $sheet->freezeFirstRow();
31 |
32 | $sheet->cells('A1:Z1', function ($cells) {
33 | $cells->setFontWeight('bold');
34 | $cells->setBorder('node', 'none', 'solid', 'none');
35 | });
36 |
37 | $rowCounter = 1;
38 |
39 | $sheet->row($rowCounter++, $this->getHeaderColumns());
40 |
41 | foreach ($fragments as $fragment) {
42 | $fragmentProperties = [
43 | $fragment['group'],
44 | $fragment['key'],
45 | $fragment['contains_html'] ? 0 : 1,
46 | $fragment['description'],
47 | ];
48 |
49 | $translatedFragmentProperties = locales()
50 | ->map(function (string $locale) use ($fragment) {
51 | return $fragment->getTranslation($locale);
52 | })
53 | ->toArray();
54 |
55 | $sheet->row($rowCounter++, array_merge($fragmentProperties, $translatedFragmentProperties));
56 | }
57 | });
58 | }
59 |
60 | protected function getHeaderColumns(): array
61 | {
62 | return collect(['group', 'key', 'contains_html', 'description'])->merge(
63 | locales()->map(function (string $locale) {
64 | return "text_{$locale}";
65 | })
66 | )->toArray();
67 | }
68 |
69 | public function getVisibleFragments(): Collection
70 | {
71 | return $this->getFragments($hidden = false);
72 | }
73 |
74 | public function getHiddenFragments(): Collection
75 | {
76 | return $this->getFragments($hidden = true);
77 | }
78 |
79 | public function getFragments(bool $hidden): Collection
80 | {
81 | return Fragment::where('hidden', $hidden)
82 | ->orderBy('group')
83 | ->orderBy('key')
84 | ->get();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Importer.php:
--------------------------------------------------------------------------------
1 | newFragments = new Collection();
23 | }
24 |
25 | public function updateExistingFragments()
26 | {
27 | $this->updateExistingFragments = true;
28 | }
29 |
30 | public function import(string $path)
31 | {
32 | $this->guardAgainstInvalidPath($path);
33 |
34 | $this->loadFragments($path)->each(function (array $data) {
35 | $fragment = Fragment::firstOrNew(['group' => $data['group'], 'key' => $data['key']]);
36 |
37 | if (!$this->shouldImport($fragment)) {
38 | return;
39 | }
40 |
41 | if (! $fragment->exists) {
42 | $this->newFragments->push($fragment);
43 | }
44 |
45 | $fragment->group = $data['group'];
46 | $fragment->key = $data['key'];
47 | $fragment->hidden = $data['hidden'];
48 | $fragment->contains_html = $data['contains_html'] ?? false;
49 | $fragment->description = $data['description'] ?? '';
50 | $fragment->draft = false;
51 |
52 | $this->locales()->each(function (string $locale) use ($fragment, $data) {
53 | $fragment->setTranslation($locale, $data["text_{$locale}"] ?? '');
54 | });
55 |
56 | $fragment->save();
57 | });
58 | }
59 |
60 | public function getNewFragments(): Collection
61 | {
62 | return $this->newFragments;
63 | }
64 |
65 | protected function guardAgainstInvalidPath(string $path)
66 | {
67 | if (!file_exists($path)) {
68 | throw FragmentFileNotFound::inPath($path);
69 | }
70 | }
71 |
72 | protected function loadFragments(string $path): Collection
73 | {
74 | return Excel::load($path)->all()->flatMap(function (RowCollection $sheet) {
75 | return $sheet->reject(function (CellCollection $row) {
76 | return empty(trim($row->group));
77 | })->map(function (CellCollection $row) use ($sheet) {
78 | return $row->put('hidden', $sheet->getTitle() === 'hidden')->toArray();
79 | });
80 | });
81 | }
82 |
83 | protected function shouldImport(Fragment $fragment): bool
84 | {
85 | if (!$fragment->exists) {
86 | return true;
87 | }
88 |
89 | return $this->updateExistingFragments;
90 | }
91 |
92 | protected function locales(): Collection
93 | {
94 | return collect(config('app.locales'))
95 | ->merge(config('app.backLocales'))
96 | ->unique();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [
](https://supportukrainenow.org)
3 |
4 | # Import fragments from an excel file
5 |
6 | [](LICENSE.md)
7 | [](https://insight.sensiolabs.com/projects/9012cf42-8d1a-4649-b5ab-b96db48eed21)
8 | [](https://scrutinizer-ci.com/g/spatie-custom/fragment-importer)
9 | [](https://styleci.io/repos/50928093)
10 |
11 | This Blender specific package provides some classes and commands to easily import fragments
12 | using an excel file. An exporter is included too.
13 |
14 | Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).
15 |
16 | ## Support us
17 |
18 | [
](https://spatie.be/github-ad-click/fragment-importer)
19 |
20 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
21 |
22 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
23 |
24 | ## Install
25 |
26 | This package is custom built for [Spatie](https://spatie.be) projects and is therefore not registered on packagist.
27 | In order to install it via composer you must specify this extra repository in `composer.json`:
28 |
29 | ```json
30 | "repositories": [ { "type": "composer", "url": "https://satis.spatie.be/" } ]
31 | ```
32 |
33 | You can install the package via composer:
34 | ``` bash
35 | $ composer require spatie/fragment-importer
36 | ```
37 |
38 | ## Usage
39 |
40 | Fragments not yet present in the database can be imported using:
41 | ``` console
42 | php artisan fragment:import
43 | ```
44 |
45 | If you want to update the existing ones as well, run this command:
46 | ``` console
47 | php artisan fragment:import --update
48 | ```
49 |
50 | ## Changelog
51 |
52 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
53 |
54 | ## Contributing
55 |
56 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
57 |
58 | ## Security
59 |
60 | If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.
61 |
62 | ## Credits
63 |
64 | - [Freek Van der Herten](https://github.com/freekmurze)
65 | - [All Contributors](../../contributors)
66 |
67 | ## About Spatie
68 | Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).
69 |
70 | ## License
71 |
72 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
73 |
--------------------------------------------------------------------------------