├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── examples
├── import_step1.jpg
└── import_step2.jpg
├── phpunit.xml
├── public
├── css
│ ├── bootstrap-theme.css
│ ├── bootstrap-theme.min.css
│ ├── bootstrap.css
│ ├── bootstrap.min.css
│ └── default.css
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ └── glyphicons-halflings-regular.woff
└── js
│ ├── bootstrap.js
│ ├── bootstrap.min.js
│ ├── jquery-1.10.2.min.js
│ └── jquery-1.10.2.min.map
├── src
├── Jacopo
│ └── LaravelImportExport
│ │ ├── LaravelImportExportServiceProvider.php
│ │ ├── Models
│ │ ├── DatabaseSchemaManager.php
│ │ ├── Exceptions
│ │ │ ├── ClassNotFoundException.php
│ │ │ ├── FileNotFoundException.php
│ │ │ ├── HeadersNotSetException.php
│ │ │ ├── NoDataException.php
│ │ │ └── UnalignedArrayException.php
│ │ ├── InputWrapper.php
│ │ ├── ParseCsv
│ │ │ ├── CsvFile.php
│ │ │ ├── CsvFileBuilder.php
│ │ │ ├── CsvFileHandler.php
│ │ │ ├── CsvLine.php
│ │ │ ├── DbFileBuilder.php
│ │ │ ├── File.php
│ │ │ └── ParseCsv.php
│ │ ├── RuntimeModel.php
│ │ ├── StateHandling
│ │ │ ├── Export
│ │ │ │ ├── ExportCompleteState.php
│ │ │ │ ├── GeneralState.php
│ │ │ │ ├── GetTableConfig.php
│ │ │ │ ├── GetTableName.php
│ │ │ │ └── StateHandler.php
│ │ │ ├── GeneralState.php
│ │ │ ├── Import
│ │ │ │ ├── GeneralState.php
│ │ │ │ ├── GetCsvState.php
│ │ │ │ ├── GetTableState.php
│ │ │ │ ├── ImportCompleteState.php
│ │ │ │ └── StateHandler.php
│ │ │ ├── StateArray.php
│ │ │ ├── StateHandler.php
│ │ │ └── StateInterface.php
│ │ ├── TemporaryModel.php
│ │ └── ValidatorFormInputModel.php
│ │ ├── routes.php
│ │ └── start.php
├── config
│ ├── baseconf.php
│ └── database.php
├── controllers
│ ├── BaseController.php
│ ├── ExportController.php
│ ├── HomeController.php
│ └── ImportController.php
├── migrations
│ └── 2013_09_25_222039__laravel_import_export_temporary_table.php
└── views
│ ├── home
│ └── index.blade.php
│ └── layouts
│ └── default.blade.php
└── tests
├── .gitkeep
└── unit
├── TestCsvFile.php
├── TestCsvFileBuilder.php
├── TestCsvFileHandler.php
├── TestCsvLine.php
├── TestDbFileBuilder.php
├── TestFile.php
├── TestGeneralState.php
├── TestGetCsvState.php
├── TestGetTableConfig.php
├── TestGetTableName.php
├── TestGetTableState.php
├── TestParseCsv.php
├── TestRuntimeModel.php
├── TestStateHandler.php
├── TestTemporaryModel.php
└── TestValidatorFormInputModel.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | composer.lock
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.3
5 | - 5.4
6 | - 5.5
7 |
8 | before_script:
9 | - curl -s http://getcomposer.org/installer | php
10 | - php composer.phar install --dev
11 |
12 | script: phpunit
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, jacopo
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | Redistributions in binary form must reproduce the above copyright notice, this
11 | list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | Neither the name of the {organization} nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Laravel-Import-Export
2 |
3 | Import-Export is a package to import and export data from various format into a database.
4 |
5 | - **Author**: Jacopo Beschi
6 | - **Version**: 0.1.0
7 |
8 | [](https://travis-ci.org/intrip/laravel-import-export)
9 |
10 |
11 |
12 | ## This package is no longer supported: either any bugfix or any new feature will be added. Install at your own risk!
13 |
14 | ##Features
15 |
16 | - Import and export data from Csv file into database
17 | - Multi DBMS: works with all DBMS supported by Laravel ORM
18 | - Create database schema: allow you to create database schema when importing data
19 |
20 | ##Under the box: features incoming in 0.2.0
21 |
22 | - Import and export an arbitrary number of lines
23 | - Import and export JSON and XML
24 | - Database access configurabile with a GUI
25 |
26 | ## Requirements
27 |
28 | - PHP >= 5.3.7
29 | - Composer
30 | - Laravel framework 4+
31 | - DBMS that support transactions and supported by Laravel ORM
32 |
33 | ##Installation with Composer
34 |
35 | To install Import-Export with Composer, add this line to your composer.json file in the `require field:
36 |
37 | ```json
38 | "jacopo/laravel-import-export": "dev-master"
39 | ```
40 | Also remember to set the minimum-stability to "dev" in your composer.json file
41 |
42 | Then open `app/config/app.php` and add the following line in the `providers` array:
43 |
44 | ```php
45 | 'providers' => array(
46 | 'Jacopo\LaravelImportExport\LaravelImportExportServiceProvider',
47 | )
48 | ```
49 |
50 | After you need to execute the following commands:
51 |
52 | ```php
53 | php artisan config:publish jacopo/laravel-import-export
54 | php artisan asset:publish jacopo/laravel-import-export
55 | ```
56 | Now you have under `app/config/packages/jacopo/laravel-import-export` the package configuration files. At this point you need to configure the database access. Open the file `app/config/packages/jacopo/laravel-import-export/database.php` and update it with the database access information. When done run the following command to initialize ImportExport database.
57 |
58 | ```php
59 | php artisan migrate --package="jacopo/laravel-import-export" --database="import"
60 | ```
61 | This command will create a `_import_export_temporary_table` in the db, you can change the name of the table editing the the key: `table_prefix` under the file `app/config/packages/jacopo/laravel-import-export/baseconf.php`.
62 |
63 | Congratulations! Now you can view the application at the url: `http://url-of-your-baseapp/importer`. If needed you can change the base route editing the the key: `base_application_route` under the file `app/config/packages/jacopo/laravel-import-export/baseconf.php`.
64 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jacopo/laravel-import-export",
3 | "description": "A package to import and export data in csv for Laravel",
4 | "version" : "0.1.0",
5 | "keywords": ["import","export","csv","database","laravel"],
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Jacopo Beschi",
10 | "email": "beschi.jacopo@gmail.com"
11 | }
12 | ],
13 | "require": {
14 | "php": ">=5.3.0",
15 | "illuminate/support": "~4",
16 | "jacopo/bootstrap-3-table-generator": "dev-master"
17 | },
18 | "require-dev": {
19 | "laravel/framework": "~4",
20 | "mockery/mockery": "dev-master"
21 | },
22 | "autoload": {
23 | "classmap": [
24 | "src/controllers"
25 | ],
26 | "psr-0": {
27 | "Jacopo\\LaravelImportExport": "src/"
28 | }
29 | },
30 | "minimum-stability": "stable"
31 | }
32 |
--------------------------------------------------------------------------------
/examples/import_step1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/examples/import_step1.jpg
--------------------------------------------------------------------------------
/examples/import_step2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/examples/import_step2.jpg
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | ./tests/unit
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/public/css/bootstrap-theme.css:
--------------------------------------------------------------------------------
1 | .btn-default,
2 | .btn-primary,
3 | .btn-success,
4 | .btn-info,
5 | .btn-warning,
6 | .btn-danger {
7 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
8 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
9 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
10 | }
11 |
12 | .btn-default:active,
13 | .btn-primary:active,
14 | .btn-success:active,
15 | .btn-info:active,
16 | .btn-warning:active,
17 | .btn-danger:active,
18 | .btn-default.active,
19 | .btn-primary.active,
20 | .btn-success.active,
21 | .btn-info.active,
22 | .btn-warning.active,
23 | .btn-danger.active {
24 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
25 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
26 | }
27 |
28 | .btn:active,
29 | .btn.active {
30 | background-image: none;
31 | }
32 |
33 | .btn-default {
34 | text-shadow: 0 1px 0 #fff;
35 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#e6e6e6));
36 | background-image: -webkit-linear-gradient(top, #ffffff, 0%, #e6e6e6, 100%);
37 | background-image: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%);
38 | background-image: linear-gradient(to bottom, #ffffff 0%, #e6e6e6 100%);
39 | background-repeat: repeat-x;
40 | border-color: #e0e0e0;
41 | border-color: #ccc;
42 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
43 | }
44 |
45 | .btn-default:active,
46 | .btn-default.active {
47 | background-color: #e6e6e6;
48 | border-color: #e0e0e0;
49 | }
50 |
51 | .btn-primary {
52 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9));
53 | background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%);
54 | background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%);
55 | background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
56 | background-repeat: repeat-x;
57 | border-color: #2d6ca2;
58 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
59 | }
60 |
61 | .btn-primary:active,
62 | .btn-primary.active {
63 | background-color: #3071a9;
64 | border-color: #2d6ca2;
65 | }
66 |
67 | .btn-success {
68 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44));
69 | background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%);
70 | background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%);
71 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
72 | background-repeat: repeat-x;
73 | border-color: #419641;
74 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
75 | }
76 |
77 | .btn-success:active,
78 | .btn-success.active {
79 | background-color: #449d44;
80 | border-color: #419641;
81 | }
82 |
83 | .btn-warning {
84 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f));
85 | background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%);
86 | background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
87 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
88 | background-repeat: repeat-x;
89 | border-color: #eb9316;
90 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
91 | }
92 |
93 | .btn-warning:active,
94 | .btn-warning.active {
95 | background-color: #ec971f;
96 | border-color: #eb9316;
97 | }
98 |
99 | .btn-danger {
100 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c));
101 | background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%);
102 | background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%);
103 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
104 | background-repeat: repeat-x;
105 | border-color: #c12e2a;
106 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
107 | }
108 |
109 | .btn-danger:active,
110 | .btn-danger.active {
111 | background-color: #c9302c;
112 | border-color: #c12e2a;
113 | }
114 |
115 | .btn-info {
116 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5));
117 | background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%);
118 | background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
119 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
120 | background-repeat: repeat-x;
121 | border-color: #2aabd2;
122 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
123 | }
124 |
125 | .btn-info:active,
126 | .btn-info.active {
127 | background-color: #31b0d5;
128 | border-color: #2aabd2;
129 | }
130 |
131 | .thumbnail,
132 | .img-thumbnail {
133 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
134 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
135 | }
136 |
137 | .dropdown-menu > li > a:hover,
138 | .dropdown-menu > li > a:focus,
139 | .dropdown-menu > .active > a,
140 | .dropdown-menu > .active > a:hover,
141 | .dropdown-menu > .active > a:focus {
142 | background-color: #357ebd;
143 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd));
144 | background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%);
145 | background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%);
146 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
147 | background-repeat: repeat-x;
148 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
149 | }
150 |
151 | .navbar {
152 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#f8f8f8));
153 | background-image: -webkit-linear-gradient(top, #ffffff, 0%, #f8f8f8, 100%);
154 | background-image: -moz-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
155 | background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);
156 | background-repeat: repeat-x;
157 | border-radius: 4px;
158 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
159 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
160 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
161 | }
162 |
163 | .navbar .navbar-nav > .active > a {
164 | background-color: #f8f8f8;
165 | }
166 |
167 | .navbar-brand,
168 | .navbar-nav > li > a {
169 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
170 | }
171 |
172 | .navbar-inverse {
173 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#3c3c3c), to(#222222));
174 | background-image: -webkit-linear-gradient(top, #3c3c3c, 0%, #222222, 100%);
175 | background-image: -moz-linear-gradient(top, #3c3c3c 0%, #222222 100%);
176 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);
177 | background-repeat: repeat-x;
178 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
179 | }
180 |
181 | .navbar-inverse .navbar-nav > .active > a {
182 | background-color: #222222;
183 | }
184 |
185 | .navbar-inverse .navbar-brand,
186 | .navbar-inverse .navbar-nav > li > a {
187 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
188 | }
189 |
190 | .navbar-static-top,
191 | .navbar-fixed-top,
192 | .navbar-fixed-bottom {
193 | border-radius: 0;
194 | }
195 |
196 | .alert {
197 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
198 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
199 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
200 | }
201 |
202 | .alert-success {
203 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#c8e5bc));
204 | background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #c8e5bc, 100%);
205 | background-image: -moz-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
206 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
207 | background-repeat: repeat-x;
208 | border-color: #b2dba1;
209 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
210 | }
211 |
212 | .alert-info {
213 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#b9def0));
214 | background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #b9def0, 100%);
215 | background-image: -moz-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
216 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
217 | background-repeat: repeat-x;
218 | border-color: #9acfea;
219 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
220 | }
221 |
222 | .alert-warning {
223 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#f8efc0));
224 | background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #f8efc0, 100%);
225 | background-image: -moz-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
226 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
227 | background-repeat: repeat-x;
228 | border-color: #f5e79e;
229 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
230 | }
231 |
232 | .alert-danger {
233 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#e7c3c3));
234 | background-image: -webkit-linear-gradient(top, #f2dede, 0%, #e7c3c3, 100%);
235 | background-image: -moz-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
236 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
237 | background-repeat: repeat-x;
238 | border-color: #dca7a7;
239 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
240 | }
241 |
242 | .progress {
243 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ebebeb), to(#f5f5f5));
244 | background-image: -webkit-linear-gradient(top, #ebebeb, 0%, #f5f5f5, 100%);
245 | background-image: -moz-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
246 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
247 | background-repeat: repeat-x;
248 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
249 | }
250 |
251 | .progress-bar {
252 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9));
253 | background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%);
254 | background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%);
255 | background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
256 | background-repeat: repeat-x;
257 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
258 | }
259 |
260 | .progress-bar-success {
261 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44));
262 | background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%);
263 | background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%);
264 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
265 | background-repeat: repeat-x;
266 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
267 | }
268 |
269 | .progress-bar-info {
270 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5));
271 | background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%);
272 | background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
273 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
274 | background-repeat: repeat-x;
275 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
276 | }
277 |
278 | .progress-bar-warning {
279 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f));
280 | background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%);
281 | background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
282 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
283 | background-repeat: repeat-x;
284 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
285 | }
286 |
287 | .progress-bar-danger {
288 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c));
289 | background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%);
290 | background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%);
291 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
292 | background-repeat: repeat-x;
293 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
294 | }
295 |
296 | .list-group {
297 | border-radius: 4px;
298 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
299 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
300 | }
301 |
302 | .list-group-item.active,
303 | .list-group-item.active:hover,
304 | .list-group-item.active:focus {
305 | text-shadow: 0 -1px 0 #3071a9;
306 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3278b3));
307 | background-image: -webkit-linear-gradient(top, #428bca, 0%, #3278b3, 100%);
308 | background-image: -moz-linear-gradient(top, #428bca 0%, #3278b3 100%);
309 | background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
310 | background-repeat: repeat-x;
311 | border-color: #3278b3;
312 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
313 | }
314 |
315 | .panel {
316 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
317 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
318 | }
319 |
320 | .panel-default > .panel-heading {
321 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f5f5f5), to(#e8e8e8));
322 | background-image: -webkit-linear-gradient(top, #f5f5f5, 0%, #e8e8e8, 100%);
323 | background-image: -moz-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
324 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
325 | background-repeat: repeat-x;
326 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
327 | }
328 |
329 | .panel-primary > .panel-heading {
330 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd));
331 | background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%);
332 | background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%);
333 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
334 | background-repeat: repeat-x;
335 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
336 | }
337 |
338 | .panel-success > .panel-heading {
339 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#d0e9c6));
340 | background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #d0e9c6, 100%);
341 | background-image: -moz-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
342 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
343 | background-repeat: repeat-x;
344 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
345 | }
346 |
347 | .panel-info > .panel-heading {
348 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#c4e3f3));
349 | background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #c4e3f3, 100%);
350 | background-image: -moz-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
351 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
352 | background-repeat: repeat-x;
353 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
354 | }
355 |
356 | .panel-warning > .panel-heading {
357 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#faf2cc));
358 | background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #faf2cc, 100%);
359 | background-image: -moz-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
360 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
361 | background-repeat: repeat-x;
362 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
363 | }
364 |
365 | .panel-danger > .panel-heading {
366 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#ebcccc));
367 | background-image: -webkit-linear-gradient(top, #f2dede, 0%, #ebcccc, 100%);
368 | background-image: -moz-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
369 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
370 | background-repeat: repeat-x;
371 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
372 | }
373 |
374 | .well {
375 | background-image: -webkit-gradient(linear, left 0%, left 100%, from(#e8e8e8), to(#f5f5f5));
376 | background-image: -webkit-linear-gradient(top, #e8e8e8, 0%, #f5f5f5, 100%);
377 | background-image: -moz-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
378 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
379 | background-repeat: repeat-x;
380 | border-color: #dcdcdc;
381 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
382 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
383 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
384 | }
--------------------------------------------------------------------------------
/public/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,0%,#e6e6e6,100%);background-image:-moz-linear-gradient(top,#fff 0,#e6e6e6 100%);background-image:linear-gradient(to bottom,#fff 0,#e6e6e6 100%);background-repeat:repeat-x;border-color:#e0e0e0;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0)}.btn-default:active,.btn-default.active{background-color:#e6e6e6;border-color:#e0e0e0}.btn-primary{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;border-color:#2d6ca2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.btn-primary:active,.btn-primary.active{background-color:#3071a9;border-color:#2d6ca2}.btn-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;border-color:#419641;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.btn-success:active,.btn-success.active{background-color:#449d44;border-color:#419641}.btn-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;border-color:#eb9316;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.btn-warning:active,.btn-warning.active{background-color:#ec971f;border-color:#eb9316}.btn-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;border-color:#c12e2a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.btn-danger:active,.btn-danger.active{background-color:#c9302c;border-color:#c12e2a}.btn-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;border-color:#2aabd2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.btn-info:active,.btn-info.active{background-color:#31b0d5;border-color:#2aabd2}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#f8f8f8));background-image:-webkit-linear-gradient(top,#fff,0%,#f8f8f8,100%);background-image:-moz-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar .navbar-nav>.active>a{background-color:#f8f8f8}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-gradient(linear,left 0,left 100%,from(#3c3c3c),to(#222));background-image:-webkit-linear-gradient(top,#3c3c3c,0%,#222,100%);background-image:-moz-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0)}.navbar-inverse .navbar-nav>.active>a{background-color:#222}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#c8e5bc));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#c8e5bc,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#b9def0));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#b9def0,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#f8efc0));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#f8efc0,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#e7c3c3));background-image:-webkit-linear-gradient(top,#f2dede,0%,#e7c3c3,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-gradient(linear,left 0,left 100%,from(#ebebeb),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#ebebeb,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3278b3));background-image:-webkit-linear-gradient(top,#428bca,0%,#3278b3,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f5f5f5),to(#e8e8e8));background-image:-webkit-linear-gradient(top,#f5f5f5,0%,#e8e8e8,100%);background-image:-moz-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#d0e9c6));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#d0e9c6,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#c4e3f3));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#c4e3f3,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#faf2cc));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#faf2cc,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#ebcccc));background-image:-webkit-linear-gradient(top,#f2dede,0%,#ebcccc,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-gradient(linear,left 0,left 100%,from(#e8e8e8),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#e8e8e8,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)}
--------------------------------------------------------------------------------
/public/css/default.css:
--------------------------------------------------------------------------------
1 | body
2 | {
3 | padding-top: 70px;
4 | }
5 |
6 | .fill-screen
7 | {
8 | max-width: 100%;
9 | }
10 |
11 | /******* Bootstrap Icons **********/
12 | .icon-large{font-size:60px}
13 | .icon-medium{font-size:30px}
14 | .icon-small{font-size:20px}
15 |
16 | /********** Layouts ***********/
17 | .bottom-10{margin-bottom:10px}
18 | .top-10{margin-top:10px}
19 |
20 | /*********** Custom Bootstrap colors ***********/
21 | .jumbotron
22 | {
23 | /*background-color: #5a5a5a;*/
24 | }
25 |
26 | /*********** Table ***********/
27 | table
28 | {
29 | table-layout: fixed;
30 | word-wrap: break-word;
31 | font-size: 0.9em;
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * bootstrap.js v3.0.0 by @fat and @mdo
3 | * Copyright 2013 Twitter Inc.
4 | * http://www.apache.org/licenses/LICENSE-2.0
5 | */
6 | if(!jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]}}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(window.jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){"loadingText"==a?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]');if(a.length){var b=this.$element.find("input").prop("checked",!this.$element.hasClass("active")).trigger("change");"radio"===b.prop("type")&&a.find(".active").removeClass("active")}this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(!e.hasClass("active")){if(this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(j),j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)}).emulateTransitionEnd(600)}else{if(this.$element.trigger(j),j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this}};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?(this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350),void 0):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(window.jQuery),+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('
').insertAfter(a(this)).on("click",b),f.trigger(d=a.Event("show.bs.dropdown")),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown"),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",f);if(h.length){var i=h.index(h.filter(":focus"));38==b.keyCode&&i>0&&i--,40==b.keyCode&&i').appendTo(document.body),this.$element.on("click.dismiss.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(window.jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focus",i="hover"==g?"mouseleave":"blur";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show),void 0):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide),void 0):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this.tip();this.setContent(),this.options.animation&&c.addClass("fade");var d="function"==typeof this.options.placement?this.options.placement.call(this,c[0],this.$element[0]):this.options.placement,e=/\s?auto?\s?/i,f=e.test(d);f&&(d=d.replace(e,"")||"top"),c.detach().css({top:0,left:0,display:"block"}).addClass(d),this.options.container?c.appendTo(this.options.container):c.insertAfter(this.$element);var g=this.getPosition(),h=c[0].offsetWidth,i=c[0].offsetHeight;if(f){var j=this.$element.parent(),k=d,l=document.documentElement.scrollTop||document.body.scrollTop,m="body"==this.options.container?window.innerWidth:j.outerWidth(),n="body"==this.options.container?window.innerHeight:j.outerHeight(),o="body"==this.options.container?0:j.offset().left;d="bottom"==d&&g.top+g.height+i-l>n?"top":"top"==d&&g.top-l-i<0?"bottom":"right"==d&&g.right+h>m?"left":"left"==d&&g.left-h'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(window.jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top()),"function"==typeof h&&(h=f.bottom());var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;this.affixed!==i&&(this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin="bottom"==i?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),"bottom"==i&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()}))}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(window.jQuery);
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/LaravelImportExportServiceProvider.php:
--------------------------------------------------------------------------------
1 | package('jacopo/laravel-import-export');
27 |
28 | $this->registerImportState();
29 | $this->registerExportState();
30 | }
31 |
32 | /**
33 | * Get the services provided by the provider.
34 | *
35 | * @return array
36 | */
37 | public function provides()
38 | {
39 | return array();
40 | }
41 |
42 | public function boot()
43 | {
44 | // include start.php
45 | include_once __DIR__ . '/start.php';
46 |
47 | // Use custom package database configuration
48 | $this->app['config']['database.connections'] = array_merge(
49 | $this->app['config']['database.connections'],
50 | \Config::get('laravel-import-export::database.connections')
51 | );
52 | }
53 |
54 | protected function registerImportState(ImportHandler $handler = null)
55 | {
56 | $this->app['import_csv_handler'] = $this->app->share(function($app)
57 | {
58 | $handler = new ImportHandler();
59 | $handler->initializeState();
60 |
61 | return $handler;
62 | });
63 | }
64 |
65 | protected function registerExportState(ExportHandler $handler = null)
66 | {
67 | $this->app['export_csv_handler'] = $this->app->share(function($app)
68 | {
69 | $handler = new ExportHandler();
70 | $handler->initializeState();
71 |
72 | return $handler;
73 | });
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/DatabaseSchemaManager.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\DB;
9 | use Illuminate\Support\Facades\Config;
10 | use Illuminate\Support\Facades\Schema;
11 |
12 | class DatabaseSchemaManager
13 | {
14 | protected $manager;
15 | /**
16 | * Name of the connection to use
17 | * @var String
18 | */
19 | protected $connection;
20 |
21 | public function __construct()
22 | {
23 | $this->connection = Config::get('laravel-import-export::baseconf.connection_name');
24 | $this->manager = DB::connection($this->connection)->getDoctrineSchemaManager();
25 | }
26 |
27 | public function getTableList()
28 | {
29 | $tables = $this->manager->listTableNames();
30 |
31 | return $tables;
32 | }
33 |
34 | public function getTableColumns($table_name)
35 | {
36 | $columns = $this->manager->listTableColumns($table_name);
37 |
38 | return $columns;
39 | }
40 |
41 | /**
42 | * Create a table schme with the given columns
43 | *
44 | * @param $name table name
45 | * @param Array $columns "type" => "name"
46 | * @param $safe_create if is enabled doesnt create a table if already exists
47 | *
48 | */
49 | public function createTable($name, Array $columns, $safe_create = false)
50 | {
51 | if( (! $safe_create) || ($safe_create && ! Schema::connection($this->connection)->hasTable('users')) )
52 | {
53 | // dtop table if exists
54 | if (Schema::connection($this->connection)->hasTable($name))
55 | {
56 | Schema::connection($this->connection)->drop($name);
57 | }
58 |
59 | Schema::connection($this->connection)->create($name, function($table) use ($columns)
60 | {
61 | foreach($columns as $name => $type)
62 | {
63 | $table->$type($name);
64 | }
65 | });
66 | }
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/Exceptions/ClassNotFoundException.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Input;
9 |
10 | class InputWrapper
11 | {
12 |
13 | public function get($params, $default_value = null)
14 | {
15 | return Input::get($params,$default_value);
16 | }
17 |
18 | public function post($params, $default_value = null)
19 | {
20 | return Input::post($params,$default_value);
21 | }
22 |
23 | public function all()
24 | {
25 | return Input::all();
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/CsvFile.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 |
9 | class CsvFile extends \ArrayIterator
10 | {
11 | protected $csv_headers = array();
12 |
13 | public function getCsvHeader()
14 | {
15 | return $this->csv_headers;
16 | }
17 |
18 | public function setCsvHeader($value)
19 | {
20 | $this->csv_headers = $value;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/CsvFileBuilder.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | class CsvFileBuilder
8 | {
9 |
10 | protected $config_file_parse;
11 | protected $config_model;
12 | protected $csv_file;
13 | protected $csv_parser;
14 | /**
15 | * 'first_line_headers' if first line of the file contains data headers
16 | * @var Array
17 | */
18 | protected $config;
19 |
20 | /**
21 | *
22 | * @param $config_model configuration for the RuntimeModel
23 | * @param $config_file_parse configuration for the csv file parser
24 | * @param $config configuration for the builder
25 | * @param $csv_file instance of CsvFile
26 | * @param $csv_parser istance of ParseCsv
27 | */
28 | public function __construct(array $config_model = array(), array $config_file_parse = array(), $config = array(), CsvFile $csv_file = null, ParseCsv $csv_parser = null)
29 | {
30 | $this->config_model = $config_model;
31 | $this->config_file_parse = $config_file_parse;
32 | $this->config = $config;
33 | $this->csv_file = $csv_file ? $csv_file : new CsvFile;
34 | $this->csv_parser = $csv_parser ? $csv_parser : new ParseCsv;
35 | }
36 |
37 | public function setConfigModel($config)
38 | {
39 | $this->config_model = $config;
40 | }
41 | public function setConfigFileParse($config)
42 | {
43 | $this->config_file_parse = $config;
44 | }
45 | public function setConfig($config)
46 | {
47 | $this->config = $config;
48 | }
49 | /**
50 | * This method build the CsvFile from a csv file
51 | *
52 | * @throws FileNotFoundException
53 | * @throws InvalidArgumentException
54 | * @throws UnalignedArrayException
55 | * @throws DomainException
56 | */
57 | public function buildFromCsv(CsvLine $csv_line_base = null)
58 | {
59 | $this->csv_line_base = $csv_line_base ? $csv_line_base : new CsvLine;
60 | $this->csv_parser->setConfig($this->config_file_parse);
61 | $this->csv_line_base->setConfig($this->config_model);
62 |
63 | $this->updateCsvHeader();
64 |
65 | // Csv loop
66 | while ( ($csv_line_array = $this->csv_parser->parseCsvFile()) != false )
67 | {
68 | if( count($csv_line_array) && (! ( (count($csv_line_array) == 1) && is_null($csv_line_array[0]) ) ) )
69 | {
70 | // create csv_line
71 | $csv_line = clone $this->csv_line_base;
72 | $csv_line->forceSetAttributes($csv_line_array);
73 | $this->appendLine($csv_line);
74 | }
75 | }
76 | }
77 |
78 | public function getCsvFile()
79 | {
80 | return $this->csv_file;
81 | }
82 |
83 | protected function appendLine(CsvLine $line)
84 | {
85 | $this->csv_file->append($line);
86 | }
87 |
88 | /**
89 | * Update the csv header with first row of the file
90 | * if "first_line_headers" is enabled
91 | */
92 | protected function updateCsvHeader()
93 | {
94 | if( $this->config['first_line_headers'] )
95 | {
96 | $csv_line_array = $this->csv_parser->parseCsvFile();
97 | $this->csv_file->setCsvHeader($csv_line_array);
98 | }
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/CsvFileHandler.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileBuilder;
9 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFile;
10 | use Jacopo\LaravelImportExport\Models\ParseCsv\DbFileBuilder;
11 | use Jacopo\LaravelImportExport\Models\FileHandlerInterface;
12 | use Jacopo\LaravelImportExport\Models\Exceptions\HeadersNotSetException;
13 | use Jacopo\LaravelImportExport\Models\Exceptions\UnalignedArrayException;
14 | use Jacopo\LaravelImportExport\Models\TemporaryModel;
15 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
16 | use Illuminate\Support\Facades\DB;
17 | use Illuminate\Support\Facades\Config;
18 | use Illuminate\Filesystem\FileSystem;
19 | use Jacopo\LaravelImportExport\Models\DatabaseSchemaManager as DBM;
20 |
21 | class CsvFileHandler
22 | {
23 | protected $csv_file;
24 |
25 | /**
26 | * Get data from the temporary table
27 | *
28 | * @return Mixed $data
29 | * @throws Exception
30 | */
31 | public function getTemporary()
32 | {
33 | // disable query logging
34 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
35 | DB::connection($connection_name)->disableQueryLog();
36 | $temporary = TemporaryModel::whereRaw("1")->orderBy("id","DESC")->first();
37 | if($temporary)
38 | {
39 | $this->csv_file = $temporary->file_object;
40 | return $this->csv_file;
41 | }
42 | return false;
43 | }
44 |
45 | /**
46 | * Put data in the temporary table
47 | *
48 | * @return Boolean $success
49 | * @throws Exception
50 | */
51 | public function saveTemporary($csv_file = null, $temporary_model = null)
52 | {
53 | $csv_file = $csv_file ? $csv_file : $this->csv_file;
54 | if( $csv_file )
55 | {
56 | $temporary_model = ($temporary_model) ? $temporary_model : new TemporaryModel();
57 | $temporary_model->fill(array("file_object"=>$csv_file));
58 | // disable query logging
59 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
60 | DB::connection($connection_name)->disableQueryLog();
61 | return $temporary_model->save();
62 | }
63 | else
64 | {
65 | return false;
66 | }
67 | }
68 |
69 | /**
70 | * Update headers of the csv_file
71 | *
72 | * @param CsvFile $csv_line
73 | * @param Array $columns $key=column name, $value=column index
74 | * @param Sring $table_name name of the table
75 | * @throws UnalignedArrayException
76 | */
77 | public function updateHeaders(CsvFile $csv_file, array $columns, $table_name)
78 | {
79 | $this->csv_file = $csv_file ? $csv_file : $this->csv_file;
80 |
81 | foreach($this->csv_file as $csv_line)
82 | {
83 | $this->updateHeader($csv_line, $columns, $table_name);
84 | }
85 | }
86 |
87 | /**
88 | * Update headers of the csv_line
89 | *
90 | * @param CsvLine $csv_line
91 | * @param Array $columns $key=column name, $value=column index
92 | * @param Sring $table_name name of the table
93 | * @return Boolean
94 | * @throws UnalignedArrayException
95 | */
96 | protected function updateHeader(CsvLine $csv_line, array $columns, $table_name)
97 | {
98 | $model_attributes = $csv_line->getAttributes();
99 | $new_attributes = array();
100 | foreach($columns as $key_column => $column)
101 | {
102 | if( isset($model_attributes[$key_column]) )
103 | {
104 | // append data to new attributes
105 | $new_attributes = array_merge($new_attributes,array($column => $model_attributes[$key_column]));
106 | unset($model_attributes[$key_column]);
107 | }
108 | else
109 | {
110 | throw new UnalignedArrayException;
111 | }
112 | }
113 |
114 | // update data
115 | $csv_line->resetAttributes();
116 | foreach($new_attributes as $key_attribute => $attribute)
117 | {
118 | $csv_line->forceSetAttribute($key_attribute,$attribute);
119 | }
120 |
121 | $table = array("table" => $table_name);
122 | $csv_line->setConfig( $table );
123 |
124 | return true;
125 | }
126 |
127 | /**
128 | * @throws HeadersNotSetException
129 | * @throws PDOException
130 | */
131 | public function saveToDb(Array $columns_type)
132 | {
133 | $csv_file = $this->csv_file;
134 |
135 | // create schema if not exists
136 | if( ! empty($columns_type))
137 | {
138 | $line = $csv_file[0];
139 | $dbm = new DBM();
140 | $dbm->createTable($line->getTableName(), $columns_type);
141 | }
142 |
143 | // disable query logging
144 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
145 | DB::connection($connection_name)->disableQueryLog();
146 | // start transaction
147 | DB::connection($connection_name)->transaction(function() use($csv_file)
148 | {
149 | foreach($csv_file as $csv_line)
150 | {
151 | if($csv_line->canSaveToDb())
152 | {
153 | $csv_line->save();
154 | }
155 | else
156 | {
157 | throw new HeadersNotSetException;
158 | }
159 | }
160 | });
161 |
162 | return true;
163 | }
164 |
165 | /**
166 | * This method build the CsvFile from a csv file
167 | *
168 | * @param $config
169 | * 'model' for RunTimeModel
170 | * 'file' for ParseCsv
171 | * 'builder' for CsvFileBuilder
172 | *
173 | * @throws FileNotFoundException
174 | * @throws InvalidArgumentException
175 | * @throws NoDataException
176 | * @throws UnalignedArrayException
177 | * @throws DomainException
178 | * @return CsvFile
179 | */
180 | public function openFromCsv(array $config, CsvFileBuilder $builder = null)
181 | {
182 | $builder = $builder ? $builder : new CsvFileBuilder();
183 | $builder->setConfigModel($config["model"]);
184 | $builder->setConfigFileParse($config["file_parse"]);
185 | $builder->setConfig($config["builder"]);
186 |
187 | $builder->buildFromCsv();
188 | $this->csv_file = $builder->getCsvFile();
189 | if( ! count($this->csv_file))
190 | throw new NoDataException();
191 |
192 | return $this->getCsvFile();
193 | }
194 |
195 | /**
196 | * Build the csvFile from Db
197 | *
198 | * @throws Exception
199 | * @throws PDOException
200 | * @return CsvFile
201 | */
202 | public function openFromDb(array $config, DbFileBuilder $builder = null)
203 | {
204 | $builder = $builder ? $builder : new DbFileBuilder();
205 | $builder->setConfig($config);
206 |
207 | $builder->build();
208 | $this->csv_file = $builder->getCsvFile();
209 |
210 | return $this->getCsvFile();
211 | }
212 |
213 | /**
214 | * Get the max lenght of a csv_line
215 | * @return Integer
216 | */
217 | public function getMaxLength($csv_file = null)
218 | {
219 | $csv_file = $csv_file ? $csv_file : $this->csv_file;
220 |
221 | $sizes = array(0);
222 | if( ! $csv_file )
223 | {
224 | throw new NoDataException();
225 | }
226 |
227 | foreach($csv_file as $line)
228 | {
229 | $sizes[]=count($line->getElements() );
230 | }
231 |
232 | return max($sizes);
233 | }
234 |
235 | /**
236 | * Create the csv string rappresenting the CsvFile
237 | *
238 | * @return String $csv
239 | * @throws NoDataException
240 | */
241 | public function getCsvString($separator, CsvFile $csv_file = null)
242 | {
243 | $csv_file = $csv_file ? $csv_file : $this->csv_file;
244 | $csv = '';
245 | if( ! isset($csv_file) )
246 | {
247 | throw new NoDataException;
248 | }
249 | else
250 | {
251 | foreach($csv_file as $key => $csv_line)
252 | {
253 | if($key == 0)
254 | {
255 | $csv.=$csv_line->getCsvHeader($separator);
256 | }
257 | $csv.=$csv_line->getCsvString($separator);
258 | }
259 | }
260 |
261 | return $csv;
262 | }
263 |
264 | public function getCsvFile()
265 | {
266 | return $this->csv_file;
267 | }
268 |
269 |
270 | public function saveCsvFile($path, $separator = ",")
271 | {
272 | $file = new FileSystem();
273 | return $file->put($path, $this->getCsvString($separator) );
274 | }
275 |
276 | }
277 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/CsvLine.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 |
9 | use Jacopo\LaravelImportExport\Models\RuntimeModel;
10 | use Illuminate\Support\Facades\Config;
11 |
12 | class CsvLine extends RuntimeModel
13 | {
14 | public function __construct()
15 | {
16 | $this->connection = Config::get('laravel-import-export::baseconf.connection_name');
17 | return parent::__construct( func_get_args() );
18 | }
19 |
20 | public function getElements()
21 | {
22 | return $this->toArray();
23 | }
24 |
25 | public function getCsvString($separator)
26 | {
27 | $attributes = $this->toArray();
28 | return $this->arrayToCsv($attributes, $separator);
29 | }
30 |
31 | public function getCsvHeader($separator)
32 | {
33 | $attributes_keys = array_keys( $this->toArray() );
34 | return $this->arrayToCsv($attributes_keys, $separator);
35 | }
36 |
37 | protected function arrayToCsv($attributes, $separator)
38 | {
39 | $str = '';
40 | $attribute_size = count($attributes);
41 | $current_item = 1;
42 | foreach($attributes as $key => $attribute)
43 | {
44 | $str.="{$attribute}";
45 | if( $current_item++ < $attribute_size)
46 | {
47 | $str.= $separator;
48 | }
49 | }
50 | $str.= "\n";
51 |
52 | return $str;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/DbFileBuilder.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\DB;
9 | use Illuminate\Support\Facades\Config;
10 |
11 | class DbFileBuilder
12 | {
13 | protected $csv_file;
14 | /**
15 | * Import configuration:
16 | * columns: key (db name) value (export name)
17 | * table: table name
18 | * @var Array
19 | */
20 | protected $config;
21 |
22 | public function __construct(array $config = null, $csv_file = null)
23 | {
24 | $this->config = $config;
25 | $this->csv_file = $csv_file ? $csv_file : new CsvFile;
26 | }
27 |
28 | /**
29 | * Build the CsvFile
30 | *
31 | * @throws Exception
32 | * @throws PDOException
33 | */
34 | public function build(CsvLine $csv_line_base = null)
35 | {
36 | $csv_line_base = $csv_line_base ? $csv_line_base : new CsvLine;
37 | $stdclass_lines = $this->getAttributesFromDb();
38 | foreach($stdclass_lines as $key => $line)
39 | {
40 | $csv_line = clone $csv_line_base;
41 | $csv_line->forceSetAttributes((Array)$line);
42 | $this->appendLine($csv_line);
43 | }
44 | }
45 |
46 | /**
47 | * Get the data from db
48 | *
49 | * @return Array
50 | */
51 | protected function getAttributesFromDb()
52 | {
53 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
54 | return DB::connection($connection_name)
55 | ->table($this->config["table"])
56 | ->select($this->createSelect() )
57 | ->get();
58 | }
59 |
60 | /**
61 | * Create select to make the CsvFile attributes
62 | * to export
63 | *
64 | * @return String
65 | */
66 | protected function createSelect($config = null)
67 | {
68 | $config = $config ? $config : $this->config;
69 | $select = array();
70 | if( ($columns = $config["columns"]) )
71 | {
72 | foreach($columns as $db_key => $export_key)
73 | {
74 | $select[]= "{$db_key} as {$export_key}";
75 | }
76 | }
77 | return $select;
78 | }
79 |
80 | protected function appendLine(CsvLine $line)
81 | {
82 | $this->csv_file->append($line);
83 | }
84 |
85 | public function setConfig($value)
86 | {
87 | $this->config = $value;
88 | }
89 |
90 | public function getCsvFile()
91 | {
92 | return $this->csv_file;
93 | }
94 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/File.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Jacopo\LaravelImportExport\Models\Exceptions\FileNotFoundException;
9 |
10 | class File
11 | {
12 |
13 | /**
14 | * @throws FileNotFoundException
15 | * @return Handle file handler
16 | */
17 | public function openFile($file_path)
18 | {
19 | if( $file_path && file_exists($file_path) )
20 | {
21 | return fopen($file_path, "r");
22 | }
23 | else
24 | {
25 | throw new FileNotFoundException;
26 | }
27 | }
28 |
29 | public function closeFile($file)
30 | {
31 | return fclose($file);
32 | }
33 |
34 | public function readCsv($file,$max_length,$separator)
35 | {
36 | return fgetcsv($file,$max_length,$separator);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ParseCsv/ParseCsv.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | Class ParseCsv
9 | {
10 | /**
11 | * Attributes:
12 | * file_path
13 | * separator
14 | */
15 | protected $config;
16 | protected $csvFile;
17 | protected $file;
18 | protected $file_wrapper;
19 |
20 | public function __construct(array $config=null, File $file_wrapper = null)
21 | {
22 | if($config)
23 | {
24 | $this->config=$config;
25 | }
26 |
27 | $this->file_wrapper = $file_wrapper ?: new File;
28 |
29 | }
30 |
31 |
32 | public function parseCsvFile()
33 | {
34 | if( ! isset($this->file) )
35 | {
36 | $this->openFile();
37 | }
38 |
39 | $separator = (isset($this->config["separator"])) ? $this->config["separator"] : ",";
40 | $csv_line_array = $this->file_wrapper->readCsv($this->file,0,$separator);
41 |
42 | if( (! $csv_line_array) && (! is_null($csv_line_array)) )
43 | {
44 | $this->closeFile();
45 | }
46 |
47 | return $csv_line_array;
48 | }
49 |
50 | private function closeFile()
51 | {
52 | if( isset($this->file))
53 | {
54 | $this->file_wrapper->closeFile($this->file);
55 | unset($this->file);
56 | }
57 | }
58 |
59 | /**
60 | * Open csv file
61 | * @return Handle file
62 | * @throws FileNotFoundException
63 | */
64 | private function openFile()
65 | {
66 | $file_path = isset( $this->config["file_path"] ) ? $this->config["file_path"] : null;
67 |
68 | $this->file = $this->file_wrapper->openFile($file_path);
69 | }
70 |
71 | public function setConfig(array $value)
72 | {
73 | $this->config=$value;
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/RuntimeModel.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Database\Eloquent\Model;
9 | use Illuminate\Support\Facades\Config;
10 |
11 | class RuntimeModel extends Model
12 | {
13 | // validation rules
14 | protected $rules;
15 |
16 | protected static $unguarded = true;
17 |
18 | public $timestamps = false;
19 |
20 | protected $connection;
21 |
22 | public function __construc()
23 | {
24 | $args = func_get_args();
25 | $this->connection = Config::get('laravel-import-export::baseconf.connection_name');
26 |
27 | return parent::__construct($args);
28 | }
29 |
30 | /**
31 | * set parameters of the object
32 | * @param array $config
33 | * @throws InvalidArgumentException
34 | */
35 | public function setConfig(array $configs)
36 | {
37 | foreach($configs as $config_key => $config_value)
38 | {
39 | if( property_exists(get_class($this), $config_key) )
40 | {
41 | $this->$config_key = $config_value;
42 | }
43 | else
44 | {
45 | throw new \InvalidArgumentException;
46 | }
47 | }
48 | }
49 |
50 | public function forceSetAttribute($key, $value)
51 | {
52 | $this->attributes[$key]=$value;
53 | }
54 |
55 | public function forceSetAttributes(array $attributes)
56 | {
57 | foreach($attributes as $key => $value)
58 | {
59 | $this->attributes[$key]=$value;
60 | }
61 | }
62 |
63 | public function resetAttributes()
64 | {
65 | $this->attributes = array();
66 | }
67 |
68 | public function canSavetoDb()
69 | {
70 | return ( isset($this->table) && static::isAssoc($this->attributes) );
71 | }
72 |
73 | public static function isAssoc($array) {
74 |
75 | return (bool)count(array_filter(array_keys($array), 'is_string'));
76 | }
77 |
78 | public function getTableName()
79 | {
80 | return $this->table;
81 | }
82 |
83 | }
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Export/ExportCompleteState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\URL;
9 | use Illuminate\Support\Facades\Session;
10 |
11 | class ExportCompleteState extends GeneralState {
12 |
13 | /**
14 | * Return the form that needs to be processed
15 | */
16 | protected function printFormNew(){
17 | $str = parent::printFormNew();
18 |
19 | $reset_url = $this->getResetUrl();
20 | $download_path = Session::get($this->exchange_key);
21 |
22 | $str.=<<
24 |
28 |
29 | STR;
30 |
31 |
32 | return $str;
33 | }
34 |
35 | public function printFormOld(){}
36 | public function processForm(){}
37 | public function fillFormInput(){}
38 | }
39 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Export/GeneralState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Jacopo\LaravelImportExport\Models\StateHandling\GeneralState as GeneralStateBase;
9 |
10 | abstract class GeneralState extends GeneralStateBase {
11 |
12 | protected $process_action = "Jacopo\LaravelImportExport\ExportController@postProcessForm";
13 | protected $reset_state = "Jacopo\LaravelImportExport\ExportController@getResetState";
14 | protected $exchange_key = 'export_state_exchange';
15 | protected $errors_key = 'errors_export';
16 | }
17 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Export/GetTableConfig.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Form;
9 | use Illuminate\Support\Facades\Session;
10 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
11 | use Jacopo\LaravelImportExport\Models\ValidatorFormInputModel;
12 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler;
13 | use Jacopo\LaravelImportExport\Models\InputWrapper as Input;
14 |
15 | class GetTableConfig extends GeneralState {
16 |
17 | protected $next_state_class = "Jacopo\LaravelImportExport\Models\StateHandling\Export\ExportCompleteState";
18 | protected $csv_path = "download.csv";
19 | protected $rules = array();
20 |
21 | /**
22 | * Return the form that needs to be processed
23 | */
24 | protected function printFormNew(){
25 | $prev_data = Session::get($this->exchange_key);
26 | $str = parent::printFormNew();
27 | $str.= "Step2: fill save settings
".
28 | $prev_data["preview"];
29 | // config form
30 | $str.="Fill the form below:
";
31 | $str.= Form::open(array( 'url' => $this->getProcessUrl(), "role" => "form", "class" => "form-horizontal") );
32 | $str.= "Write the name of each column to export (\"__empty\"=don't export)
";
33 | $columns = $prev_data["column_names"];
34 | foreach( $columns as $key => $column)
35 | {
36 | $str.= "";
42 | }
43 | $str.= "";
48 | $str.= Form::close();
49 |
50 | return $str;
51 | }
52 |
53 | /**
54 | * Return the form that has already been processed
55 | */
56 | protected function printFormOld(){
57 | $str = <<
59 |
60 | Export table: completed succesfully!
61 |
62 |
63 |
64 | STR;
65 | return $str;
66 | }
67 |
68 | /**
69 | * Process the form
70 | *
71 | * @return Boolean $is_executed if the state is executed successfully
72 | */
73 | public function processForm(array $input = null, $validator = null, CsvFileHandler $handler = null)
74 | {
75 | if($input)
76 | {
77 | $this->form_input = $input;
78 | }
79 | else
80 | {
81 | $this->fillFormInput();
82 | }
83 |
84 | $validator = ($validator) ? $validator : new ValidatorFormInputModel($this);
85 | $handler = $handler ? $handler : new CsvFileHandler();
86 |
87 | if ( $validator->validateInput() )
88 | {
89 | $builder_config = array(
90 | "columns" => $this->form_input["attributes"],
91 | "table" => $this->form_input["table_name"],
92 | );
93 | try
94 | {
95 | $handler->openFromDb($builder_config);
96 | }
97 | catch(\PDOException $e)
98 | {
99 | $this->appendError("DbException" , $e->getMessage() );
100 | return $this->getIsExecuted();
101 | }
102 | catch(\Exception $e)
103 | {
104 | $this->appendError("DbException" , $e->getMessage() );
105 | return $this->getIsExecuted();
106 | }
107 | try
108 | {
109 | $exchange_data = Session::get($this->exchange_key);
110 | $separator = $exchange_data["separator"];
111 | $success = $handler->saveCsvFile($this->csv_path,$separator);
112 | if($success)
113 | {
114 | Session::put($this->exchange_key,$this->csv_path);
115 | $this->is_executed = true;
116 | }
117 | else
118 | {
119 | $this->appendError("Permission" , "Cannot save temporary data: please set write permission on public folder");
120 | return $this->getIsExecuted();
121 | }
122 | }
123 | catch(NoDataException $e)
124 | {
125 | $this->appendError("NoData" , "No data to save");
126 | return $this->getIsExecuted();
127 | }
128 | }
129 | else
130 | {
131 | $this->appendError("fileEmpty" , "No data found in the file" );
132 | }
133 |
134 | return $this->getIsExecuted();
135 | }
136 |
137 | public function fillFormInput($input = null)
138 | {
139 | $input = $input ? $input : new Input();
140 |
141 | $prev_data = Session::get($this->exchange_key);
142 |
143 | $this->form_input["table_name"] = $prev_data["table_name"];
144 | $columns = $prev_data["column_names"];
145 | $this->form_input["attributes"] = array();
146 | foreach( $columns as $key => $column)
147 | {
148 | $this->form_input["attributes"][$column] = $input->get($column);
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Export/GetTableName.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Form;
9 | use Illuminate\Support\Facades\DB;
10 | use Illuminate\Support\Facades\Config;
11 | use Illuminate\Support\Facades\Session;
12 | use Jacopo\Bootstrap3Table\BootstrapTable as Table;
13 | use Jacopo\LaravelImportExport\Models\ValidatorFormInputModel;
14 | use Jacopo\LaravelImportExport\Models\DatabaseSchemaManager as DBM;
15 | use Jacopo\LaravelImportExport\Models\InputWrapper as Input;
16 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
17 |
18 | class GetTableName extends GeneralState {
19 |
20 | protected $next_state_class = "Jacopo\LaravelImportExport\Models\StateHandling\Export\GetTableConfig";
21 |
22 | protected $rules = array(
23 | "table_name" => "required",
24 | "max_rows" => "required|integer"
25 | );
26 |
27 | /**
28 | * Return the form that needs to be processed
29 | */
30 | protected function printFormNew(){
31 | $str = parent::printFormNew();
32 | $str .=
33 | "\n".
34 | "
\n".
35 | "
Step1: get table data
\n".
36 | "
\n".
37 | Form::open(array( 'url' => $this->getProcessUrl(), 'role' => 'form'))."\n".
38 | $this->createSelectTables().
39 | "
".
40 | Form::label('separator','Type of separator: ').
41 | Form::select('separator' , array( ','=>'comma ,' , ';'=>'semicolon ;' ) , ',', array("class" => "form-control") ).
42 | "
".
43 | "
\n".
44 | Form::label('max_rows','Max number of lines to show in preview: ')."\n".
45 | Form::select('max_rows' , array('10'=>'10', '50'=>'50', '100'=>'100', '150'=>'150') , '10', array("class"=> "form-control") )."\n".
46 | "
\n".
47 | Form::submit('Open' , array('class'=>'btn btn-success'))."\n".
48 | Form::close().
49 | "
\n". // form-group
50 | "
\n". // col
51 | "\n". // row
52 | "
\n";
53 |
54 | return $str;
55 | }
56 |
57 | /**
58 | * Return the form that has already been processed
59 | */
60 | protected function printFormOld(){
61 | $reset_url = $this->getResetUrl();
62 |
63 | $str=<<
65 |
68 |
69 |
70 |
71 |
72 | Open table: completed succesfully!
73 |
74 |
75 |
76 | STR;
77 | return $str;
78 | }
79 |
80 | /**
81 | * Process the form
82 | *
83 | * @return Boolean $is_executed if the state is executed successfully
84 | */
85 | public function processForm(array $input = null, $validator = null)
86 | {
87 | if($input)
88 | {
89 | $this->form_input = $input;
90 | }
91 | else
92 | {
93 | $this->fillFormInput();
94 | }
95 |
96 | $validator = ($validator) ? $validator : new ValidatorFormInputModel($this);
97 |
98 | if ( $validator->validateInput() )
99 | {
100 | try
101 | {
102 | $table_preview = $this->getDataTable();
103 | }
104 | catch(BadMethodCallException $e)
105 | {
106 | $this->appendError("BadMethod" , "Invalid input data: cannot show the table." );
107 | return $this->getIsExecuted();
108 | }
109 | catch(NoDataException $e)
110 | {
111 | $this->appendError("NoData" , "The table is empty." );
112 | return $this->getIsExecuted();
113 | }
114 | $exchange_data = array(
115 | "preview" => $table_preview,
116 | "table_name" => $this->form_input["table_name"],
117 | "form_input" => $this->form_input,
118 | "column_names" => $this->getTableHeader(),
119 | "separator" => $this->form_input["separator"]
120 | );
121 | $this->is_executed = true;
122 | // save data for next state
123 | Session::put($this->exchange_key, $exchange_data);
124 | }
125 | else
126 | {
127 | $this->appendError("fileEmpty" , "No data found in the file" );
128 | }
129 |
130 | return $this->getIsExecuted();
131 | }
132 |
133 | public function fillFormInput(Input $input = null)
134 | {
135 | $input = $input ? $input : new Input();
136 | $this->form_input['table_name'] = $input->get('table_name');
137 | $this->form_input['max_rows'] = $input->get('max_rows');
138 | $this->form_input['separator'] = $input->get('separator');
139 | }
140 |
141 | protected function createSelectTables()
142 | {
143 | $table_list = $this->getTableValuesSelect();
144 |
145 | if($table_list)
146 | {
147 | $select = "\n".
148 | Form::label('table_name','Table name to open:')."\n".
149 | Form::select('table_name' , $table_list , reset($table_list) , array("class"=> "form-control") )."\n".
150 | "
\n";
151 | }
152 | else
153 | {
154 | $this->appendError("NoTables" , "No tables found in the db" );
155 | $select = '';
156 | }
157 |
158 | return $select;
159 | }
160 |
161 | /**
162 | * Return value with table names for a select
163 | * @return Array
164 | */
165 | protected function getTableValuesSelect($dbm = null)
166 | {
167 | $dbm = $dbm ? $dbm : new DBM;
168 | $table_raw = $dbm->getTableList();
169 |
170 | return $table_raw ? array_combine(array_values($table_raw), array_values($table_raw) ) : false;
171 | }
172 |
173 | /**
174 | * Return the table for the preview
175 | * @return String $table
176 | */
177 | protected function getDataTable()
178 | {
179 | $data = $this->getTableData();
180 | $header = $this->getTableHeader();
181 |
182 | $table = new Table();
183 | // set the configuration
184 | $table->setConfig(array(
185 | "table-hover"=>true,
186 | "table-condensed"=>false,
187 | "table-responsive" => true,
188 | "table-striped" => true,
189 | ));
190 | // set header
191 | $table->setHeader( $header );
192 | // set data
193 | foreach($data as $val)
194 | {
195 | $table->addRows( get_object_vars($val) );
196 | }
197 |
198 | return $table->getHtml();
199 | }
200 |
201 | /**
202 | * Get the data from the db for the preview
203 | *
204 | * @throws BadMethodCallException
205 | * @throws NoDataException
206 | * @return Array $data
207 | */
208 | protected function getTableData()
209 | {
210 | $data = array();
211 | $form_input = $this->getFormInput();
212 |
213 | if( $form_input['table_name'] && $form_input['max_rows'] )
214 | {
215 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
216 | $temp_data = DB::connection($connection_name)
217 | ->table($this->form_input['table_name'])
218 | ->select("*")
219 | ->take($this->form_input['max_rows']);
220 | if( $temp_data->exists() )
221 | {
222 | $data = $temp_data->get();
223 | }
224 | else
225 | {
226 | throw new NoDataException;
227 | }
228 | }
229 | else
230 | {
231 | throw new \BadMethodCallException;
232 | }
233 |
234 | return $data;
235 | }
236 |
237 | /**
238 | * Get the header for the preview
239 | *
240 | * @throws BadMethodCallException
241 | * @return Array $columns
242 | */
243 | protected function getTableHeader($dbm = null)
244 | {
245 | $dbm = $dbm ? $dbm : new DBM;
246 | $columns = array();
247 | $form_input = $this->getFormInput();
248 |
249 | if( $form_input['table_name'] )
250 | {
251 | $dbal_columns = $dbm->getTableColumns($this->form_input['table_name']);
252 | foreach($dbal_columns as $column)
253 | {
254 | $array_columns = $column->toArray();
255 | $columns[] = $array_columns["name"];
256 | }
257 | }
258 | else
259 | {
260 | throw new \BadMethodCallException;
261 | }
262 |
263 | return $columns;
264 | }
265 |
266 | }
267 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Export/StateHandler.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Config;
9 | use Illuminate\Support\Facades\Session;
10 | use Illuminate\Support\Facades\Response;
11 | use Jacopo\LaravelImportExport\Models\StateHandling\StateHandler as StateHandlerBase;
12 |
13 | class StateHandler extends StateHandlerBase
14 | {
15 | protected $session_key;
16 | protected $initial_state = "Jacopo\LaravelImportExport\Models\StateHandling\Export\GetTableName";
17 |
18 | public function __construct()
19 | {
20 | $this->session_key = Config::get('laravel-import-export::baseconf.session_export_key','export_state');
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/GeneralState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Jacopo\LaravelImportExport\Models\StateHandling\StateInterface;
9 | use Illuminate\Support\Facades\Config;
10 | use Illuminate\Support\Facades\URL;
11 | use Illuminate\Support\Facades\Session;
12 | use Illuminate\Support\MessageBag;
13 | use Jacopo\LaravelImportExport\Models\Exceptions\ClassNotFoundException;
14 |
15 | abstract class GeneralState implements StateInterface {
16 |
17 | /**
18 | * Name of the next state class
19 | * @var String
20 | */
21 | protected $next_state_class;
22 | /**
23 | * Name of the action to process the form
24 | * @var String
25 | */
26 | protected $process_action;
27 | /**
28 | * if the status has already been executed with success
29 | * @var boolean
30 | */
31 | /**
32 | * Name of the action to reset current state
33 | * @var string
34 | */
35 | protected $reset_state;
36 | /**
37 | * If the state has been executed
38 | * @var boolean
39 | */
40 | protected $is_executed = false;
41 | /**
42 | * The imput given from the form
43 | * @var Mixed
44 | */
45 | protected $form_input;
46 | /**
47 | * Validation rules
48 | * @var Array
49 | */
50 | protected $rules;
51 | /**
52 | * Validation erorrs
53 | * @var Array
54 | */
55 | protected $errors;
56 | /**
57 | * key of the session used to exchange data between states
58 | * @var string
59 | */
60 | protected $exchange_key;
61 | /**
62 | * Return the form
63 | */
64 | /**
65 | * Name of session key which store errors
66 | * @var String
67 | */
68 | protected $errors_key;
69 |
70 | public function getForm(){
71 |
72 | if( ! $this->getIsExecuted() )
73 | {
74 | return $this->printFormNew();
75 | }
76 | else
77 | {
78 | return $this->printFormOld();
79 | }
80 | }
81 |
82 | protected function getProcessUrl()
83 | {
84 | return URL::action($this->process_action);
85 | }
86 |
87 | /**
88 | * Return the next state
89 | *
90 | * @throws Jacopo\LaravelImportExport\Exception\ClassNotFoundException
91 | * @return ImportState
92 | */
93 | public function getNextState()
94 | {
95 | if( $this->getIsExecuted() )
96 | {
97 | if ( class_exists( $next = $this->getNextStateClass() ) )
98 | {
99 | return (new $next );
100 | }
101 | else
102 | {
103 | throw new ClassNotFoundException;
104 | }
105 | }
106 | else
107 | {
108 | return $this;
109 | }
110 | }
111 |
112 | /**
113 | * Print the form errors if exists
114 | *
115 | * @return String|null
116 | */
117 | public function getErrorHeader()
118 | {
119 | $err_str = '';
120 | $error_class = $this->getErrors();
121 | $error_session = Session::get($this->errors_key);
122 |
123 | if( $error_class )
124 | {
125 | foreach ($error_class->all() as $error_key => $error) {
126 | $err_str.="{$error}
";
127 | }
128 | }
129 |
130 | if( $error_session)
131 | {
132 | foreach ($error_session->all() as $error_key => $error) {
133 | $err_str.="{$error}
";
134 | }
135 | }
136 |
137 | $this->resetErrors();
138 |
139 | return $err_str;
140 | }
141 |
142 | public function getRules()
143 | {
144 | return $this->rules;
145 | }
146 |
147 | public function getErrors()
148 | {
149 | return $this->errors;
150 | }
151 |
152 | public function setErrors($value)
153 | {
154 | $this->errors = $value;
155 | }
156 |
157 | public function getFormInput()
158 | {
159 | return $this->form_input;
160 | }
161 |
162 | public function getIsExecuted()
163 | {
164 | return $this->is_executed;
165 | }
166 |
167 | public function getNextStateClass()
168 | {
169 | return $this->next_state_class;
170 | }
171 |
172 | /**
173 | * Return the form that needs to be processed
174 | */
175 | protected function printFormNew()
176 | {
177 | return $this->getErrorHeader();
178 | }
179 | /**
180 | * Return the form that has already been processed
181 | */
182 | protected abstract function printFormOld();
183 |
184 | /**
185 | * Process the form and update the current state
186 | * @return ImportState
187 | */
188 | public abstract function processForm();
189 |
190 | public abstract function fillFormInput();
191 |
192 | function __sleep()
193 | {
194 | $serialize_fields = array();
195 |
196 | $serialize_fields[] = 'next_state_class';
197 | $serialize_fields[] = 'is_executed';
198 | $serialize_fields[] = 'process_action';
199 | $serialize_fields[] = 'reset_state';
200 | $serialize_fields[] = 'rules';
201 | $serialize_fields[] = 'errors';
202 |
203 | return $serialize_fields;
204 | }
205 |
206 | /**
207 | * Append error to the MessageBag
208 | */
209 | public function appendError($error_key, $error_string)
210 | {
211 | if($this->getErrors())
212 | {
213 | // append
214 | $this->errors->add( $error_key, $error_string );
215 | }
216 | else
217 | {
218 | // new MessageBag
219 | $this->errors = new MessageBag( array($error_key => $error_string) );
220 | }
221 | }
222 |
223 | protected function getResetUrl()
224 | {
225 | return \URL::action($this->reset_state);
226 | }
227 |
228 | /**
229 | * Clean all errors
230 | */
231 | protected function resetErrors()
232 | {
233 | Session::forget($this->errors_key);
234 | $this->errors = array();
235 | }
236 |
237 | }
238 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Import/GeneralState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Jacopo\LaravelImportExport\Models\StateHandling\GeneralState as GeneralStateBase;
9 |
10 | abstract class GeneralState extends GeneralStateBase {
11 |
12 | protected $process_action = "Jacopo\LaravelImportExport\ImportController@postProcessForm";
13 | protected $reset_state = "Jacopo\LaravelImportExport\ImportController@getResetState";
14 | protected $exchange_key = 'import_state_exchange';
15 | protected $errors_key = 'errors_import';
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Import/GetCsvState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Exception;
9 | use Illuminate\Support\Facades\Form;
10 | use Illuminate\Support\Facades\Input;
11 | use Illuminate\Support\Facades\Session;
12 | use Jacopo\LaravelImportExport\Models\ValidatorFormInputModel;
13 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler;
14 | use Jacopo\LaravelImportExport\Models\Exceptions\FileNotFoundException;
15 | use Jacopo\LaravelImportExport\Models\Exceptions\InvalidArgumentException;
16 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
17 | use Jacopo\LaravelImportExport\Models\Exceptions\UnalignedArrayException;
18 | use Jacopo\LaravelImportExport\Models\Exceptions\DomainException;
19 |
20 | class GetCsvState extends GeneralState {
21 |
22 | protected $next_state_class = "Jacopo\LaravelImportExport\Models\StateHandling\Import\GetTableState";
23 |
24 | protected $rules = array(
25 | "file_csv" => "required",
26 | );
27 |
28 | /**
29 | * Return the form that needs to be processed
30 | */
31 | protected function printFormNew(){
32 | $str = parent::printFormNew();
33 | $str .=
34 | "".
35 | "
".
36 | "
Step1: Upload file
".
37 | // "
".
38 | Form::open(array( 'url' => $this->getProcessUrl(), 'files' => true , 'role' => 'form')).
39 | "
".
40 | Form::label('file_csv', 'Select file to upload (CSV only for now) *').
41 | Form::file('file_csv').
42 | "
".
43 | "
".
44 | Form::label('separator','Type of separator: ').
45 | Form::select('separator' , array( ','=>'comma ,' , ';'=>'semicolon ;' ) , ',', array("class" => "form-control") ).
46 | "
".
47 | "
".
48 | Form::label('max_lines','Max number of lines to show in preview: ').
49 | Form::select('max_lines' , array('10'=>'10', '50'=>'50', '100'=>'100', '150'=>'150') , '10', array("class"=> "form-control") ).
50 | "
".
51 | "
".
52 | "".
56 | "
".
57 | "
".
58 | "".
62 | "
".
63 | "
".
64 | Form::submit('Load' , array('class'=>'btn btn-success')).
65 | Form::close().
66 | "
". // form-group
67 | "
". // col
68 | "
". // row
69 | "
";
70 |
71 | return $str;
72 | }
73 |
74 | /**
75 | * Return the form that has already been processed
76 | */
77 | protected function printFormOld(){
78 | $reset_url = $this->getResetUrl();
79 |
80 | $str=<<
82 |
85 |
86 |
87 |
88 |
89 | Upload file: completed succesfully!
90 |
91 |
92 |
93 | STR;
94 | return $str;
95 | }
96 |
97 | /**
98 | * Process the form
99 | *
100 | * @return Boolean $is_executed if the state is executed successfully
101 | */
102 | public function processForm(array $input = null, $validator = null, $csv_handler = null)
103 | {
104 | if($input)
105 | {
106 | $this->form_input = $input;
107 | }
108 | else
109 | {
110 | $this->fillFormInput();
111 | }
112 |
113 | $validator = ($validator) ? $validator : new ValidatorFormInputModel($this);
114 | $csv_handler = ($csv_handler) ? $csv_handler : new CsvFileHandler();
115 |
116 | if ( $validator->validateInput() && $this->checkInputCsv() )
117 | {
118 | // process data
119 | $config = $this->getConfigFromInput();
120 | $success = true;
121 | // big try catch to set errors
122 | try
123 | {
124 | $csv_file = $csv_handler->openFromCsv($config);
125 | }
126 | catch(FileNotFoundException $e)
127 | {
128 | $this->appendError("NotFound", "File not found." );
129 | $success = false;
130 | }
131 | catch(InvalidArgumentException $e)
132 | {
133 | $this->appendError("InvalidArgument", "Invalid argument." );
134 | $success = false;
135 | }
136 | catch(DomainException $e)
137 | {
138 | $this->appendError("Domain", "Invalid temporary data." );
139 | $success = false;
140 | }
141 | catch(UnalignedArrayException $e)
142 | {
143 | $this->appendError("UnalignedArray", "Unaligned data." );
144 | $success = false;
145 | }
146 | catch(NoDataException $e)
147 | {
148 | $this->appendError("NoData", "No data found in the file." );
149 | $success = false;
150 | }
151 |
152 | // save temporary
153 | if($success)
154 | {
155 | $saved = false;
156 |
157 | try
158 | {
159 | $saved = $csv_handler->saveTemporary();
160 | }
161 | catch( Exception $e)
162 | {
163 | $this->appendError("SaveTemporary" , "Cannot save temporary data: check database access configuration." );
164 | }
165 |
166 | if($saved)
167 | {
168 | $this->is_executed = true;
169 | // add if want to create table to session
170 | $exchange_data = array(
171 | "max_lines" => $this->form_input['max_lines'],
172 | "create_table" => $this->form_input['create_table']
173 | );
174 | // save data for next state
175 | Session::put($this->exchange_key,$exchange_data);
176 | }
177 | }
178 | }
179 |
180 | return $this->getIsExecuted();
181 | }
182 |
183 | public function fillFormInput()
184 | {
185 | if(Input::hasFile('file_csv'))
186 | {
187 | $this->form_input['file_csv'] = Input::file('file_csv');
188 | }else
189 | {
190 | $this->form_input['file_csv'] = '';
191 | }
192 | $this->form_input['separator'] = Input::get('separator');
193 | $this->form_input['headers'] = Input::get('headers');
194 | $this->form_input['max_lines'] = Input::get('max_lines');
195 | $this->form_input['create_table'] = Input::get('create_table');
196 | }
197 |
198 | protected function checkInputCsv()
199 | {
200 | $valid = false;
201 |
202 | $input = $this->form_input['file_csv'];
203 | if( ! empty($input) )
204 | {
205 | $name = $this->form_input['file_csv']->getClientOriginalName();
206 | if(strstr($name,"."))
207 | {
208 | $name = explode(".",$name);
209 | $extension = end($name);
210 | if(strcasecmp($extension,"csv") == 0)
211 | $valid = true;
212 | }
213 | }
214 |
215 | if( ! $valid )
216 | {
217 | $this->appendError("Invalid_extension", "The input file must be .csv" );
218 | }
219 |
220 | return $valid;
221 | }
222 |
223 | // get the config from form input
224 | protected function getConfigFromInput()
225 | {
226 | $config_file_parse['separator'] = $this->form_input['separator'];
227 | $config_file_parse['file_path'] = $this->form_input['file_csv']->getRealPath();
228 | $config["file_parse"] = $config_file_parse;
229 |
230 | $config_builder['first_line_headers'] = ( $this->form_input['headers'] != '' );
231 | $config["builder"] = $config_builder;
232 |
233 | $config_model = array();
234 | $config["model"] = $config_model;
235 |
236 | return $config;
237 | }
238 |
239 | }
240 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Import/GetTableState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Form;
9 | use Illuminate\Support\Facades\Session;
10 | use Jacopo\LaravelImportExport\Models\InputWrapper as Input;
11 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler;
12 | use Jacopo\LaravelImportExport\Models\ParseCsv\CsvFile;
13 | use Jacopo\LaravelImportExport\Models\ValidatorFormInputModel;
14 | use Jacopo\LaravelImportExport\Models\Exceptions\UnalignedArrayException;
15 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
16 | use Jacopo\LaravelImportExport\Models\Exceptions\HeadersNotSetException;
17 | use Jacopo\Bootstrap3Table\BootstrapTable as Table;
18 | use Exception;
19 |
20 | class GetTableState extends GeneralState {
21 |
22 | protected $next_state_class = "Jacopo\LaravelImportExport\Models\StateHandling\Import\ImportCompleteState";
23 |
24 | protected $rules = array(
25 | "table_name" => "required"
26 | );
27 |
28 | /**
29 | * Return the form that needs to be processed
30 | */
31 | protected function printFormNew(){
32 |
33 | $str = parent::printFormNew();
34 |
35 | $csv_handler = new CsvFileHandler();
36 | $csv_file = $csv_handler->getTemporary();
37 |
38 | $str.= "".
39 | "
".
40 | "
Step2: Configure import data
".
41 | "Sample data from csv file:
";
42 | try
43 | {
44 | $str.= $this->getCsvTableStr($csv_handler, $csv_file);
45 | }
46 | catch(NoDataException $e)
47 | {
48 | }
49 |
50 | $str.= "Fill the form below:
";
51 | $exchange_data = Session::get($this->exchange_key);
52 | $setSchema = $exchange_data["create_table"];
53 | $str.= $this->getConfigForm($csv_handler, $csv_file, $setSchema);
54 |
55 | $str.= "". // col-md-12
56 | "
"; // row
57 |
58 | return $str;
59 | }
60 |
61 | /**
62 | * Return the form that has already been processed
63 | */
64 | protected function printFormOld(){
65 |
66 | $str=<<
68 |
69 | Save file: completed succesfully!
70 |
71 |
72 |
73 |
74 | STR;
75 | return $str;
76 | }
77 |
78 | protected function getConfigForm(CsvFileHandler $csv_handler, CsvFile $csv_file, $setSchema = false)
79 | {
80 | $str = Form::open(array( 'url' => $this->getProcessUrl(), "role" => "form", "class" => "form-horizontal") );
81 |
82 | // table name
83 | $str.= "";
89 |
90 | // column names
91 | $str.= "Write the name of each column to save into the DB, the index number are the same as the column number in the sample data(\"__empty\"=don't save)
";
92 | $num_cols = $csv_handler->getMaxLength();
93 | $header = $csv_file->getCsvHeader();
94 | foreach( range(0,$num_cols-1) as $key)
95 | {
96 | $default_value = isset($header[$key]) ? $header[$key] : "__empty";
97 | $str.= "";
108 | }
109 | $str.= Form::hidden("num_cols",$num_cols);
110 | $str.= "";
115 |
116 | $str.= Form::close();
117 |
118 | return $str;
119 |
120 | }
121 |
122 | /**
123 | * Return a select for the type of data to create
124 | *
125 | * @param $name select name and id
126 | * @return String $select
127 | */
128 | protected function getSelectSchema($name)
129 | {
130 | $data_types = array(
131 | "string" => "string",
132 | "integer" => "integer",
133 | "increments" => "increments",
134 | "bigIncrements" => "bigIncrements",
135 | "bigInteger" => "bigInteger",
136 | "smallInteger" => "smallInteger",
137 | "float" => "float",
138 | "double" => "double",
139 | "decimal" => "decimal",
140 | "boolean" => "boolean",
141 | "date" => "date",
142 | "dateTime" => "dateTime",
143 | "time" => "time",
144 | "blob" => "binary",
145 | );
146 |
147 | $select =Form::label($name,'Type: ', array("class"=>"control-label col-lg-2") ).
148 | "".
149 | Form::select($name , $data_types, '', array("class" => "form-control") ).
150 | "
";
151 |
152 | return $select;
153 | }
154 |
155 | /**
156 | * Return the table rappresenting the csv data
157 | *
158 | * @throws NoDataException
159 | * @return String $table
160 | */
161 | protected function getCsvTableStr(CsvFileHandler $csv_handler, CsvFile $csv_file)
162 | {
163 | if(! $csv_file)
164 | {
165 | throw new NoDataException();
166 | }
167 |
168 | $table = new Table();
169 | // set the configuration
170 | $table->setConfig(array(
171 | "table-hover"=>true,
172 | "table-condensed"=>false,
173 | "table-responsive" => true,
174 | "table-striped" => true,
175 | ));
176 |
177 | // set header
178 | if( $csv_header = $csv_file->getCsvHeader() )
179 | {
180 | $table->setHeader( $csv_header );
181 | }
182 |
183 | // set content
184 | $exchange_data = Session::get($this->exchange_key);
185 | $max_num_lines = $exchange_data["max_lines"];
186 | foreach( $csv_file as $csv_line_key => $csv_line)
187 | {
188 | if($csv_line_key >= $max_num_lines)
189 | break;
190 |
191 | // add data table row
192 | $table->addRows( $csv_line->getElements() );
193 | }
194 |
195 |
196 |
197 | return $table->getHtml();
198 | }
199 |
200 | /**
201 | * Process the form and return the next state
202 | * @return Boolean $is_executed
203 | */
204 | public function processForm(array $input = null, $validator = null, $csv_handler = null)
205 | {
206 | if($input)
207 | {
208 | $this->form_input = $input;
209 | }
210 | else
211 | {
212 | $this->fillFormInput();
213 | }
214 |
215 | $validator = ($validator) ? $validator : new ValidatorFormInputModel($this);
216 | $csv_handler = ($csv_handler) ? $csv_handler : new CsvFileHandler();
217 |
218 | if ( $validator->validateInput() && $this->checkColumns() )
219 | {
220 | // process form
221 | $csv_file = $csv_handler->getTemporary();
222 | if($csv_file)
223 | {
224 | try
225 | {
226 | $csv_handler->updateHeaders($csv_file, $this->form_input["columns"], $this->form_input["table_name"]);
227 | }
228 | catch(UnalignedArrayException $e)
229 | {
230 | $this->appendError("No_temporary", "Invalid Column names." );
231 | return $this->getIsExecuted();
232 | }
233 |
234 | try
235 | {
236 | $csv_handler->saveToDb($this->form_input['types']);
237 | $this->is_executed = true;
238 | }
239 | catch( HeadersNotSetException $e)
240 | {
241 | $this->appendError("Save_err", "Cannot save data: check if dmbs support transaction.");
242 | }
243 | catch( PDOException $e)
244 | {
245 | $this->appendError("Save_err", $e->getMessage() );
246 | }
247 | catch( Exception $e)
248 | {
249 | $this->appendError("Save_err", $e->getMessage() );
250 | }
251 | }
252 | else
253 | {
254 | $this->appendError("No_temporary","No data available to save");
255 | }
256 | }
257 | return $this->getIsExecuted();
258 | }
259 |
260 | public function fillFormInput(Input $input = null)
261 | {
262 | $input = $input ? $input : new Input();
263 | $this->form_input['table_name'] = $input->get('table_name');
264 | $num_cols = $input->get('num_cols');
265 | if($num_cols)
266 | {
267 | $array_cols = array();
268 | $array_type = array();
269 | // if need to create schema
270 | $this->form_input['create_schema'] = $input->get('create_schema');
271 | foreach( range(0,$num_cols-1) as $key)
272 | {
273 | $column_name = $input->get("column_{$key}");
274 | if( $column_name != '__empty')
275 | {
276 | $array_cols = array_merge($array_cols , array( $key => $column_name) );
277 | $column_type = $input->get("column_type_{$key}");
278 | $array_type = array_merge($array_type , array( $column_name => $column_type) );
279 | }
280 | }
281 | $this->form_input['types'] = $array_type;
282 | $this->form_input['columns'] = $array_cols;
283 | }
284 | }
285 |
286 | /**
287 | * Check the column field if atleast one exists
288 | * @return Boolean $success
289 | */
290 | protected function checkColumns()
291 | {
292 | $success = false;
293 |
294 | if ( ! empty($this->form_input['columns']) )
295 | {
296 | $success = true;
297 | }
298 | else
299 | {
300 | $this->appendError("No_columns","No column name setted: you need to fill atleast one \"column_\" field");
301 | }
302 |
303 | return $success;
304 | }
305 |
306 | }
307 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Import/ImportCompleteState.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | class ImportCompleteState extends GeneralState {
9 |
10 | /**
11 | * Return the form that needs to be processed
12 | */
13 | protected function printFormNew(){
14 |
15 | $str = parent::printFormNew();
16 |
17 | $reset_url = $this->getResetUrl();
18 |
19 | $str.=<<
21 |
24 |
25 | STR;
26 |
27 |
28 | return $str;
29 | }
30 |
31 | public function printFormOld(){}
32 | public function processForm(){}
33 | public function fillFormInput(){}
34 | }
35 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/Import/StateHandler.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Config;
9 | use Illuminate\Support\Facades\DB;
10 | use Jacopo\LaravelImportExport\Models\StateHandling\StateHandler as StateHandlerBase;
11 |
12 | class StateHandler extends StateHandlerBase
13 | {
14 | protected $session_key;
15 | protected $initial_state = "Jacopo\LaravelImportExport\Models\StateHandling\Import\GetCsvState";
16 |
17 | public function __construct()
18 | {
19 | $this->session_key = Config::get('laravel-import-export::baseconf.session_import_key','import_state');
20 | }
21 |
22 | /**
23 | * Reset the session_array state
24 | */
25 | public function resetState()
26 | {
27 | parent::resetState();
28 |
29 | // clean temporary db
30 | $table_name = Config::get('laravel-import-export::baseconf.table_prefix');
31 | $connection_name = Config::get('laravel-import-export::baseconf.connection_name');
32 | DB::connection($connection_name)->table($table_name)->truncate();
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/StateArray.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use \ArrayIterator;
9 |
10 | class StateArray extends ArrayIterator {}
11 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/StateHandler.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Session;
9 | use Illuminate\Support\Facades\DB;
10 | use Illuminate\Support\Facades\Config;
11 | use Illuminate\Support\MessageBag;
12 | use Jacopo\LaravelImportExport\Models\Exceptions\NoDataException;
13 | use Jacopo\LaravelImportExport\Models\Exceptions\ClassNotFoundException;
14 |
15 | class StateHandler
16 | {
17 | protected $session_key;
18 | protected $initial_state;
19 | protected $state_array;
20 |
21 | /**
22 | * Initialize starting import state from session
23 | */
24 | public function initializeState()
25 | {
26 | if (Session::has($this->session_key))
27 | {
28 | $this->setStateArray( Session::get($this->session_key) );
29 | }
30 | else
31 | {
32 | $this->resetState();
33 | }
34 | return $this->getStateArray();
35 | }
36 |
37 | /**
38 | * Reset the session_array state
39 | */
40 | public function resetState()
41 | {
42 | // clean states
43 | $this->setStateArray( new StateArray() );
44 | $state_array = $this->getStateArray();
45 | $state_array->append( new $this->initial_state );
46 | Session::put($this->session_key,$state_array);
47 | }
48 |
49 | /**
50 | * Fill layout content with forms
51 | */
52 | public function setContent($layout)
53 | {
54 | $content = '';
55 |
56 | $state_array = $this->getStateArray();
57 | foreach($state_array as $state_key => $state)
58 | {
59 | $content.=$state->getForm();
60 | }
61 | $layout->content = $content;
62 | }
63 |
64 | /**
65 | * Process the current form
66 | * @return $executed if success
67 | * @throws ClassNotFoundException
68 | */
69 | public function processForm()
70 | {
71 | $current_state = $this->getCurrent();
72 | $executed_process = $current_state->processForm();
73 | // set next state
74 | $executed_next_state = $this->setNextState($current_state,$executed_process);
75 | // return success
76 | return ( $executed_process && $executed_next_state );
77 | }
78 |
79 | /**
80 | * Set the next state
81 | *
82 | * @return Boolean $success
83 | */
84 | protected function setNextState($current_state, $executed)
85 | {
86 | try
87 | {
88 | $next_state = $current_state->getNextState();
89 | }
90 | catch(ClassNotFoundException $e)
91 | {
92 | Session::put('Errors', new MessageBag( array("Class" => "Class not found") ) );
93 | return false;
94 | }
95 |
96 | if($executed)
97 | {
98 | // append next state
99 | $this->append($next_state);
100 | }
101 | else
102 | {
103 | // replace current state
104 | $this->replaceCurrent($next_state);
105 | }
106 |
107 | return true;
108 | }
109 |
110 | protected function append($value)
111 | {
112 | $this->state_array->append($value);
113 | }
114 |
115 | public function getCurrent()
116 | {
117 | return $this->getLastState();
118 | }
119 |
120 | /**
121 | * Replace the current state
122 | */
123 | public function replaceCurrent($value)
124 | {
125 | $key = $this->getLastKey();
126 | if($key >= 0)
127 | {
128 | $this->getStateArray()->offsetSet($key,$value);
129 | }
130 | else
131 | {
132 | throw new NoDataException;
133 | }
134 | }
135 |
136 | public function getLastState()
137 | {
138 | $key = $this->getLastKey();
139 | if($key >= 0)
140 | {
141 | $state_array = $this->getStateArray();
142 | return $state_array[$key];
143 | }
144 | else
145 | {
146 | throw new NoDataException;
147 | }
148 | }
149 |
150 | public function getLastKey()
151 | {
152 | return ( count($this->state_array) - 1 );
153 | }
154 |
155 | public function getStateArray()
156 | {
157 | return $this->state_array;
158 | }
159 |
160 | public function setStateArray($value)
161 | {
162 | $this->state_array = $value;
163 | }
164 |
165 | }
166 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/StateHandling/StateInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Database\Eloquent\Model;
9 | use Illuminate\Support\Facades\Config;
10 |
11 | class TemporaryModel extends Model {
12 |
13 | protected $table;
14 |
15 | protected $fillable = array('file_object','id');
16 |
17 | public $timestamps = false;
18 |
19 | protected $connection;
20 |
21 | // test model saving and getting
22 | public function __construct()
23 | {
24 | $this->table = Config::get('laravel-import-export::baseconf.table_prefix');
25 | $this->connection = Config::get('laravel-import-export::baseconf.connection_name');
26 |
27 | $params = func_get_args();
28 |
29 | return parent::__construct($params);
30 | }
31 |
32 | // encode object for saving
33 | public function setFileObjectAttribute($value)
34 | {
35 | $this->attributes['file_object'] = base64_encode( serialize($value) );
36 | }
37 |
38 | // decode object for saving
39 | public function getFileObjectAttribute()
40 | {
41 | return unserialize( base64_decode( $this->attributes['file_object'] ) );
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/Models/ValidatorFormInputModel.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | use Illuminate\Support\Facades\Validator;
9 | use Illuminate\Database\Eloquent\Model;
10 |
11 | class ValidatorFormInputModel extends Model {
12 |
13 | protected $model;
14 |
15 | public function __construct($model)
16 | {
17 | $this->model = $model;
18 | }
19 |
20 | /**
21 | * Validate form_input with $rules
22 | * @return Boolean
23 | */
24 | public function validateInput()
25 | {
26 | $v = Validator::make ( $this->model->getFormInput() , $this->model->getRules() );
27 |
28 | $success = true;
29 | if ( $v->fails() )
30 | {
31 | $this->model->setErrors( $v->messages() );
32 | $success = false;
33 | }
34 |
35 | return $success;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/Jacopo/LaravelImportExport/routes.php:
--------------------------------------------------------------------------------
1 | "_import_export_temporary_table",
5 | "default_title" => "Laravel-Import-Export",
6 | "session_import_key" => "import_state",
7 | "session_export_key" => "export_state",
8 | "base_application_route" => "importer",
9 | "connection_name" => "import",
10 | );
--------------------------------------------------------------------------------
/src/config/database.php:
--------------------------------------------------------------------------------
1 | array(
5 |
6 | 'import' => array(
7 | 'driver' => 'mysql', //sqlite | mysql | pgsql | sqlsrv
8 | 'host' => 'localhost',
9 | 'database' => 'laravel_import_export',
10 | 'username' => 'root',
11 | 'password' => 'root',
12 | 'charset' => 'utf8',
13 | 'collation' => 'utf8_unicode_ci',
14 | 'prefix' => '',
15 | ),
16 | ),
17 | );
--------------------------------------------------------------------------------
/src/controllers/BaseController.php:
--------------------------------------------------------------------------------
1 | layout))
22 | {
23 | $this->layout = View::make($this->layout);
24 | // set menu index
25 | $this->layout->menu_index = $this->menu_index;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/controllers/ExportController.php:
--------------------------------------------------------------------------------
1 | setContent($this->layout);
13 | }
14 |
15 | public function getResetState()
16 | {
17 | \App::make('export_csv_handler')->resetState();
18 |
19 | return \Redirect::action('Jacopo\LaravelImportExport\ExportController@getIndex');
20 | }
21 |
22 | public function postProcessForm()
23 | {
24 | $success =\App::make('export_csv_handler')->processForm();
25 |
26 | return \Redirect::action('Jacopo\LaravelImportExport\ExportController@getIndex');
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/controllers/HomeController.php:
--------------------------------------------------------------------------------
1 | layout->nest('content','laravel-import-export::home/index');
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/src/controllers/ImportController.php:
--------------------------------------------------------------------------------
1 | setContent($this->layout);
13 | }
14 |
15 | public function getResetState()
16 | {
17 | \App::make('import_csv_handler')->resetState();
18 |
19 | return \Redirect::action('Jacopo\LaravelImportExport\ImportController@getIndex');
20 | }
21 |
22 | public function postProcessForm()
23 | {
24 | $success =\App::make('import_csv_handler')->processForm();
25 |
26 | return \Redirect::action('Jacopo\LaravelImportExport\ImportController@getIndex');
27 | }
28 | }
--------------------------------------------------------------------------------
/src/migrations/2013_09_25_222039__laravel_import_export_temporary_table.php:
--------------------------------------------------------------------------------
1 | getTableName();
16 | Schema::create($table_name, function($table)
17 | {
18 | $table->increments('id');
19 | });
20 | DB::statement('ALTER TABLE `'.$table_name.'` ADD `file_object` LONGBLOB NOT NULL');
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | *
26 | * @return void
27 | */
28 | public function down()
29 | {
30 | $table_name = $this->getTableName();
31 |
32 | Schema::drop($table_name);
33 | }
34 |
35 | private function getTableName()
36 | {
37 | return Config::get('laravel-import-export::baseconf.table_prefix');
38 | }
39 |
40 | private function getConnectionName()
41 | {
42 | return Config::get('laravel-import-export::baseconf.connection_name');
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/src/views/home/index.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
Welcome
3 |
Welcome to laravel import-export package. This software is built to import and export data from various format file to an sql database.
4 |
What are you waiting for?
5 |
6 | Start importing »
7 |
8 |
--------------------------------------------------------------------------------
/src/views/layouts/default.blade.php:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{(isset($title)) ? $title : Config::get('laravel-import-export::baseconf.default_title')}}
12 |
13 | {{-- loading css --}}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
41 |
42 |
43 |
44 | {{isset($content) ? $content : ''}}
45 |
46 |
47 |
48 |
49 | {{-- loading javascript --}}
50 | {{ HTML::script(asset('packages/jacopo/laravel-import-export/js/jquery-1.10.2.min.js') ) }}
51 | {{ HTML::script(asset('packages/jacopo/laravel-import-export/js/bootstrap.js') ) }}
52 |
53 |
54 |
--------------------------------------------------------------------------------
/tests/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intrip/laravel-import-export/2e6963778a0214c9123d0c51a0d01d8127e1e935/tests/.gitkeep
--------------------------------------------------------------------------------
/tests/unit/TestCsvFile.php:
--------------------------------------------------------------------------------
1 | csv_file = new CsvFile();
12 | }
13 |
14 | //@todo write tests
15 | public function testToMakePass()
16 | {}
17 | }
--------------------------------------------------------------------------------
/tests/unit/TestCsvFileBuilder.php:
--------------------------------------------------------------------------------
1 | makePartial();
25 | $mock->shouldReceive('parseCsvFile')
26 | ->times(4)
27 | ->andReturn($mocked_csv_data[0],$mocked_csv_data[1],$mocked_csv_data[2],$mocked_csv_data[3]);
28 | $this->mockConfig();
29 |
30 | $builder = new CsvFileBuilder(array(),array(),array("first_line_headers"=>false),null,$mock);
31 | $builder->buildFromCsv();
32 |
33 | $csv_file = $builder->getCsvFile();
34 |
35 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFile', $csv_file);
36 |
37 | // check headers
38 | $this->assertEmpty($csv_file->getCsvHeader());
39 |
40 | // check data
41 | foreach($csv_file as $key_csv_line => $csv_line)
42 | {
43 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\ParseCsv\CsvLine', $csv_line);
44 | $this->assertSame($mocked_csv_data[$key_csv_line], $csv_line->getAttributes());
45 | }
46 | }
47 |
48 | public function testBuildCreateFileFromCsvSuccessWithHeaders()
49 | {
50 | $mocked_csv_data = array(
51 | array("name","surname"),
52 | array("Jacopo","Beschi"),
53 | false,
54 | );
55 | $mock = \Mockery::mock('Jacopo\LaravelImportExport\Models\ParseCsv\ParseCsv')->makePartial();
56 | $mock->shouldReceive('parseCsvFile')
57 | ->times(3)
58 | ->andReturn($mocked_csv_data[0],$mocked_csv_data[1],$mocked_csv_data[2]);
59 |
60 | $builder = new CsvFileBuilder(array(),array(),array("first_line_headers"=>true),null,$mock);
61 | $builder->buildFromCsv();
62 |
63 | $csv_file = $builder->getCsvFile();
64 |
65 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFile', $csv_file);
66 |
67 | // check headers
68 | $csv_file->rewind();
69 | $this->assertSame($mocked_csv_data[0],$csv_file->getCsvHeader());
70 |
71 | // check values
72 | $second = $csv_file->current();
73 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\ParseCsv\CsvLine', $second);
74 | $this->assertSame($mocked_csv_data[1], $second->getAttributes());
75 | }
76 |
77 | protected function mockConfig()
78 | {
79 | $app = m::mock('AppMock');
80 | $app->shouldReceive('instance')->once()->andReturn($app);
81 |
82 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
83 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
84 |
85 | $config->shouldReceive('get')
86 | ->andReturn(true);
87 | }
88 |
89 | }
--------------------------------------------------------------------------------
/tests/unit/TestCsvFileHandler.php:
--------------------------------------------------------------------------------
1 | csv_file_handler = m::mock('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler')->makePartial();
16 | }
17 |
18 | public function tearDown()
19 | {
20 | m::close();
21 | }
22 |
23 | public function testOpenFromCsvSuccess()
24 | {
25 | $mock = m::mock('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileBuilder')->makePartial();
26 | $mock->shouldReceive('buildFromCsv','getCsvFile')
27 | ->andReturn(true,true);
28 |
29 | $config = array(
30 | "model" => 1,
31 | "file_parse" => 2,
32 | "builder" => 3,
33 | );
34 |
35 | $result = $this->csv_file_handler->openFromCsv($config,$mock);
36 |
37 | $this->assertSame(true,$result);
38 | }
39 |
40 | public function testSaveTemporarySuccess()
41 | {
42 | $this->mockConfig();
43 | $this->mockDbConnection();
44 | $temporary_stub = new TemporaryModelStub();
45 | $csv_file = new CsvFile();
46 |
47 | $success = $this->csv_file_handler->saveTemporary($csv_file,$temporary_stub);
48 |
49 | $this->assertTrue($success);
50 | $this->assertTrue($_SERVER['__temporary.saved']);
51 | }
52 |
53 | public function testGetMaxLength()
54 | {
55 | $csv_line1 = new CsvLine();
56 | $csv_line1->first = 1;
57 | $csv_line1->second = 2;
58 | $csv_line2 = new CsvLine();
59 |
60 | $csv_file = new CsvFile(array($csv_line1, $csv_line2));
61 |
62 | $expected_length = 2;
63 | $length = $this->csv_file_handler->getMaxLength($csv_file);
64 |
65 | $this->assertEquals($expected_length, $length);
66 | }
67 |
68 | /**
69 | * @expectedException Jacopo\LaravelImportExport\Models\Exceptions\NoDataException
70 | */
71 | public function testGetMaxLengthThrowsNoDataException()
72 | {
73 | $this->csv_file_handler->getMaxLength();
74 | }
75 |
76 | /**
77 | * @expectedException Jacopo\LaravelImportExport\Models\Exceptions\UnalignedArrayException
78 | */
79 | public function testUpdateHeadersThrowsUnalignedArrayException()
80 | {
81 | $line1 = new CsvLine();
82 | $line1->setAttribute("0", "first");
83 | $line1->setAttribute("1", "second");
84 | $line2 = new CsvLine();
85 | $line2->setAttribute("0", "first");
86 | $csv_file = new CsvFile( array($line1, $line2) );
87 |
88 | $columns = array(
89 | "first" => 0,
90 | "second" => 1
91 | );
92 |
93 | $table_name = "table";
94 |
95 | $this->csv_file_handler->updateHeaders($csv_file, $columns, $table_name);
96 | }
97 |
98 | public function testUpdateHeadersSuccess()
99 | {
100 | $line1 = new CsvLine();
101 | $line1->setAttribute("0", "first");
102 | $line1->setAttribute("1", "second");
103 | $line2 = new CsvLine();
104 | $line2->setAttribute("0", "first");
105 | $line2->setAttribute("1", "second");
106 | $csv_file = new CsvFile( array($line1, $line2) );
107 |
108 | $columns = array(
109 | 0 => "first",
110 | 1 => "second",
111 | );
112 |
113 | $table_name = "table";
114 |
115 | $this->csv_file_handler->updateHeaders($csv_file, $columns, $table_name);
116 | $csv_file_updated = $this->csv_file_handler->getCsvFile();
117 |
118 | $line_1_expected = new CsvLine();
119 | $line_1_expected->setAttribute("first", "first");
120 | $line_1_expected->setAttribute("second", "second");
121 | $line_1_expected->setConfig( array("table" => "table") );
122 | $line_2_expected = new CsvLine();
123 | $line_2_expected->setAttribute("first", "first");
124 | $line_2_expected->setAttribute("second", "second");
125 | $line_2_expected->setConfig( array("table" => "table") );
126 | $csv_file_expected = new CsvFile( array($line_1_expected, $line_2_expected) );
127 |
128 | $this->assertEquals($csv_file_expected, $csv_file_updated);
129 | }
130 |
131 | public function testGetCsvStringSuccess()
132 | {
133 | $mock_line = m::mock('CsvLine')->makePartial();
134 | $mock_line->shouldReceive(array(
135 | 'getCsvHeader' => "header\n",
136 | 'getCsvString' => "string\n"
137 | ));
138 |
139 | $csv_file = new CsvFile();
140 | $csv_file->append($mock_line);
141 |
142 | $expected_str="header\nstring\n";
143 | $csv_str = $this->csv_file_handler->getCsvString(',', $csv_file);
144 |
145 | $this->assertEquals($expected_str, $csv_str);
146 | }
147 |
148 | /**
149 | * @expectedException Jacopo\LaravelImportExport\Models\Exceptions\NoDataException
150 | */
151 | public function testGetCsvStringThrowsNoDataException()
152 | {
153 | $this->csv_file_handler->getCsvString(",");
154 | }
155 |
156 | protected function mockConfig()
157 | {
158 | $app = m::mock('AppMock');
159 | $app->shouldReceive('instance')->andReturn($app);
160 |
161 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
162 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
163 |
164 | $config->shouldReceive('get')
165 | ->andReturn('import');
166 | }
167 |
168 | protected function mockDbConnection()
169 | {
170 | $app = m::mock('AppMock');
171 | $app->shouldReceive('instance')->andReturn($app);
172 |
173 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
174 | Illuminate\Support\Facades\DB::swap($db = m::mock('DBMock'));
175 |
176 | $mock_connection = m::mock("StdClass");
177 | $mock_connection->shouldReceive('disableQueryLog');
178 |
179 | $db->shouldReceive('connection')
180 | ->andReturn($mock_connection);
181 | }
182 |
183 | }
184 |
185 | class TemporaryModelStub extends Illuminate\Database\Eloquent\Model {
186 | protected static $unguarded = true;
187 |
188 | public function save(array $options = array())
189 | {
190 | $_SERVER['__temporary.saved'] = true;
191 |
192 | return true;
193 | }
194 | }
--------------------------------------------------------------------------------
/tests/unit/TestCsvLine.php:
--------------------------------------------------------------------------------
1 | csv_line = new CsvLine();
10 | }
11 |
12 | public function testgetElementsSuccess()
13 | {
14 | $this->csv_line->name = "name";
15 | $attrs = $this->csv_line->getElements();
16 | $expected = array("name"=>"name");
17 |
18 | $this->assertEquals($expected,$attrs);
19 | }
20 |
21 | public function testgetCsvHeader()
22 | {
23 | $headers = array(
24 | "first" => 1,
25 | "second" => 2
26 | );
27 | $this->csv_line->forceSetAttributes($headers);
28 |
29 | $expected_header = "first,second\n";
30 | $csv_header = $this->csv_line->getCsvHeader(",");
31 |
32 | $this->assertEquals($expected_header,$csv_header);
33 | }
34 |
35 | public function testgetCsvString()
36 | {
37 | $headers = array(
38 | "first" => 1,
39 | "second" => 2
40 | );
41 | $this->csv_line->forceSetAttributes($headers);
42 |
43 | $expected_string = "1,2\n";
44 | $csv_string = $this->csv_line->getCsvString(",");
45 |
46 | $this->assertEquals($expected_string, $csv_string);
47 | }
48 | }
--------------------------------------------------------------------------------
/tests/unit/TestDbFileBuilder.php:
--------------------------------------------------------------------------------
1 | builder = m::mock("Jacopo\LaravelImportExport\Models\ParseCsv\DbFileBuilder")->makePartial();
19 | }
20 |
21 | public function testCreateSelect()
22 | {
23 | $config = array(
24 | "columns" => array(
25 | "db1" => "csv1",
26 | "db2" => "csv2"
27 | )
28 | );
29 | $select = $this->builder->createSelect($config);
30 | $expected_select = array(
31 | "db1 as csv1",
32 | "db2 as csv2",
33 | );
34 | $this->assertEquals($select,$expected_select);
35 | }
36 |
37 | public function testBuildSuccess()
38 | {
39 | $builder = new DbBuilderStub();
40 | $this->mockConfig();
41 |
42 | $expected_line = new CsvLine();
43 | $expected_line->forceSetAttributes(array("csv1"=>"data"));
44 |
45 | $builder->build();
46 | $csv_file = $builder->getCsvFile();
47 |
48 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFile', $csv_file);
49 | foreach($csv_file as $csv_line)
50 | {
51 | $this->assertEquals($expected_line->getAttributes(), $csv_line->getAttributes());
52 | }
53 | }
54 |
55 | protected function mockConfig()
56 | {
57 | $app = m::mock('AppMock');
58 | $app->shouldReceive('instance')->andReturn($app);
59 |
60 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
61 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
62 |
63 | $config->shouldReceive('get')
64 | ->andReturn('import');
65 | }
66 | }
67 |
68 | class DbBuilderStub extends DbFileBuilder
69 | {
70 | protected function getAttributesFromDb()
71 | {
72 | return array( array("csv1" => "data") );
73 | }
74 | }
--------------------------------------------------------------------------------
/tests/unit/TestFile.php:
--------------------------------------------------------------------------------
1 | file_wrapper = new File();
12 | }
13 |
14 | /**
15 | *@expectedException Jacopo\LaravelImportExport\Models\Exceptions\FileNotFoundException
16 | */
17 | public function testOpenFileThrowsFileNotFoundException()
18 | {
19 | $path = "notfound.csv";
20 |
21 | $this->file_wrapper->openFile($path);
22 | }
23 | }
--------------------------------------------------------------------------------
/tests/unit/TestGeneralState.php:
--------------------------------------------------------------------------------
1 | mockSessionMessageBag();
17 | $error_all_mock = m::mock('StdClass');
18 | $error_all_mock->shouldReceive('all')
19 | ->once()
20 | ->andReturn(array('Error1'));
21 |
22 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\GeneralState')->makePartial();
23 | $mock->shouldReceive('getErrors')
24 | ->once()
25 | ->andReturn($error_all_mock);
26 |
27 | $header = $mock->getErrorHeader();
28 | $this->assertSame("Error1
".
29 | "Class not found
", $header);
30 | }
31 |
32 | public function testgetErrorHeaderNotExists()
33 | {
34 | $this->mockSessionEmpty();
35 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\GeneralState')->makePartial();
36 | $mock->shouldReceive('getErrors')
37 | ->once()
38 | ->andReturn(null);
39 |
40 | $header = $mock->getErrorHeader();
41 | $this->assertSame("", $header);
42 | }
43 |
44 | public function testGetNextStateExist()
45 | {
46 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetCsvState')->makePartial();
47 | $mock->shouldReceive('getIsExecuted')
48 | ->andReturn(true);
49 |
50 | $next_state = $mock->getNextState();
51 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetTableState', $next_state);
52 | }
53 |
54 | public function testGetNextStateNotExists()
55 | {
56 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetCsvState')->makePartial();
57 | $mock->shouldReceive('getIsExecuted')
58 | ->andReturn(false);
59 |
60 | $next_state = $mock->getNextState();
61 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetCsvState', $next_state);
62 | }
63 |
64 | /**
65 | *@expectedException Jacopo\LaravelImportExport\Models\Exceptions\ClassNotFoundException
66 | */
67 | public function testGetNextStateThrowsClassNotFoundException()
68 | {
69 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetCsvState')->makePartial();
70 | $mock->shouldReceive(array(
71 | 'getIsExecuted' => true,
72 | 'getNextStateClass' => 'invalid__class___name____'
73 | ));
74 |
75 | $next_state = $mock->getNextState();
76 | }
77 |
78 | public function testAppendErrorAppend()
79 | {
80 | $csv_state = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\GeneralState')->makePartial();
81 |
82 | $error_key = "Error1";
83 | $error_string = "1";
84 |
85 | $csv_state->appendError($error_key, $error_string);
86 |
87 | $this->assertInstanceOf( 'Illuminate\Support\MessageBag' , $csv_state->getErrors() );
88 | $this->assertSame( array("1"), $csv_state->getErrors()->all() );
89 | }
90 |
91 | public function testAppendErrorCreateNew()
92 | {
93 | $csv_state = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\GeneralState')->makePartial();
94 |
95 | $error = array("Error1" => "1");
96 | $csv_state->setErrors(new MessageBag($error));
97 | $csv_state->appendError("Error2", "1");
98 |
99 | $this->assertInstanceOf( 'Illuminate\Support\MessageBag' , $csv_state->getErrors() );
100 | $this->assertSame( array("1","1"), $csv_state->getErrors()->all() );
101 | }
102 |
103 | protected function mockSessionMessageBag()
104 | {
105 | $app = m::mock('AppMock');
106 | $app->shouldReceive('instance')->once()->andReturn($app);
107 |
108 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
109 | Illuminate\Support\Facades\Session::swap($session = m::mock('SessionMock'));
110 |
111 | $session->shouldReceive('get','forget')
112 | ->andReturn(new MessageBag( array("Class" => "Class not found") ), true );
113 | }
114 |
115 | protected function mockSessionEmpty()
116 | {
117 | $app = m::mock('AppMock');
118 | $app->shouldReceive('instance')->once()->andReturn($app);
119 |
120 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
121 | Illuminate\Support\Facades\Session::swap($session = m::mock('SessionMock'));
122 |
123 | $session->shouldReceive('get','forget')
124 | ->andReturn(false,true);
125 | }
126 | }
--------------------------------------------------------------------------------
/tests/unit/TestGetCsvState.php:
--------------------------------------------------------------------------------
1 | state = new GetCsvState;
14 | }
15 |
16 | public function tearDown()
17 | {
18 | m::close();
19 | }
20 |
21 | public function testProcessFormSuccess()
22 | {
23 | $mock_validator = m::mock('Jacopo\LaravelImportExport\Models\ValidatorFormInputModel');
24 | $mock_validator->shouldReceive('validateInput')
25 | ->once()
26 | ->andReturn(true);
27 | $this->mockSessionPut();
28 |
29 | $mock_file = m::mock('StdClass');
30 | $mock_file->shouldReceive(array(
31 | 'getRealPath' => 'path/path',
32 | 'getClientOriginalName' => 'test.csv',
33 | ));
34 |
35 | $form_input = array(
36 | 'separator' => ';',
37 | 'file_csv' => $mock_file,
38 | 'headers' => false,
39 | 'max_lines' => 1,
40 | 'create_table' => true,
41 | );
42 |
43 | $mock_csv_handler = m::mock('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler');
44 | $mock_csv_handler->shouldReceive(array(
45 | 'openFromCsv' => true,
46 | 'saveTemporary' => true,
47 | ));
48 |
49 | $executed = $this->state->processForm($form_input,$mock_validator,$mock_csv_handler);
50 | $this->assertSame(true,$executed);
51 | }
52 |
53 | public function testProcessFormFailsValidation()
54 | {
55 | $mock_file = m::mock('StdClass');
56 | $mock_file->shouldReceive(array(
57 | 'getRealPath' => 'path/path',
58 | 'getClientOriginalName' => 'test.csv',
59 | ));
60 |
61 | $form_input = array(
62 | 'separator' => ';',
63 | 'file_csv' => $mock_file,
64 | 'headers' => false,
65 | );
66 |
67 | $mock_temporary_model = m::mock('Jacopo\LaravelImportExport\Models\TemporaryModel');
68 |
69 | $mock_validator = m::mock('Jacopo\LaravelImportExport\Models\ValidatorFormInputModel');
70 | $mock_validator->shouldReceive('validateInput')
71 | ->once()
72 | ->andReturn(false);
73 |
74 | $executed = $this->state->processForm($form_input,$mock_validator,null);
75 | $this->assertSame(false,$executed);
76 |
77 | }
78 |
79 | protected function mockSessionPut()
80 | {
81 | $app = m::mock('AppMock');
82 | $app->shouldReceive('instance')->once()->andReturn($app);
83 |
84 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
85 | Illuminate\Support\Facades\Session::swap($input = m::mock('SessionMock'));
86 |
87 | $input->shouldReceive('put')->once()->andReturn(true);
88 | }
89 | }
--------------------------------------------------------------------------------
/tests/unit/TestGetTableConfig.php:
--------------------------------------------------------------------------------
1 | state = new GetTableConfig;
17 | }
18 |
19 | public function tearDown()
20 | {
21 | m::close();
22 | }
23 |
24 | public function testProcessFormSuccess()
25 | {
26 | $form_input = array(
27 | "attributes" => '',
28 | 'table_name' => ''
29 | );
30 | $mock_handler = m::mock('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler')
31 | ->shouldReceive(array(
32 | 'openFromDb' => true,
33 | "saveCsvFile" => true,
34 | ))
35 | ->getMock();
36 | $mock_validator = m::mock('StdClass')
37 | ->shouldReceive('validateInput')
38 | ->andReturn(true)
39 | ->getMock();
40 |
41 | $this->mockSessionGetPut();
42 | $success = $this->state->processForm($form_input, $mock_validator, $mock_handler);
43 |
44 | $this->assertTrue($success);
45 | }
46 |
47 | public function testProcessFormFailsValidation()
48 | {
49 | $form_input = array(
50 | "attributes" => '',
51 | 'table_name' => ''
52 | );
53 | $mock_validator = m::mock('StdClass')
54 | ->shouldReceive('validateInput')
55 | ->andReturn(true)
56 | ->getMock();
57 |
58 | $success = $this->state->processForm($form_input, $mock_validator);
59 |
60 | $this->assertFalse($success);
61 | }
62 |
63 | protected function mockSessionGetPut()
64 | {
65 | $app = m::mock('AppMock');
66 | $app->shouldReceive('instance')->once()->andReturn($app);
67 |
68 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
69 | Illuminate\Support\Facades\Session::swap($session = m::mock('ConfigMock'));
70 |
71 | $session->shouldReceive('get','put');
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/tests/unit/TestGetTableName.php:
--------------------------------------------------------------------------------
1 | state = new GetTableName();
15 | }
16 |
17 | public function tearDown()
18 | {
19 | m::close();
20 | }
21 |
22 | public function testFillFormInput()
23 | {
24 | $input_mock = m::mock('Jacopo\LaravelImportExport\Models\InputWrapper');
25 | $input_mock->shouldReceive(
26 | 'get',
27 | 'get',
28 | 'get'
29 | )->andReturn(
30 | 'table_name',
31 | '50',
32 | ','
33 | );
34 | $this->state->fillFormInput($input_mock);
35 | $form_input = $this->state->getFormInput();
36 |
37 | $this->assertEquals('table_name', $form_input["table_name"]);
38 | $this->assertEquals('50', $form_input["max_rows"]);
39 | $this->assertEquals(',', $form_input["separator"]);
40 | }
41 |
42 | public function testGetTableValuesSelect()
43 | {
44 | $expected_tables = array(
45 | "first" => "first",
46 | "second" => "second",
47 | );
48 | $mock_dbm = m::mock('Jacopo\LaravelImportExport\Models\DatabaseSchemaManager');
49 | $mock_dbm->shouldReceive('getTableList')
50 | ->once()
51 | ->andReturn(array("first","second"));
52 | $mock_state = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Export\GetTableName')->makePartial();
53 |
54 | $table_list = $mock_state->getTableValuesSelect($mock_dbm);
55 | $this->assertEquals($expected_tables, $table_list);
56 | }
57 |
58 | public function testGetTableHeader()
59 | {
60 | $mock_cols = m::mock("StdClass")
61 | ->shouldReceive('toArray')
62 | ->andReturn(array("name"=>"name"))
63 | ->getMock();
64 | $array_mock_cols = array($mock_cols);
65 |
66 | $mock_dbm = m::mock('Jacopo\LaravelImportExport\Models\DatabaseSchemaManager');
67 | $mock_dbm->shouldReceive('getTableColumns')
68 | ->once()
69 | ->andReturn($array_mock_cols);
70 |
71 | $mock_state = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Export\GetTableName')->makePartial();
72 | $mock_state->shouldReceive('getFormInput')
73 | ->once()
74 | ->andReturn(array("table_name"=>1));
75 | $expected_columns = array("name");
76 |
77 | $columns = $mock_state->getTableHeader($mock_dbm);
78 | $this->assertEquals($expected_columns,$columns);
79 | }
80 |
81 | public function testProcessFormSuccess()
82 | {
83 | $mock_validator = m::mock('Jacopo\LaravelImportExport\Models\ValidatorFormInputModel');
84 | $mock_validator->shouldReceive('validateInput')
85 | ->once()
86 | ->andReturn(true);
87 | $this->mockSessionPut();
88 |
89 | $form_input = array(
90 | 'table_name' => 'table',
91 | 'max_rows' => '50',
92 | 'separator' => ','
93 | );
94 |
95 | $state_stub = new GetTableNameStub;
96 |
97 | $executed = $state_stub->processForm($form_input,$mock_validator);
98 | $this->assertSame(true,$executed);
99 | }
100 |
101 | public function testProcessFormFails()
102 | {
103 | $mock_validator = m::mock('Jacopo\LaravelImportExport\Models\ValidatorFormInputModel');
104 | $mock_validator->shouldReceive('validateInput')
105 | ->once()
106 | ->andReturn(false);
107 |
108 | $form_input = array(
109 | 'table_name' => 'table',
110 | 'max_rows' => '50',
111 |
112 | );
113 |
114 |
115 | $executed = $this->state->processForm($form_input,$mock_validator);
116 | $this->assertSame(false,$executed);
117 | }
118 |
119 | protected function mockSessionPut()
120 | {
121 | $app = m::mock('AppMock');
122 | $app->shouldReceive('instance')->once()->andReturn($app);
123 |
124 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
125 | Illuminate\Support\Facades\Session::swap($input = m::mock('SessionMock'));
126 |
127 | $input->shouldReceive('put')->once()->andReturn(true);
128 | }
129 |
130 | }
131 |
132 | class GetTableNameStub extends GetTableName
133 | {
134 | protected function getDataTable()
135 | {
136 | return true;
137 | }
138 |
139 | protected function getTableHeader($dbm = null)
140 | {
141 | return array("column1");
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/tests/unit/TestGetTableState.php:
--------------------------------------------------------------------------------
1 | state = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\GetTableState')->makePartial();
15 | }
16 |
17 | public function tearDown()
18 | {
19 | m::close();
20 | }
21 |
22 | public function testFillFormInput()
23 | {
24 | $input_mock = m::mock('Jacopo\LaravelImportExport\Models\InputWrapper');
25 | $input_mock->shouldReceive(//array("get"=>2,"get"=>2,"get"=>2,"get"=>2));
26 | 'get',
27 | 'get',
28 | 'get',
29 | 'get',
30 | 'get',
31 | 'get',
32 | 'get'
33 | )->andReturn(
34 | 'table_name',
35 | '2',
36 | '1',
37 | 'first',
38 | 'string',
39 | 'second',
40 | 'string'
41 | );
42 | $this->state->fillFormInput($input_mock);
43 | $form_input = $this->state->getFormInput();
44 |
45 | $this->assertEquals('table_name', $form_input["table_name"]);
46 | $expected_vals = array(
47 | 0 => 'first',
48 | 1 => 'second'
49 | );
50 | $this->assertEquals($expected_vals, $form_input["columns"]);
51 | $expected_types = array(
52 | 'first' => 'string',
53 | 'second' => 'string',
54 | );
55 | $this->assertEquals($expected_types, $form_input["types"]);
56 | }
57 |
58 | public function testProcessFormSuccess()
59 | {
60 | $mock_validator = m::mock('Jacopo\LaravelImportExport\Models\ValidatorFormInputModel');
61 | $mock_validator->shouldReceive('validateInput')
62 | ->once()
63 | ->andReturn(true);
64 |
65 | $form_input = array(
66 | 'table_name' => 'table',
67 | 'columns' => array(
68 | "first" => 0,
69 | "second" => 1
70 | ),
71 | 'types' => array(),
72 | );
73 |
74 | $mock_csv_handler = m::mock('Jacopo\LaravelImportExport\Models\ParseCsv\CsvFileHandler');
75 | $mock_csv_handler->shouldReceive(array(
76 | 'getTemporary' => new CsvFile(),
77 | 'updateHeaders' => true,
78 | 'saveToDb' => true
79 | ));
80 |
81 | $executed = $this->state->processForm($form_input,$mock_validator,$mock_csv_handler);
82 | $this->assertSame(true,$executed);
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/tests/unit/TestParseCsv.php:
--------------------------------------------------------------------------------
1 | parse_csv = new ParseCsv();
11 | }
12 |
13 | public function tearDown()
14 | {
15 | \Mockery::close();
16 | }
17 |
18 | public function testParseCsvFileSuccess()
19 | {
20 | $csv_line_file = array("test"=>"test");
21 | $mock = \Mockery::mock('Jacopo\LaravelImportExport\Models\ParseCsv\File');
22 | $mock->shouldReceive(array(
23 | 'openFile'=>true,
24 | 'readCsv'=>$csv_line_file));
25 |
26 | $parse_csv = new ParseCsv(array(),$mock);
27 |
28 | $csv_line_array = $parse_csv->parseCsvFile();
29 | $this->assertEquals($csv_line_file, $csv_line_array);
30 |
31 | $mock = \Mockery::mock('Jacopo\LaravelImportExport\Models\ParseCsv\File');
32 | $mock->shouldReceive(array(
33 | 'openFile'=>true,
34 | 'readCsv'=>false,
35 | 'closeFile'=>true));
36 |
37 | $parse_csv = new ParseCsv(array(),$mock);
38 |
39 | $csv_line_array = $parse_csv->parseCsvFile();
40 | $this->assertEquals(false, $csv_line_array);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/tests/unit/TestRuntimeModel.php:
--------------------------------------------------------------------------------
1 | model = new RuntimeModel();
12 | }
13 |
14 | public function testValidConfig()
15 | {
16 | $config = array("timestamps" => true);
17 |
18 | $this->model->setConfig($config);
19 |
20 | $this->assertObjectHasAttribute("timestamps", $this->model);
21 |
22 | }
23 |
24 | public function testForceSetAttributesSuccess()
25 | {
26 | $atts = array(
27 | "first" => 1,
28 | "second" => 2,
29 | );
30 | $this->model->forceSetAttributes($atts);
31 |
32 | $this->assertEquals($atts["first"],$this->model->first);
33 | $this->assertEquals($atts["second"],$this->model->second);
34 | }
35 |
36 | /**
37 | * @expectedException InvalidArgumentException
38 | */
39 | public function testExceptionInvalidConfig()
40 | {
41 |
42 | $config = array("invalid" => "invalid");
43 |
44 | $this->model->setConfig($config);
45 | }
46 |
47 | public function testCanSaveToDbSuccess()
48 | {
49 | $config = array("table"=>"table");
50 |
51 | $this->model->setConfig($config);
52 | // set a string attribute
53 | $this->model->key = 0;
54 | $can_save = $this->model->canSaveToDb();
55 |
56 | $this->assertTrue($can_save);
57 | }
58 |
59 | public function testCanSaveToDbFailsTable()
60 | {
61 | $config = array();
62 |
63 | $this->model->setConfig($config);
64 | // set a string attribute
65 | $this->model->key = 0;
66 | $can_save = $this->model->canSaveToDb();
67 |
68 | $this->assertFalse($can_save);
69 | }
70 |
71 | public function testCanSaveToDbFailsAttributes()
72 | {
73 | $config = array("table"=>"table");
74 |
75 | $this->model->setConfig($config);
76 | $can_save = $this->model->canSaveToDb();
77 |
78 | $this->assertFalse($can_save);
79 | }
80 | }
--------------------------------------------------------------------------------
/tests/unit/TestStateHandler.php:
--------------------------------------------------------------------------------
1 | handler = new StateHandler();
22 | $this->mockSessionExist();
23 |
24 | $this->handler->initializeState();
25 | $current_state = Session::get($this->session_key);
26 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\StateHandling\StateArray', $current_state);
27 | }
28 |
29 | public function testInizializeStateSuccessReset()
30 | {
31 | $mock = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\StateHandler')->makePartial();
32 | $mock->shouldReceive('resetState')
33 | ->once()
34 | ->andReturn(true);
35 |
36 | $this->mockSessionReset();
37 | $mock->initializeState();
38 | }
39 |
40 | public function testResetStateSuccess()
41 | {
42 | $handler_stub = new StateHandlerStubReset;
43 |
44 | $this->mockSessionReset();
45 | $this->mockConfigTableDb();
46 |
47 | $handler_stub->resetState();
48 |
49 | $returned_array_state = $handler_stub->getStateArray();
50 | $this->assertInstanceOf('Jacopo\LaravelImportExport\Models\StateHandling\StateArray', $returned_array_state);
51 | $current_state = $handler_stub->getCurrent();
52 | $this->assertInstanceOf('StdClass', $current_state);
53 |
54 | }
55 |
56 | public function testReplaceCurrentSuccess()
57 | {
58 | $mock_state_array = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\StateArray');
59 | $mock_state_array->shouldReceive('offsetSet')
60 | ->once()
61 | ->andReturn(true);
62 |
63 | $mock_handler = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\StateHandler')->makePartial();
64 | $mock_handler->shouldReceive(array(
65 | "getLastKey" => 0,
66 | "getStateArray" => $mock_state_array,
67 | ));
68 |
69 | $mock_handler->replaceCurrent( array() );
70 | }
71 |
72 | /**
73 | *@expectedException Jacopo\LaravelImportExport\Models\Exceptions\NoDataException
74 | */
75 | public function testReplaceCurrentThrowsNoDataException()
76 | {
77 | $mock_handler = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\StateHandler')->makePartial();
78 | $mock_handler->shouldReceive('getLastKey')
79 | ->once()
80 | ->andReturn(-1);
81 | $mock_handler->replaceCurrent( array() );
82 | }
83 |
84 | public function testProcessFormSuccess()
85 | {
86 | $handler = new StateHandler();
87 | $mock_get_csv_s = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\GeneralState')->makePartial();
88 | $mock_get_csv_s->shouldReceive('processForm')
89 | ->once()
90 | ->andReturn(true);
91 | $this->mockSessionPut();
92 |
93 | $handler->setStateArray( new StateArray( array( $mock_get_csv_s ) ) );
94 |
95 | $handler->processForm();
96 | }
97 |
98 | public function textGetLastStateThrowsNoDataException()
99 | {
100 | $mock_handler = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\StateHandler')->makePartial();
101 | $mock_handler->shouldReceive('getLastKey')
102 | ->once()
103 | ->andReturn(-1);
104 |
105 | $mock_handler->getLastState();
106 | }
107 |
108 | public function textGetLastStateSuccess()
109 | {
110 | $state_array = array("test array");
111 |
112 | $mock_handler = m::mock('Jacopo\LaravelImportExport\Models\StateHandling\Import\StateHandler')->makePartial();
113 | $mock_handler->shouldReceive(array(
114 | "getLastKey" => 0,
115 | "getStateArray" => $state_array,
116 | ));
117 |
118 | $res = $mock_handler->getLastState();
119 | $this->assertEquals($state_array, $mock_handler->getStateArray());
120 | }
121 |
122 | protected function mockSessionExist()
123 | {
124 | Illuminate\Support\Facades\Session::swap($session = m::mock('SessionMock'));
125 | $session->shouldReceive(array(
126 | 'has'=>true,
127 | 'get' => new StateArray()
128 | ));
129 | }
130 |
131 | protected function mockSessionReset()
132 | {
133 | Illuminate\Support\Facades\Session::swap($session = m::mock('SessionMock'));
134 | $session->shouldReceive(array(
135 | 'has'=>false,
136 | 'put'=>true,
137 | ));
138 | }
139 |
140 | protected function mockSessionPut()
141 | {
142 | Illuminate\Support\Facades\Session::swap($session = m::mock('SessionMock'));
143 | $session->shouldReceive(array(
144 | 'put'=> true
145 | ));
146 | }
147 |
148 | protected function mockDbTruncate()
149 | {
150 | $mock_truncate = m::mock("StdClass")
151 | ->shouldReceive("truncate")
152 | ->once()
153 | ->andReturn(true)
154 | ->getMock();
155 |
156 | $mock_table = m::mock('StdClass')
157 | ->shouldReceive('table')
158 | ->andReturn($mock_truncate)
159 | ->getMock();
160 |
161 | $app = m::mock('AppMock');
162 | $app->shouldReceive('instance')->andReturn($app);
163 |
164 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
165 | Illuminate\Support\Facades\DB::swap($db = m::mock('DBMock'));
166 | $db->shouldReceive(array(
167 | 'connection'=> $mock_table
168 | ));
169 | }
170 |
171 | protected function mockConfigTable()
172 | {
173 | $app = m::mock('AppMock');
174 | $app->shouldReceive('instance')->andReturn($app);
175 |
176 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
177 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
178 |
179 | $config->shouldReceive('get')->once()->with('laravel-import-export::baseconf.table_prefix')->andReturn(true);
180 | }
181 |
182 | protected function mockConfigTableDb()
183 | {
184 | $app = m::mock('AppMock');
185 | $app->shouldReceive('instance')->andReturn($app);
186 |
187 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
188 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
189 |
190 | $config->shouldReceive('get','get')
191 | ->andReturn(true,'import');
192 | }
193 |
194 | protected function mockConfig()
195 | {
196 | $app = m::mock('AppMock');
197 | $app->shouldReceive('instance')->andReturn($app);
198 |
199 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
200 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
201 |
202 | $config->shouldReceive('get')->once()->with('laravel-import-export::baseconf.session_import_key','import_state')->andReturn($this->session_key);
203 | }
204 |
205 | }
206 |
207 | class StateHandlerStubReset extends StateHandler
208 | {
209 | protected $initial_state = 'StdClass';
210 | }
--------------------------------------------------------------------------------
/tests/unit/TestTemporaryModel.php:
--------------------------------------------------------------------------------
1 | mockConfig();
11 | }
12 |
13 | public function tearDown()
14 | {
15 | m::close();
16 | }
17 |
18 | public function testCanIstantiateModel()
19 | {
20 | $model = new TemporaryModel();
21 | }
22 |
23 | protected function mockConfig()
24 | {
25 | $app = m::mock('AppMock');
26 | $app->shouldReceive('instance')->once()->andReturn($app);
27 |
28 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
29 | Illuminate\Support\Facades\Config::swap($config = m::mock('ConfigMock'));
30 |
31 | $config->shouldReceive('get','get')
32 | ->andReturn('_import_export_temporary_table','import');
33 | }
34 | }
--------------------------------------------------------------------------------
/tests/unit/TestValidatorFormInputModel.php:
--------------------------------------------------------------------------------
1 | shouldReceive(array(
17 | 'getFormInput' => $uploaded_file_mock,
18 | 'getRules' => $rules,
19 | 'setErrors' => true,
20 | ));
21 | $this->import_state_mock = $import_state_mock;
22 | }
23 |
24 | public function tearDown()
25 | {
26 | m::close();
27 | }
28 |
29 | public function testValidateInputSuccess()
30 | {
31 | $this->mockValidatorSuccess();
32 | $validator = new ValidatorFormInputModel($this->import_state_mock);
33 | $success = $validator->validateInput();
34 |
35 | $this->assertTrue($success);
36 | }
37 |
38 | public function testValidateInputFail()
39 | {
40 | $this->mockValidatorFail();
41 | $validator = new ValidatorFormInputModel($this->import_state_mock);
42 | $success = $validator->validateInput();
43 |
44 | $this->assertFalse($success);
45 | }
46 |
47 | protected function mockValidatorSuccess()
48 | {
49 | $app = m::mock('AppMock');
50 | $app->shouldReceive('instance')->once()->andReturn($app);
51 |
52 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
53 | Illuminate\Support\Facades\Validator::swap($validator = m::mock('validatorMock'));
54 |
55 | $mock_success = m::mock('StdClass');
56 | $mock_success->shouldReceive(array(
57 | 'fails' => false,
58 | ));
59 |
60 | $validator->shouldReceive('make')
61 | ->with( m::type('Symfony\Component\HttpFoundation\File\UploadedFile') , m::type('array') )
62 | ->once()
63 | ->andReturn($mock_success);
64 | }
65 |
66 | protected function mockValidatorFail()
67 | {
68 | $app = m::mock('AppMock');
69 | $app->shouldReceive('instance')->once()->andReturn($app);
70 |
71 | Illuminate\Support\Facades\Facade::setFacadeApplication($app);
72 | Illuminate\Support\Facades\Validator::swap($validator = m::mock('validatorMock'));
73 |
74 | $mock_success = m::mock('StdClass');
75 | $mock_success->shouldReceive(array(
76 | 'fails' => true,
77 | 'messages' => 'ok',
78 | ));
79 |
80 | $validator->shouldReceive('make')
81 | ->with( m::type('Symfony\Component\HttpFoundation\File\UploadedFile') , m::type('array') )
82 | ->once()
83 | ->andReturn($mock_success);
84 | }
85 | }
--------------------------------------------------------------------------------