├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── README_PT.md
├── composer.json
├── composer.lock
├── config
└── report.php
├── docker-compose.yml
├── examples
├── report-boleto.pdf
├── report1-html.php
├── report1-image.php
├── report1-pdf.php
└── report1.html
├── phpunit.xml
├── src
└── Report
│ ├── Contracts
│ ├── ExporterInterface.php
│ └── ReportInterface.php
│ ├── Exporters
│ ├── AbstractExporter.php
│ ├── AbstractPhantomExporter.php
│ ├── HtmlExporter.php
│ ├── ImageExporter.php
│ └── PdfExporter.php
│ ├── Laravel
│ └── ReportServiceProvider.php
│ └── Report.php
└── tests
└── Report
├── Exporters
├── AbstractExporterTest.php
├── AbstractPhantomExporterTest.php
├── HtmlExporterTest.php
├── ImageExporterTest.php
└── PdfExporterTest.php
└── ReportTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /node_modules
3 | /docs
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | sudo: required
3 | php:
4 | - '5.6'
5 | - '7.0'
6 | - nightly
7 |
8 | before_script:
9 | - travis_retry composer self-update
10 | - travis_retry composer install --prefer-source --no-interaction --dev
11 |
12 | #notifications:
13 | # slack: chanel:token
14 |
15 | addons:
16 | code_climate:
17 | repo_token: c70199b1102996ce7de86c5ce4c89a4f308ca496ebb266deb21f41e7f4be75cb
18 |
19 | script:
20 | - "phpunit --process-isolation --coverage-clover build/logs/clover.xml"
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Fireguard Soluções em Tecnologia Ltda
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fireguard Report
2 |
3 | [](https://travis-ci.org/fireguard/report)
4 | [](https://packagist.org/packages/fireguard/report)
5 | [](https://packagist.org/packages/fireguard/report)
6 | [](https://packagist.org/packages/fireguard/report)
7 | [](https://packagist.org/packages/fireguard/report)
8 | [](https://codeclimate.com/github/fireguard/report)
9 |
10 | [](https://insight.sensiolabs.com/projects/f378db1b-5a6a-4b13-b49d-ff28a9c29a62)
11 |
12 | **Other languages for this documentation: [PORTUGUÊS](README_PT.md)**
13 |
14 | The **Fireguard Report** is a report management package in PHP that aims to help you export information in a variety of
15 | formats, such as HTML, PDF and IMAGE, using a unique, integrated and simple interface.
16 |
17 |
18 | # Summary
19 |
20 | - [Installation](#install)
21 | - [Installing and Updating PhantomJs](#install-phantom)
22 | - [How to use](#use)
23 | - [Generating our first report](#first-report)
24 | - [Header and Footer](#footer-header)
25 | - [Exporters](#exporters)
26 | - [Methods available in all Exports](#methods-exports)
27 | - [HtmlExporter](#html-exporter)
28 | - [PdfExporter](#pdf-exporter)
29 | - [ImageExporter](#image-exporter)
30 |
31 | - [Laravel](#laravel)
32 | - [Registering Service Provider](#laravel-register-provider)
33 | - [Publishing the configuration file](#laravel-publish-config)
34 | - [Examples of use with Laravel (Dependency Injection)](#laravel-use)
35 | - [Other usage examples](#examples)
36 | - [Generating an HTML report](#use-link-html)
37 | - [Generating an PDF report](#use-link-pdf)
38 | - [Generating an IMAGE report](#use-link-image)
39 | - [Sample ticket generated with this package](#use-link-boleto)
40 |
41 |
42 | # Installation
43 |
44 | The FireGuard Report can be installed through the composer.
45 |
46 | In order for the package to be automatically added to your composer.json file, run the following command:
47 |
48 | ```bash
49 | composer require fireguard/report
50 | ```
51 |
52 | Or if you prefer, add the following snippet manually:
53 |
54 | ```
55 | {
56 | "require": {
57 | ...
58 | "fireguard/report": "^0.1"
59 | }
60 | }
61 | ```
62 |
63 | ## Installing and Updating PhantomJs
64 |
65 | To generate the PDF files and Images, this package is used by PhantomJs. For installation and update, we suggest two
66 | options:
67 |
68 | **1st Option:** Add the lines below in the composer.json file, so the installation and update process will occur every
69 | time you execute the "composer install" or "composer update" commands.
70 |
71 | ```
72 | "scripts": {
73 | "post-install-cmd": [
74 | "PhantomInstaller\\Installer::installPhantomJS"
75 | ],
76 | "post-update-cmd": [
77 | "PhantomInstaller\\Installer::installPhantomJS"
78 | ]
79 | }
80 | ```
81 |
82 | **2st Option:** If you do not want to always keep the latest PhantomJS version, one possibility is to add a new script
83 | in composer.json as shown below:
84 |
85 | ```
86 | "scripts": {
87 | "update-phantomjs": [
88 | "PhantomInstaller\\Installer::installPhantomJS"
89 | ]
90 | }
91 | ```
92 |
93 | And run whenever you want to update the version of the executable the following command ``composer run-script update-phantomjs``
94 |
95 | If you choose this option, you must run at least the first time for it to be installed.
96 |
97 |
98 | # How to use
99 |
100 | ## Generating our first report
101 |
102 | The use of this package is very simple, we will need two objects to generate a final file, the first one is Report,
103 | with it we define the effective content of the report, the second is the Exporter, which receives a Report and is
104 | responsible for handling the information and export to a final file.
105 |
106 | Here is a simple example to generate a file:
107 |
108 | ```php
109 | $report = new \Fireguard\Report\Report('Report Title
');
110 | $exporter = new \Fireguard\Report\Exporters\PdfExporter();
111 | $file = $exporter->generate($report);
112 | ```
113 |
114 | So at the end of the execution, in the variable **$file** we will have the actual path to the generated file.
115 |
116 | ## Header and Footer
117 |
118 | For header and footer HTML, two variables are available in exporters that use paging, such as PdfExporter, **numPage**,
119 | and **totalPages**, which contains the current page and the total pages of the page respectively.
120 | To access them, you must enclose them by "@{{ }}", so the contents of the content will be automatically updated.
121 | Below is a simple example that will use the header and footer;
122 |
123 | ```php
124 | $html = file_get_contents('report.html');
125 |
126 | $header = '';
127 | $header.= ' THE MANAGEMENT REPORT TITLE';
128 | $header.= '
';
129 |
130 | $footer = '';
131 | $footer.= ' Page @{{ numPage }} of @{{ totalPages }}';
132 | $footer.= '
';
133 |
134 | $report = new \Fireguard\Report\Report($html, $header, $footer);
135 | $exporter = new \Fireguard\Report\Exporters\PdfExporter('.', 'report1-to-pdf');
136 | $file = $exporter->generate($report);
137 |
138 | ```
139 | With this example above we will find in the variable **$file** the path to the generated PDF file;
140 |
141 | ## Exporters
142 |
143 | As we saw in the previous examples, the export of the report requires an Exporter class. An Exporter is a specialized
144 | class that implements an ExporterInterface interface and is responsible for catching a Report object and transforming it
145 | into a finalized file.
146 |
147 | At this point we have included in the package three Exporters, one for HTML, one for PDF and one for Images, it is
148 | possible that in future new Exporters will be available, we also encourage you to develop new Exporters and, if
149 | possible, contribute to the project.
150 |
151 | ### Methods available in all Exports
152 |
153 | ``getPath()``: Returns the location where the generated file will be saved;
154 |
155 | ``setPath($path, $mode = 0777)``: Sets the location where the file should be saved;
156 |
157 | ``getFileName()``: Returns the name of the file to save;
158 |
159 | ``setFileName($fileName)``: Sets the name of the file to be saved;
160 |
161 | ``getFullPath()``: Returns the complete path with the name of the file to be generated;
162 |
163 | ``compress($buffer)``: Returns a compressed string with no comments or line breaks;
164 |
165 | ``configure(array $config)``: Sets the settings to apply to the current report;
166 |
167 | ``generate(ReportInterface $report)``: Renders the report and returns a path to the generated file;
168 |
169 | ``response(ReportInterface $report, $forceDownload)``: Renders the report and returns an instance of the Symfony\Component\HttpFoundation\Response;
170 |
171 | Example of use with a fluent interface:
172 |
173 | ```php
174 | $report = new \Fireguard\Report\Report('Report Title
');
175 | $exporter = new \Fireguard\Report\Exporters\PdfExporter();
176 | // Example returning an HTTP response
177 | $exporterGenerates report
178 | ->setPath('.') // Sets the save to the local folder
179 | ->setFileName('report.pdf') // Define as 'report.pdf' the name of the file to be generated
180 | ->configure(['footer' => ['height' => '30px']) // Set the footer size to 30px
181 | ->response($report) // Create an HTTP response
182 | ->send(); // Returns the response to the user
183 |
184 | // Example generating a local file
185 | $file = $exporter
186 | ->setPath('.') // Sets the save to the local folder
187 | ->setFileName('report.pdf') // Define as 'report.pdf' the name of the file to be generated
188 | ->configure(['footer' => ['height' => '30px']) // Set the footer size to 30px
189 | ->generate($report); // Generates report
190 |
191 | ```
192 |
193 | ### HtmlExport
194 |
195 | For exporting files in **HTML** format, in addition to the standard methods, some others are available, below all are
196 | listed with a brief description of their function:
197 |
198 | ``saveFile($content)``: Saves the HTML file and returns the full path to the generated file;
199 |
200 | ### PdfExport
201 |
202 | For exporting files in **PDF** format, in addition to the standard methods, some others are available, below all are
203 | listed with a brief description of their function:
204 |
205 | ``getFormat()``: Returns the defined paper size;
206 |
207 | ``setFormat($format)``: Sets a paper size to be exported. (Valid Formats: 'A4', 'A3', 'Letter')
208 |
209 | ``getOrientation()``: Returns the orientation of the defined paper;
210 |
211 | ``setOrientation($orientation)``: Sets the orientation of the paper to be exported. (Valid Orientations: 'landscape', 'portrait')
212 |
213 | ``getMargin()``: Returns the defined paper margin;
214 |
215 | ``setMargin($margin)``: Sets the paper margin to be exported;
216 |
217 | ``getBinaryPath()``: Returns the path to the PhantomJS binary in the application;
218 |
219 | ``setBinaryPath($binaryPath)``: Sets the path to the PhantomJS binary file in the application;
220 |
221 | ``getCommandOptions()``: Returns the parameters to be executed with the PhantomJS for export;
222 |
223 | ``setCommandOptions(array $options)``: Sets the parameters to be executed with the PhantomJS for export;
224 |
225 | ``addCommandOption($option, $value)``: Adds a new parameter to run with PhantomJS for export;
226 |
227 | ``getHeaderHeight()``: Returns the size of the header defined;
228 |
229 | ``getFooterHeight()``: Returns the size of the footer defined;
230 |
231 | ### ImageExport
232 |
233 | For exporting files in **IMAGE** format, in addition to the standard methods, some others are available, below all are
234 | listed with a brief description of their function:
235 |
236 | ``getFormat()``: Returns the defined paper size;
237 |
238 | ``setFormat($format)``: Sets a paper size to be exported. (Valid Formats: 'A4', 'A3', 'Letter')
239 |
240 | ``getOrientation()``: Returns the orientation of the defined paper;
241 |
242 | ``setOrientation($orientation)``: Sets the orientation of the paper to be exported. (Valid Orientations: 'landscape', 'portrait')
243 |
244 | ``getMargin()``: Returns the defined paper margin;
245 |
246 | ``setMargin($margin)``: Sets the paper margin to be exported;
247 |
248 | ``getBinaryPath()``: Returns the path to the PhantomJS binary in the application;
249 |
250 | ``setBinaryPath($binaryPath)``: Sets the path to the PhantomJS binary file in the application;
251 |
252 | ``getCommandOptions()``: Returns the parameters to be executed with the PhantomJS for export;
253 |
254 | ``setCommandOptions(array $options)``: Sets the parameters to be executed with the PhantomJS for export;
255 |
256 | ``addCommandOption($option, $value)``: Adds a new parameter to run with PhantomJS for export;
257 |
258 | ``getHeaderHeight()``: Returns the size of the header defined;
259 |
260 | ``getFooterHeight()``: Returns the size of the footer defined;
261 |
262 |
263 | # Laravel
264 |
265 | The steps described below are optional and can only make it easier for those who want to use this package with Laravel 5.
266 |
267 | ## Registering Service Provider
268 |
269 | In the ``config\app.php`` configuration file, register above the providers of your application as follows:
270 |
271 | ```
272 | 'providers' => [
273 | Fireguard\Report\Laravel\ReportServiceProvider::class,
274 | ...
275 | ]
276 | ```
277 |
278 | ## Publishing the configuration file
279 |
280 | To publish the configuration file you must use the following command:
281 | ```
282 | php artisan vendor:publish --provider="Fireguard\Report\Laravel\ReportServiceProvider"
283 | ```
284 |
285 | ## Examples of use with Laravel (Dependency Injection)
286 |
287 | With the registration of the service provider, you can now use the dependency injection of Laravel to solve the
288 | exporters, already bringing them ready and configured with the application configuration file.
289 |
290 | For dependency injection four classes are available, one interface and three concrete, the default interface is solved
291 | for the concrete PdfExporter class, which can be changed in the ``default-exporter`` parameter of the configuration
292 | file ``report.php`` generated in the integration. See below some examples of use.
293 |
294 | ### Exporter Interface
295 |
296 | ```php
297 | public function index (\Fireguard\Report\Exporters\ExporterInterface $exporter)
298 | {
299 | $html = view()->make('welcome')->render();
300 |
301 | // Option 1
302 | return $exporter
303 | ->response(new Report($html))
304 | ->send();
305 |
306 | // Option 2
307 | $file = $exporter->generate(new Report($html));
308 | $headers = [
309 | 'Content-type' => mime_content_type($file),
310 | 'Content-Transfer-Encoding' => 'binary',
311 | 'Content-Length' => filesize($file),
312 | 'Accept-Ranges' => 'bytes'
313 | ];
314 | // If you want to directly display the file
315 | return response()->make(file_get_contents($file), 200, $headers);
316 | // If you want to force download
317 | // return response()->download($file, 'report.pdf', $headers);
318 | }
319 | ```
320 |
321 | ### HtmlExporter Class
322 |
323 | ```php
324 | public function index (\Fireguard\Report\Exporters\HtmlExporter $exporter)
325 | {
326 | $html = view()->make('welcome')->render();
327 | // Option 1
328 | return $exporter
329 | ->response(new Report($html))
330 | ->send();
331 |
332 |
333 | // Option 2
334 | $file = $exporter->generate(new Report($html));
335 | // If you want to directly display the file
336 | // return response()->make(file_get_contents($file), 200);
337 | // If you want to force download
338 | return response()->download($file, 'report.html', []);
339 | }
340 | ```
341 |
342 | ### PdfExporter Class
343 |
344 | ```php
345 | public function index (\Fireguard\Report\Exporters\PdfExporter $exporter)
346 | {
347 | $html = view()->make('welcome')->render();
348 | // Option 1
349 | return $exporter
350 | ->response(new Report($html))
351 | ->send();
352 |
353 |
354 | // Option 2
355 | $file = $exporter->generate(new Report($html));
356 | $headers = [
357 | 'Content-type' => 'application/pdf',
358 | 'Content-Transfer-Encoding' => 'binary',
359 | 'Content-Length' => filesize($file),
360 | 'Accept-Ranges' => 'bytes'
361 | ];
362 | // If you want to directly display the file
363 | return response()->make(file_get_contents($file), 200, $headers);
364 | // If you want to force download
365 | // return response()->download($file, 'report.pdf', $headers);
366 | }
367 | ```
368 |
369 | ### ImageExporter Class
370 |
371 | ```php
372 | public function index (\Fireguard\Report\Exporters\ImageExporter $exporter)
373 | {
374 | $html = view()->make('welcome')->render();
375 |
376 | // Option 1
377 | return $exporter
378 | ->response(new Report($html))
379 | ->send();
380 |
381 |
382 | // Option 2
383 | $file = $exporter->generate(new Report($html));
384 | $headers = [
385 | 'Content-type' => 'image/jpg',
386 | 'Content-Length' => filesize($file),
387 | ];
388 | // If you want to directly display the file
389 | return response()->make(file_get_contents($file), 200, $headers);
390 | // If you want to force download
391 | // return response()->download($file, 'report.jpg', $headers);
392 | }
393 | ```
394 |
395 | # Other usage examples
396 |
397 | Generating an HTML report
398 | Generating an PDF report
399 | Generating an IMAGE report
400 | Sample ticket generated with this package
401 |
402 |
403 | Created by Fireguard Sistemas http://fireguard.com.br
404 |
--------------------------------------------------------------------------------
/README_PT.md:
--------------------------------------------------------------------------------
1 | # Fireguard Report
2 |
3 | [](https://travis-ci.org/fireguard/report)
4 | [](https://packagist.org/packages/fireguard/report)
5 | [](https://packagist.org/packages/fireguard/report)
6 | [](https://packagist.org/packages/fireguard/report)
7 | [](https://packagist.org/packages/fireguard/report)
8 | [](https://codeclimate.com/github/fireguard/report)
9 |
10 | **Other languages for this documentation: [ENGLISH](README.md)**
11 |
12 | O **Fireguard Report** é um pacote para gestão de relatórios em PHP que tem o intuito de auxiliar na exportação
13 | de informações em diversos formatos, como HTML, PDF e IMAGEM, usando-se para isso de uma interface única, integrada e simples.
14 |
15 |
16 | # Sumário
17 |
18 | - [Instalação](#install)
19 | - [Instalação e Atualização do PhantomJs](#install-phantom)
20 | - [Como utilizar](#use)
21 | - [Gerando nosso primeiro relatório](#first-report)
22 | - [Cabeçalho e Rodapé](#footer-header)
23 | - [Exporters](#exporters)
24 | - [Métodos disponíveis em todos os Exports](#methods-exports)
25 | - [HtmlExporter](#html-exporter)
26 | - [PdfExporter](#pdf-exporter)
27 | - [ImageExporter](#image-exporter)
28 |
29 | - [Laravel](#laravel)
30 | - [Registrando Service Provider](#laravel-register-provider)
31 | - [Publicando o arquivo de configuração](#laravel-publish-config)
32 | - [Exemplos de uso com Laravel (Dependency Injection)](#laravel-use)
33 | - [Outros exemplos de uso](#examples)
34 | - [Gerando um relatório em HTML](#use-link-html)
35 | - [Gerando um relatório em PDF](#use-link-pdf)
36 | - [Gerando um relatório em Imagem](#use-link-image)
37 | - [Boleto de exemplo gerado com este package](#use-link-boleto)
38 |
39 |
40 | # Instalação
41 |
42 | O Fireguard Report pode ser instalado através do composer.
43 |
44 | Para que o package seja adicionado automaticamente ao seu arquivo composer.json execute o seguinte comando:
45 |
46 | ```bash
47 | composer require fireguard/report
48 | ```
49 |
50 | ou se preferir, adicione o seguinte trecho manualmente:
51 |
52 | ```
53 | {
54 | "require": {
55 | ...
56 | "fireguard/report": "^0.1"
57 | }
58 | }
59 | ```
60 |
61 | ## Instalação e Atualização do PhantomJs
62 |
63 | Para gerar os arquivos PDF e Imagens, este pacote utiliza-se do PhantomJs. Para a instalação e atualização do mesmo, sugerimos
64 | duas opções:
65 |
66 | **1ª Opção:** Adicionar as linhas abaixo no arquivo composer.json, dessa forma o processo de instalação e atualização
67 | acontecerá sempre que executar os comandos "composer install" ou "composer update".
68 |
69 | ```
70 | "scripts": {
71 | "post-install-cmd": [
72 | "PhantomInstaller\\Installer::installPhantomJS"
73 | ],
74 | "post-update-cmd": [
75 | "PhantomInstaller\\Installer::installPhantomJS"
76 | ]
77 | }
78 | ```
79 |
80 | **2ª Opção:** Caso não deseje manter sempre na última versão PhantomJS, uma possibilidade é acrescentar um novo script
81 | no composer.json como demonstrado abaixo:
82 |
83 | ```
84 | "scripts": {
85 | "update-phantomjs": [
86 | "PhantomInstaller\\Installer::installPhantomJS"
87 | ]
88 | }
89 | ```
90 |
91 | E executar sempre que quiser atualizar a versão do executável o seguinte comando ``composer run-script update-phantomjs``
92 |
93 | Caso opte por essa opção, deverá executar ao menos a primeira vez para que o mesmo seja instalado.
94 |
95 |
96 | # Como utilizar
97 |
98 | ## Gerando nosso primeiro relatório
99 |
100 | A utilização desse pacote é bastante simples, precisaremos de dois objetos para gerarmos um arquivo final, o primeiro é
101 | Report, com ele definimos o conteúdo efetivo do relatório, o segundo é o Exporter, que recebe um Report e é responsável
102 | por tratar a informação e exportar para um arquivo final.
103 |
104 | Abaixo um exemplo simples para gerar um arquivo:
105 |
106 | ```php
107 | $report = new \Fireguard\Report\Report('Report Title
');
108 | $exporter = new \Fireguard\Report\Exporters\PdfExporter();
109 | $file = $exporter->generate($report);
110 | ```
111 |
112 | Assim ao término da execução, na variável **$file** teremos o caminho real para o arquivo gerado.
113 |
114 | ## Cabeçalho e Rodapé
115 |
116 | Para o HTML do cabeçalho e rodapé, duas variáveis estão disponíveis em exporters que usam paginação, como é o caso do
117 | PdfExporter, o **numPage** e o **totalPages**, que contém a página atual e o total de páginas do relatório respectivamente.
118 | Para acessa-las deve-se envolver as mesmas por "@{{ }}", assim será o conteúdo da mesma atualizado automaticamente.
119 | Abaixo um exemplo simples que irá se utilizar do cabeçalho e rodapé;
120 |
121 | ```php
122 | $html = file_get_contents('report.html');
123 |
124 | $header = '';
125 | $header.= ' THE MANAGEMENT REPORT TITLE';
126 | $header.= '
';
127 |
128 | $footer = '';
129 | $footer.= ' Page @{{ numPage }} of @{{ totalPages }}';
130 | $footer.= '
';
131 |
132 | $report = new \Fireguard\Report\Report($html, $header, $footer);
133 | $exporter = new \Fireguard\Report\Exporters\PdfExporter('.', 'report1-to-pdf');
134 | $file = $exporter->generate($report);
135 |
136 | ```
137 | Com esse exemplo acima encontraremos na variável **$file** o caminho para o arquivo PDF gerado;
138 |
139 | ## Exporters
140 |
141 | Como vimos nos exemplos anteriores, para a exportação do relatório é necessário uma classe Exporter. Um Exporter é na
142 | verdade uma classe especializada, que implementa uma interface ExporterInterface e que é responsável por pegar um objeto
143 | Report e o transformar em um arquivo finalizado.
144 |
145 | Nesse momento incluímos no pacote três Exporters, um para HTML, um para PDF e um para Imagens, é possível que
146 | futuramente novos Exporters estejam disponíveis, inclusive incentivamos que desenvolvam novos Exporters, e se possível,
147 | contribuam com o projeto, assim disponibilizamos para todos um leque maior de possibilidades.
148 |
149 | ### Métodos disponíveis em todos os Exports
150 |
151 | ``getPath()``: Retorna o local onde o arquivo gerado será salvo;
152 |
153 | ``setPath($path, $mode = 0777)``: Define o local onde o arquivo deve ser salvo;
154 |
155 | ``getFileName()``: Retorna o nome do arquivo a ser salvo;
156 |
157 | ``setFileName($fileName)``: Define o nome do arquivo a ser salvo;
158 |
159 | ``getFullPath()``: Retorna o caminho completo com o nome do arquivo a ser gerado;
160 |
161 | ``compress($buffer)``: Retorna um string comprimida sem comentários ou quebra de linhas;
162 |
163 | ``configure(array $config)``: Define as configurações a serem aplicadas ao relatório atual;
164 |
165 | ``generate(ReportInterface $report)``: Processa o relatório e retorna um caminho para o arquivo gerado;
166 |
167 | ``response(ReportInterface $report, $forceDownload)``: Processa o relatório e retorna uma instância do Symfony\Component\HttpFoundation\Response ;
168 |
169 | Exemplo de uso com interface fluente:
170 |
171 | ```php
172 | $report = new \Fireguard\Report\Report('Report Title
');
173 | $exporter = new \Fireguard\Report\Exporters\PdfExporter();
174 | // Exemplo retornando uma resposta HTTP
175 | $exporter
176 | ->setPath('.') // Define o salvamento para a pasta local
177 | ->setFileName('report.pdf') // Define como 'report.pdf' o nome do arquivo a ser gerado
178 | ->configure(['footer' => ['height' => '30px']) // Configura em 30px o tamanho do rodapé
179 | ->response($report) // Cria um resposta HTTP
180 | ->send(); // Retorna a resposta ao usuário
181 |
182 | // Exemplo gerando um arquivo local
183 | $file = $exporter
184 | ->setPath('.') // Define o salvamento para a pasta local
185 | ->setFileName('report.pdf') // Define como 'report.pdf' o nome do arquivo a ser gerado
186 | ->configure(['footer' => ['height' => '30px']) // Configura em 30px o tamanho do rodapé
187 | ->generate($report); // Gera o relatório
188 |
189 | ```
190 |
191 | ### HtmlExport
192 |
193 | Para a exportação de arquivos no formato de **HTML**, além dos métodos padrões, alguns outros estão disponíveis, abaixo
194 | todos são listados com uma breve descrição de sua função:
195 |
196 | ``saveFile($content)``: Salva o arquivo HTML e retorna o caminho completo para o arquivo gerado;
197 |
198 | ### PdfExport
199 |
200 | Para a exportação de arquivos no formato de **PDF**, além dos métodos padrões, alguns outros estão disponíveis, abaixo
201 | todos são listados com uma breve descrição de sua função:
202 |
203 | ``getFormat()``: Retorna o formato do papel definido;
204 |
205 | ``setFormat($format)``: Define um formato de papel a ser exportado. (Formatos válidos: 'A4', 'A3', 'Letter')
206 |
207 | ``getOrientation()``: Retorna a orientação do papel definida;
208 |
209 | ``setOrientation($orientation)``: Define a orientação do papel a ser exportado. (Orientações válidas: 'landscape', 'portrait')
210 |
211 | ``getMargin()``: Retorna a margem do papel definida;
212 |
213 | ``setMargin($margin)``: Define a margem do papel a ser exportado;
214 |
215 | ``getBinaryPath()``: Retorna o caminho para o binário do PhantomJS na aplicação;
216 |
217 | ``setBinaryPath($binaryPath)``: Define o caminho para o arquivo binário do PhantomJS na aplicação;
218 |
219 | ``getCommandOptions()``: Retorna os parâmetros a serem executados com o PhantomJS para a exportação;
220 |
221 | ``setCommandOptions(array $options)``: Define os parâmetros a serem executados com o PhantomJS para a exportação;
222 |
223 | ``addCommandOption($option, $value)``: Adiciona um novo parâmetro a ser executado com o PhantomJS para a exportação;
224 |
225 | ``getHeaderHeight()``: Retorna o tamanho do cabeçalho definido;
226 |
227 | ``getFooterHeight()``: Retorna o tamanho do rodapé definido;
228 |
229 | ### ImageExport
230 |
231 | Para a exportação de arquivos em formatos de **Imagem**, além dos métodos padrões, alguns outros estão disponíveis,
232 | abaixo são listados com uma breve descrição de sua função:
233 |
234 | ``getFormat()``: Retorna o formato da imagem a ser exportada;
235 |
236 | ``setFormat($format)``: Define o formato da imagem a ser exportada. (Formatos válidos: 'BMP', 'JPG', 'JPEG', 'PNG')
237 |
238 | ``getOrientation()``: Retorna a orientação da imagem baseada nas configurações do viewport;
239 |
240 | ``setOrientation($orientation)``: Define a orientação da imagem a ser exportada. (Orientações válidas: 'landscape', 'portrait')
241 |
242 | ``getMargin()``: Retorna a margem da imagem a ser exportada;
243 |
244 | ``setMargin($margin)``: Define a margem da imagem a ser exportada;
245 |
246 | ``getBinaryPath()``: Retorna o caminho para o binário do PhantomJS na aplicação;
247 |
248 | ``setBinaryPath($binaryPath)``: Define o caminho para o arquivo binário do PhantomJS na aplicação;
249 |
250 | ``getCommandOptions()``: Retorna os parâmetros a serem executados com o PhantomJS para a exportação;
251 |
252 | ``setCommandOptions(array $options)``: Define os parâmetros a serem executados com o PhantomJS para a exportação;
253 |
254 | ``addCommandOption($option, $value)``: Adiciona um novo parâmetro a ser executado com o PhantomJS para a exportação;
255 |
256 | ``getHeaderHeight()``: Retorna o tamanho do cabeçalho definido;
257 |
258 | ``getFooterHeight()``: Retorna o tamanho do rodapé definido;
259 |
260 |
261 | # Laravel
262 |
263 | Os passos descritos abaixo são opcionais e apenas podem facilitar para quem pretente usar este package com o Laravel 5.
264 |
265 | ## Registrando Service Provider
266 |
267 | No arquivo de configuração ``config\app.php``, registre acima dos providers de sua aplicação como segue abaixo:
268 |
269 | ```
270 | 'providers' => [
271 | Fireguard\Report\Laravel\ReportServiceProvider::class,
272 | ...
273 | ]
274 | ```
275 |
276 | ## Publicando o arquivo de configuração
277 |
278 | Para publicar o arquivo de configuração deve-se usar o seguinte comando:
279 | ```
280 | php artisan vendor:publish --provider="Fireguard\Report\Laravel\ReportServiceProvider"
281 | ```
282 |
283 | ## Exemplos de uso com Laravel (Dependency Injection)
284 |
285 | Com o registro do service provider, agora pode-se usar a injeção de dependência do Laravel para resolver os exporters,
286 | já os trazendo prontos e configurados com o arquivo de configuração da aplicação.
287 |
288 | Para a injeção de dependência é disponibilidado quatro classes, sendo uma interface e três concretas, a interface
289 | por padrão é resolvida para a classe concreta PdfExporter, o que pode ser alterado no parâmetro ``default-exporter`` do
290 | arquivo de configuração ``report.php`` gerado na integração. Veja abaixo alguns exemplos de uso.
291 |
292 | ### Exporter Interface
293 |
294 | ```php
295 | public function index (\Fireguard\Report\Exporters\ExporterInterface $exporter)
296 | {
297 | $html = view()->make('welcome')->render();
298 |
299 | // Option 1
300 | return $exporter
301 | ->response(new Report($html))
302 | ->send();
303 |
304 | // Option 2
305 | $file = $exporter->generate(new Report($html));
306 | $headers = [
307 | 'Content-type' => mime_content_type($file),
308 | 'Content-Transfer-Encoding' => 'binary',
309 | 'Content-Length' => filesize($file),
310 | 'Accept-Ranges' => 'bytes'
311 | ];
312 | // Caso queira mostrar diretamente o arquivo
313 | return response()->make(file_get_contents($file), 200, $headers);
314 | // Caso deseja forçar o download
315 | // return response()->download($file, 'report.pdf', $headers);
316 | }
317 | ```
318 |
319 | ### HtmlExporter Class
320 |
321 | ```php
322 | public function index (\Fireguard\Report\Exporters\HtmlExporter $exporter)
323 | {
324 | $html = view()->make('welcome')->render();
325 | // Option 1
326 | return $exporter
327 | ->response(new Report($html))
328 | ->send();
329 |
330 |
331 | // Option 2
332 | $file = $exporter->generate(new Report($html));
333 | // Caso queira mostrar diretamente o arquivo
334 | // return response()->make(file_get_contents($file), 200);
335 | //Caso queira forçar o download
336 | return response()->download($file, 'report.html', []);
337 | }
338 | ```
339 |
340 | ### PdfExporter Class
341 |
342 | ```php
343 | public function index (\Fireguard\Report\Exporters\PdfExporter $exporter)
344 | {
345 | $html = view()->make('welcome')->render();
346 | // Option 1
347 | return $exporter
348 | ->response(new Report($html))
349 | ->send();
350 |
351 |
352 | // Option 2
353 | $file = $exporter->generate(new Report($html));
354 | $headers = [
355 | 'Content-type' => 'application/pdf',
356 | 'Content-Transfer-Encoding' => 'binary',
357 | 'Content-Length' => filesize($file),
358 | 'Accept-Ranges' => 'bytes'
359 | ];
360 | // Caso queira mostrar diretamente o arquivo
361 | return response()->make(file_get_contents($file), 200, $headers);
362 | // Caso deseja forçar o download
363 | // return response()->download($file, 'report.pdf', $headers);
364 | }
365 | ```
366 |
367 | ### ImageExporter Class
368 |
369 | ```php
370 | public function index (\Fireguard\Report\Exporters\ImageExporter $exporter)
371 | {
372 | $html = view()->make('welcome')->render();
373 |
374 | // Option 1
375 | return $exporter
376 | ->response(new Report($html))
377 | ->send();
378 |
379 |
380 | // Option 2
381 | $file = $exporter->generate(new Report($html));
382 | $headers = [
383 | 'Content-type' => 'image/jpg',
384 | 'Content-Length' => filesize($file),
385 | ];
386 | // Caso queira mostrar diretamente o arquivo
387 | return response()->make(file_get_contents($file), 200, $headers);
388 | // Caso deseja forçar o download
389 | // return response()->download($file, 'report.jpg', $headers);
390 | }
391 | ```
392 |
393 | # Outros exemplos de uso
394 |
395 | - Gerando um relatório em HTML
396 | - Gerando um relatório em PDF
397 | - Gerando um relatório em Imagem
398 | - Boleto de exemplo gerado com este package
399 |
400 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fireguard/report",
3 | "description": "Report management package in PHP that aims to help you export information in a variety of formats",
4 | "keywords": [ "php", "report", "relatório", "pdf", "html", "image", "laravel"],
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Ronaldo Meneguite",
9 | "email": "ronaldo@fireguard.com.br"
10 | }
11 | ],
12 | "require": {
13 | "php": ">=5.5.9",
14 | "jakoch/phantomjs-installer": "2.1.1-p06",
15 | "symfony/process": ">=2.7",
16 | "symfony/http-foundation": ">=2.7"
17 | },
18 | "require-dev": {
19 | "phpunit/phpunit": "~4.0",
20 | "illuminate/support": "~5.1"
21 | },
22 | "autoload": {
23 | "psr-4": {
24 | "Fireguard\\Report\\": "src/Report"
25 | }
26 | },
27 | "scripts": {
28 | "post-install-cmd": [
29 | "PhantomInstaller\\Installer::installPhantomJS"
30 | ],
31 | "post-update-cmd": [
32 | "PhantomInstaller\\Installer::installPhantomJS"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "265fd8f32a554d5a2d2e592a48ff55ae",
8 | "packages": [
9 | {
10 | "name": "jakoch/phantomjs-installer",
11 | "version": "2.1.1-p06",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/jakoch/phantomjs-installer.git",
15 | "reference": "26f870052263c00d09103928ad39c935108f51d4"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/jakoch/phantomjs-installer/zipball/26f870052263c00d09103928ad39c935108f51d4",
20 | "reference": "26f870052263c00d09103928ad39c935108f51d4",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "ext-bz2": "*",
25 | "ext-openssl": "*"
26 | },
27 | "type": "custom-installer",
28 | "autoload": {
29 | "psr-0": {
30 | "PhantomInstaller\\": "src/"
31 | }
32 | },
33 | "notification-url": "https://packagist.org/downloads/",
34 | "license": [
35 | "MIT"
36 | ],
37 | "authors": [
38 | {
39 | "name": "Jens-André Koch",
40 | "email": "jakoch@web.de"
41 | }
42 | ],
43 | "description": "A Composer package which installs the PhantomJS binary (Linux, Windows, Mac) into `/bin` of your project.",
44 | "keywords": [
45 | "binaries",
46 | "headless",
47 | "phantomjs"
48 | ],
49 | "time": "2016-08-09T10:14:29+00:00"
50 | },
51 | {
52 | "name": "symfony/http-foundation",
53 | "version": "v3.2.3",
54 | "source": {
55 | "type": "git",
56 | "url": "https://github.com/symfony/http-foundation.git",
57 | "reference": "e192b04de44aa1ed0e39d6793f7e06f5e0b672a0"
58 | },
59 | "dist": {
60 | "type": "zip",
61 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e192b04de44aa1ed0e39d6793f7e06f5e0b672a0",
62 | "reference": "e192b04de44aa1ed0e39d6793f7e06f5e0b672a0",
63 | "shasum": ""
64 | },
65 | "require": {
66 | "php": ">=5.5.9",
67 | "symfony/polyfill-mbstring": "~1.1"
68 | },
69 | "require-dev": {
70 | "symfony/expression-language": "~2.8|~3.0"
71 | },
72 | "type": "library",
73 | "extra": {
74 | "branch-alias": {
75 | "dev-master": "3.2-dev"
76 | }
77 | },
78 | "autoload": {
79 | "psr-4": {
80 | "Symfony\\Component\\HttpFoundation\\": ""
81 | },
82 | "exclude-from-classmap": [
83 | "/Tests/"
84 | ]
85 | },
86 | "notification-url": "https://packagist.org/downloads/",
87 | "license": [
88 | "MIT"
89 | ],
90 | "authors": [
91 | {
92 | "name": "Fabien Potencier",
93 | "email": "fabien@symfony.com"
94 | },
95 | {
96 | "name": "Symfony Community",
97 | "homepage": "https://symfony.com/contributors"
98 | }
99 | ],
100 | "description": "Symfony HttpFoundation Component",
101 | "homepage": "https://symfony.com",
102 | "time": "2017-02-02T13:47:35+00:00"
103 | },
104 | {
105 | "name": "symfony/polyfill-mbstring",
106 | "version": "v1.3.0",
107 | "source": {
108 | "type": "git",
109 | "url": "https://github.com/symfony/polyfill-mbstring.git",
110 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
111 | },
112 | "dist": {
113 | "type": "zip",
114 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
115 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
116 | "shasum": ""
117 | },
118 | "require": {
119 | "php": ">=5.3.3"
120 | },
121 | "suggest": {
122 | "ext-mbstring": "For best performance"
123 | },
124 | "type": "library",
125 | "extra": {
126 | "branch-alias": {
127 | "dev-master": "1.3-dev"
128 | }
129 | },
130 | "autoload": {
131 | "psr-4": {
132 | "Symfony\\Polyfill\\Mbstring\\": ""
133 | },
134 | "files": [
135 | "bootstrap.php"
136 | ]
137 | },
138 | "notification-url": "https://packagist.org/downloads/",
139 | "license": [
140 | "MIT"
141 | ],
142 | "authors": [
143 | {
144 | "name": "Nicolas Grekas",
145 | "email": "p@tchwork.com"
146 | },
147 | {
148 | "name": "Symfony Community",
149 | "homepage": "https://symfony.com/contributors"
150 | }
151 | ],
152 | "description": "Symfony polyfill for the Mbstring extension",
153 | "homepage": "https://symfony.com",
154 | "keywords": [
155 | "compatibility",
156 | "mbstring",
157 | "polyfill",
158 | "portable",
159 | "shim"
160 | ],
161 | "time": "2016-11-14T01:06:16+00:00"
162 | },
163 | {
164 | "name": "symfony/process",
165 | "version": "v3.2.3",
166 | "source": {
167 | "type": "git",
168 | "url": "https://github.com/symfony/process.git",
169 | "reference": "32646a7cf53f3956c76dcb5c82555224ae321858"
170 | },
171 | "dist": {
172 | "type": "zip",
173 | "url": "https://api.github.com/repos/symfony/process/zipball/32646a7cf53f3956c76dcb5c82555224ae321858",
174 | "reference": "32646a7cf53f3956c76dcb5c82555224ae321858",
175 | "shasum": ""
176 | },
177 | "require": {
178 | "php": ">=5.5.9"
179 | },
180 | "type": "library",
181 | "extra": {
182 | "branch-alias": {
183 | "dev-master": "3.2-dev"
184 | }
185 | },
186 | "autoload": {
187 | "psr-4": {
188 | "Symfony\\Component\\Process\\": ""
189 | },
190 | "exclude-from-classmap": [
191 | "/Tests/"
192 | ]
193 | },
194 | "notification-url": "https://packagist.org/downloads/",
195 | "license": [
196 | "MIT"
197 | ],
198 | "authors": [
199 | {
200 | "name": "Fabien Potencier",
201 | "email": "fabien@symfony.com"
202 | },
203 | {
204 | "name": "Symfony Community",
205 | "homepage": "https://symfony.com/contributors"
206 | }
207 | ],
208 | "description": "Symfony Process Component",
209 | "homepage": "https://symfony.com",
210 | "time": "2017-02-03T12:11:38+00:00"
211 | }
212 | ],
213 | "packages-dev": [
214 | {
215 | "name": "doctrine/inflector",
216 | "version": "v1.1.0",
217 | "source": {
218 | "type": "git",
219 | "url": "https://github.com/doctrine/inflector.git",
220 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
221 | },
222 | "dist": {
223 | "type": "zip",
224 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
225 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
226 | "shasum": ""
227 | },
228 | "require": {
229 | "php": ">=5.3.2"
230 | },
231 | "require-dev": {
232 | "phpunit/phpunit": "4.*"
233 | },
234 | "type": "library",
235 | "extra": {
236 | "branch-alias": {
237 | "dev-master": "1.1.x-dev"
238 | }
239 | },
240 | "autoload": {
241 | "psr-0": {
242 | "Doctrine\\Common\\Inflector\\": "lib/"
243 | }
244 | },
245 | "notification-url": "https://packagist.org/downloads/",
246 | "license": [
247 | "MIT"
248 | ],
249 | "authors": [
250 | {
251 | "name": "Roman Borschel",
252 | "email": "roman@code-factory.org"
253 | },
254 | {
255 | "name": "Benjamin Eberlei",
256 | "email": "kontakt@beberlei.de"
257 | },
258 | {
259 | "name": "Guilherme Blanco",
260 | "email": "guilhermeblanco@gmail.com"
261 | },
262 | {
263 | "name": "Jonathan Wage",
264 | "email": "jonwage@gmail.com"
265 | },
266 | {
267 | "name": "Johannes Schmitt",
268 | "email": "schmittjoh@gmail.com"
269 | }
270 | ],
271 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
272 | "homepage": "http://www.doctrine-project.org",
273 | "keywords": [
274 | "inflection",
275 | "pluralize",
276 | "singularize",
277 | "string"
278 | ],
279 | "time": "2015-11-06T14:35:42+00:00"
280 | },
281 | {
282 | "name": "doctrine/instantiator",
283 | "version": "1.0.5",
284 | "source": {
285 | "type": "git",
286 | "url": "https://github.com/doctrine/instantiator.git",
287 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
288 | },
289 | "dist": {
290 | "type": "zip",
291 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
292 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
293 | "shasum": ""
294 | },
295 | "require": {
296 | "php": ">=5.3,<8.0-DEV"
297 | },
298 | "require-dev": {
299 | "athletic/athletic": "~0.1.8",
300 | "ext-pdo": "*",
301 | "ext-phar": "*",
302 | "phpunit/phpunit": "~4.0",
303 | "squizlabs/php_codesniffer": "~2.0"
304 | },
305 | "type": "library",
306 | "extra": {
307 | "branch-alias": {
308 | "dev-master": "1.0.x-dev"
309 | }
310 | },
311 | "autoload": {
312 | "psr-4": {
313 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
314 | }
315 | },
316 | "notification-url": "https://packagist.org/downloads/",
317 | "license": [
318 | "MIT"
319 | ],
320 | "authors": [
321 | {
322 | "name": "Marco Pivetta",
323 | "email": "ocramius@gmail.com",
324 | "homepage": "http://ocramius.github.com/"
325 | }
326 | ],
327 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
328 | "homepage": "https://github.com/doctrine/instantiator",
329 | "keywords": [
330 | "constructor",
331 | "instantiate"
332 | ],
333 | "time": "2015-06-14T21:17:01+00:00"
334 | },
335 | {
336 | "name": "illuminate/contracts",
337 | "version": "v5.4.9",
338 | "source": {
339 | "type": "git",
340 | "url": "https://github.com/illuminate/contracts.git",
341 | "reference": "4ec919d294aca396d172e644b243b49885cd2cc7"
342 | },
343 | "dist": {
344 | "type": "zip",
345 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/4ec919d294aca396d172e644b243b49885cd2cc7",
346 | "reference": "4ec919d294aca396d172e644b243b49885cd2cc7",
347 | "shasum": ""
348 | },
349 | "require": {
350 | "php": ">=5.6.4"
351 | },
352 | "type": "library",
353 | "extra": {
354 | "branch-alias": {
355 | "dev-master": "5.4-dev"
356 | }
357 | },
358 | "autoload": {
359 | "psr-4": {
360 | "Illuminate\\Contracts\\": ""
361 | }
362 | },
363 | "notification-url": "https://packagist.org/downloads/",
364 | "license": [
365 | "MIT"
366 | ],
367 | "authors": [
368 | {
369 | "name": "Taylor Otwell",
370 | "email": "taylor@laravel.com"
371 | }
372 | ],
373 | "description": "The Illuminate Contracts package.",
374 | "homepage": "https://laravel.com",
375 | "time": "2017-01-18T20:23:54+00:00"
376 | },
377 | {
378 | "name": "illuminate/support",
379 | "version": "v5.4.9",
380 | "source": {
381 | "type": "git",
382 | "url": "https://github.com/illuminate/support.git",
383 | "reference": "5544aaf67b7e57559d58c01a9030c82ca01872a6"
384 | },
385 | "dist": {
386 | "type": "zip",
387 | "url": "https://api.github.com/repos/illuminate/support/zipball/5544aaf67b7e57559d58c01a9030c82ca01872a6",
388 | "reference": "5544aaf67b7e57559d58c01a9030c82ca01872a6",
389 | "shasum": ""
390 | },
391 | "require": {
392 | "doctrine/inflector": "~1.0",
393 | "ext-mbstring": "*",
394 | "illuminate/contracts": "5.4.*",
395 | "paragonie/random_compat": "~1.4|~2.0",
396 | "php": ">=5.6.4"
397 | },
398 | "replace": {
399 | "tightenco/collect": "self.version"
400 | },
401 | "suggest": {
402 | "illuminate/filesystem": "Required to use the composer class (5.2.*).",
403 | "symfony/process": "Required to use the composer class (~3.2).",
404 | "symfony/var-dumper": "Required to use the dd function (~3.2)."
405 | },
406 | "type": "library",
407 | "extra": {
408 | "branch-alias": {
409 | "dev-master": "5.4-dev"
410 | }
411 | },
412 | "autoload": {
413 | "psr-4": {
414 | "Illuminate\\Support\\": ""
415 | },
416 | "files": [
417 | "helpers.php"
418 | ]
419 | },
420 | "notification-url": "https://packagist.org/downloads/",
421 | "license": [
422 | "MIT"
423 | ],
424 | "authors": [
425 | {
426 | "name": "Taylor Otwell",
427 | "email": "taylor@laravel.com"
428 | }
429 | ],
430 | "description": "The Illuminate Support package.",
431 | "homepage": "https://laravel.com",
432 | "time": "2017-02-02T13:32:18+00:00"
433 | },
434 | {
435 | "name": "paragonie/random_compat",
436 | "version": "v2.0.4",
437 | "source": {
438 | "type": "git",
439 | "url": "https://github.com/paragonie/random_compat.git",
440 | "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e"
441 | },
442 | "dist": {
443 | "type": "zip",
444 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
445 | "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
446 | "shasum": ""
447 | },
448 | "require": {
449 | "php": ">=5.2.0"
450 | },
451 | "require-dev": {
452 | "phpunit/phpunit": "4.*|5.*"
453 | },
454 | "suggest": {
455 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
456 | },
457 | "type": "library",
458 | "autoload": {
459 | "files": [
460 | "lib/random.php"
461 | ]
462 | },
463 | "notification-url": "https://packagist.org/downloads/",
464 | "license": [
465 | "MIT"
466 | ],
467 | "authors": [
468 | {
469 | "name": "Paragon Initiative Enterprises",
470 | "email": "security@paragonie.com",
471 | "homepage": "https://paragonie.com"
472 | }
473 | ],
474 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
475 | "keywords": [
476 | "csprng",
477 | "pseudorandom",
478 | "random"
479 | ],
480 | "time": "2016-11-07T23:38:38+00:00"
481 | },
482 | {
483 | "name": "phpdocumentor/reflection-common",
484 | "version": "1.0",
485 | "source": {
486 | "type": "git",
487 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
488 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
489 | },
490 | "dist": {
491 | "type": "zip",
492 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
493 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
494 | "shasum": ""
495 | },
496 | "require": {
497 | "php": ">=5.5"
498 | },
499 | "require-dev": {
500 | "phpunit/phpunit": "^4.6"
501 | },
502 | "type": "library",
503 | "extra": {
504 | "branch-alias": {
505 | "dev-master": "1.0.x-dev"
506 | }
507 | },
508 | "autoload": {
509 | "psr-4": {
510 | "phpDocumentor\\Reflection\\": [
511 | "src"
512 | ]
513 | }
514 | },
515 | "notification-url": "https://packagist.org/downloads/",
516 | "license": [
517 | "MIT"
518 | ],
519 | "authors": [
520 | {
521 | "name": "Jaap van Otterdijk",
522 | "email": "opensource@ijaap.nl"
523 | }
524 | ],
525 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
526 | "homepage": "http://www.phpdoc.org",
527 | "keywords": [
528 | "FQSEN",
529 | "phpDocumentor",
530 | "phpdoc",
531 | "reflection",
532 | "static analysis"
533 | ],
534 | "time": "2015-12-27T11:43:31+00:00"
535 | },
536 | {
537 | "name": "phpdocumentor/reflection-docblock",
538 | "version": "3.1.1",
539 | "source": {
540 | "type": "git",
541 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
542 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
543 | },
544 | "dist": {
545 | "type": "zip",
546 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
547 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
548 | "shasum": ""
549 | },
550 | "require": {
551 | "php": ">=5.5",
552 | "phpdocumentor/reflection-common": "^1.0@dev",
553 | "phpdocumentor/type-resolver": "^0.2.0",
554 | "webmozart/assert": "^1.0"
555 | },
556 | "require-dev": {
557 | "mockery/mockery": "^0.9.4",
558 | "phpunit/phpunit": "^4.4"
559 | },
560 | "type": "library",
561 | "autoload": {
562 | "psr-4": {
563 | "phpDocumentor\\Reflection\\": [
564 | "src/"
565 | ]
566 | }
567 | },
568 | "notification-url": "https://packagist.org/downloads/",
569 | "license": [
570 | "MIT"
571 | ],
572 | "authors": [
573 | {
574 | "name": "Mike van Riel",
575 | "email": "me@mikevanriel.com"
576 | }
577 | ],
578 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
579 | "time": "2016-09-30T07:12:33+00:00"
580 | },
581 | {
582 | "name": "phpdocumentor/type-resolver",
583 | "version": "0.2.1",
584 | "source": {
585 | "type": "git",
586 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
587 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
588 | },
589 | "dist": {
590 | "type": "zip",
591 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
592 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
593 | "shasum": ""
594 | },
595 | "require": {
596 | "php": ">=5.5",
597 | "phpdocumentor/reflection-common": "^1.0"
598 | },
599 | "require-dev": {
600 | "mockery/mockery": "^0.9.4",
601 | "phpunit/phpunit": "^5.2||^4.8.24"
602 | },
603 | "type": "library",
604 | "extra": {
605 | "branch-alias": {
606 | "dev-master": "1.0.x-dev"
607 | }
608 | },
609 | "autoload": {
610 | "psr-4": {
611 | "phpDocumentor\\Reflection\\": [
612 | "src/"
613 | ]
614 | }
615 | },
616 | "notification-url": "https://packagist.org/downloads/",
617 | "license": [
618 | "MIT"
619 | ],
620 | "authors": [
621 | {
622 | "name": "Mike van Riel",
623 | "email": "me@mikevanriel.com"
624 | }
625 | ],
626 | "time": "2016-11-25T06:54:22+00:00"
627 | },
628 | {
629 | "name": "phpspec/prophecy",
630 | "version": "v1.6.2",
631 | "source": {
632 | "type": "git",
633 | "url": "https://github.com/phpspec/prophecy.git",
634 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
635 | },
636 | "dist": {
637 | "type": "zip",
638 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
639 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
640 | "shasum": ""
641 | },
642 | "require": {
643 | "doctrine/instantiator": "^1.0.2",
644 | "php": "^5.3|^7.0",
645 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
646 | "sebastian/comparator": "^1.1",
647 | "sebastian/recursion-context": "^1.0|^2.0"
648 | },
649 | "require-dev": {
650 | "phpspec/phpspec": "^2.0",
651 | "phpunit/phpunit": "^4.8 || ^5.6.5"
652 | },
653 | "type": "library",
654 | "extra": {
655 | "branch-alias": {
656 | "dev-master": "1.6.x-dev"
657 | }
658 | },
659 | "autoload": {
660 | "psr-0": {
661 | "Prophecy\\": "src/"
662 | }
663 | },
664 | "notification-url": "https://packagist.org/downloads/",
665 | "license": [
666 | "MIT"
667 | ],
668 | "authors": [
669 | {
670 | "name": "Konstantin Kudryashov",
671 | "email": "ever.zet@gmail.com",
672 | "homepage": "http://everzet.com"
673 | },
674 | {
675 | "name": "Marcello Duarte",
676 | "email": "marcello.duarte@gmail.com"
677 | }
678 | ],
679 | "description": "Highly opinionated mocking framework for PHP 5.3+",
680 | "homepage": "https://github.com/phpspec/prophecy",
681 | "keywords": [
682 | "Double",
683 | "Dummy",
684 | "fake",
685 | "mock",
686 | "spy",
687 | "stub"
688 | ],
689 | "time": "2016-11-21T14:58:47+00:00"
690 | },
691 | {
692 | "name": "phpunit/php-code-coverage",
693 | "version": "2.2.4",
694 | "source": {
695 | "type": "git",
696 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
697 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
698 | },
699 | "dist": {
700 | "type": "zip",
701 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
702 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
703 | "shasum": ""
704 | },
705 | "require": {
706 | "php": ">=5.3.3",
707 | "phpunit/php-file-iterator": "~1.3",
708 | "phpunit/php-text-template": "~1.2",
709 | "phpunit/php-token-stream": "~1.3",
710 | "sebastian/environment": "^1.3.2",
711 | "sebastian/version": "~1.0"
712 | },
713 | "require-dev": {
714 | "ext-xdebug": ">=2.1.4",
715 | "phpunit/phpunit": "~4"
716 | },
717 | "suggest": {
718 | "ext-dom": "*",
719 | "ext-xdebug": ">=2.2.1",
720 | "ext-xmlwriter": "*"
721 | },
722 | "type": "library",
723 | "extra": {
724 | "branch-alias": {
725 | "dev-master": "2.2.x-dev"
726 | }
727 | },
728 | "autoload": {
729 | "classmap": [
730 | "src/"
731 | ]
732 | },
733 | "notification-url": "https://packagist.org/downloads/",
734 | "license": [
735 | "BSD-3-Clause"
736 | ],
737 | "authors": [
738 | {
739 | "name": "Sebastian Bergmann",
740 | "email": "sb@sebastian-bergmann.de",
741 | "role": "lead"
742 | }
743 | ],
744 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
745 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
746 | "keywords": [
747 | "coverage",
748 | "testing",
749 | "xunit"
750 | ],
751 | "time": "2015-10-06T15:47:00+00:00"
752 | },
753 | {
754 | "name": "phpunit/php-file-iterator",
755 | "version": "1.4.2",
756 | "source": {
757 | "type": "git",
758 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
759 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
760 | },
761 | "dist": {
762 | "type": "zip",
763 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
764 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
765 | "shasum": ""
766 | },
767 | "require": {
768 | "php": ">=5.3.3"
769 | },
770 | "type": "library",
771 | "extra": {
772 | "branch-alias": {
773 | "dev-master": "1.4.x-dev"
774 | }
775 | },
776 | "autoload": {
777 | "classmap": [
778 | "src/"
779 | ]
780 | },
781 | "notification-url": "https://packagist.org/downloads/",
782 | "license": [
783 | "BSD-3-Clause"
784 | ],
785 | "authors": [
786 | {
787 | "name": "Sebastian Bergmann",
788 | "email": "sb@sebastian-bergmann.de",
789 | "role": "lead"
790 | }
791 | ],
792 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
793 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
794 | "keywords": [
795 | "filesystem",
796 | "iterator"
797 | ],
798 | "time": "2016-10-03T07:40:28+00:00"
799 | },
800 | {
801 | "name": "phpunit/php-text-template",
802 | "version": "1.2.1",
803 | "source": {
804 | "type": "git",
805 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
806 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
807 | },
808 | "dist": {
809 | "type": "zip",
810 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
811 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
812 | "shasum": ""
813 | },
814 | "require": {
815 | "php": ">=5.3.3"
816 | },
817 | "type": "library",
818 | "autoload": {
819 | "classmap": [
820 | "src/"
821 | ]
822 | },
823 | "notification-url": "https://packagist.org/downloads/",
824 | "license": [
825 | "BSD-3-Clause"
826 | ],
827 | "authors": [
828 | {
829 | "name": "Sebastian Bergmann",
830 | "email": "sebastian@phpunit.de",
831 | "role": "lead"
832 | }
833 | ],
834 | "description": "Simple template engine.",
835 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
836 | "keywords": [
837 | "template"
838 | ],
839 | "time": "2015-06-21T13:50:34+00:00"
840 | },
841 | {
842 | "name": "phpunit/php-timer",
843 | "version": "1.0.8",
844 | "source": {
845 | "type": "git",
846 | "url": "https://github.com/sebastianbergmann/php-timer.git",
847 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
848 | },
849 | "dist": {
850 | "type": "zip",
851 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
852 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
853 | "shasum": ""
854 | },
855 | "require": {
856 | "php": ">=5.3.3"
857 | },
858 | "require-dev": {
859 | "phpunit/phpunit": "~4|~5"
860 | },
861 | "type": "library",
862 | "autoload": {
863 | "classmap": [
864 | "src/"
865 | ]
866 | },
867 | "notification-url": "https://packagist.org/downloads/",
868 | "license": [
869 | "BSD-3-Clause"
870 | ],
871 | "authors": [
872 | {
873 | "name": "Sebastian Bergmann",
874 | "email": "sb@sebastian-bergmann.de",
875 | "role": "lead"
876 | }
877 | ],
878 | "description": "Utility class for timing",
879 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
880 | "keywords": [
881 | "timer"
882 | ],
883 | "time": "2016-05-12T18:03:57+00:00"
884 | },
885 | {
886 | "name": "phpunit/php-token-stream",
887 | "version": "1.4.9",
888 | "source": {
889 | "type": "git",
890 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
891 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
892 | },
893 | "dist": {
894 | "type": "zip",
895 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
896 | "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
897 | "shasum": ""
898 | },
899 | "require": {
900 | "ext-tokenizer": "*",
901 | "php": ">=5.3.3"
902 | },
903 | "require-dev": {
904 | "phpunit/phpunit": "~4.2"
905 | },
906 | "type": "library",
907 | "extra": {
908 | "branch-alias": {
909 | "dev-master": "1.4-dev"
910 | }
911 | },
912 | "autoload": {
913 | "classmap": [
914 | "src/"
915 | ]
916 | },
917 | "notification-url": "https://packagist.org/downloads/",
918 | "license": [
919 | "BSD-3-Clause"
920 | ],
921 | "authors": [
922 | {
923 | "name": "Sebastian Bergmann",
924 | "email": "sebastian@phpunit.de"
925 | }
926 | ],
927 | "description": "Wrapper around PHP's tokenizer extension.",
928 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
929 | "keywords": [
930 | "tokenizer"
931 | ],
932 | "time": "2016-11-15T14:06:22+00:00"
933 | },
934 | {
935 | "name": "phpunit/phpunit",
936 | "version": "4.8.35",
937 | "source": {
938 | "type": "git",
939 | "url": "https://github.com/sebastianbergmann/phpunit.git",
940 | "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87"
941 | },
942 | "dist": {
943 | "type": "zip",
944 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87",
945 | "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87",
946 | "shasum": ""
947 | },
948 | "require": {
949 | "ext-dom": "*",
950 | "ext-json": "*",
951 | "ext-pcre": "*",
952 | "ext-reflection": "*",
953 | "ext-spl": "*",
954 | "php": ">=5.3.3",
955 | "phpspec/prophecy": "^1.3.1",
956 | "phpunit/php-code-coverage": "~2.1",
957 | "phpunit/php-file-iterator": "~1.4",
958 | "phpunit/php-text-template": "~1.2",
959 | "phpunit/php-timer": "^1.0.6",
960 | "phpunit/phpunit-mock-objects": "~2.3",
961 | "sebastian/comparator": "~1.2.2",
962 | "sebastian/diff": "~1.2",
963 | "sebastian/environment": "~1.3",
964 | "sebastian/exporter": "~1.2",
965 | "sebastian/global-state": "~1.0",
966 | "sebastian/version": "~1.0",
967 | "symfony/yaml": "~2.1|~3.0"
968 | },
969 | "suggest": {
970 | "phpunit/php-invoker": "~1.1"
971 | },
972 | "bin": [
973 | "phpunit"
974 | ],
975 | "type": "library",
976 | "extra": {
977 | "branch-alias": {
978 | "dev-master": "4.8.x-dev"
979 | }
980 | },
981 | "autoload": {
982 | "classmap": [
983 | "src/"
984 | ]
985 | },
986 | "notification-url": "https://packagist.org/downloads/",
987 | "license": [
988 | "BSD-3-Clause"
989 | ],
990 | "authors": [
991 | {
992 | "name": "Sebastian Bergmann",
993 | "email": "sebastian@phpunit.de",
994 | "role": "lead"
995 | }
996 | ],
997 | "description": "The PHP Unit Testing framework.",
998 | "homepage": "https://phpunit.de/",
999 | "keywords": [
1000 | "phpunit",
1001 | "testing",
1002 | "xunit"
1003 | ],
1004 | "time": "2017-02-06T05:18:07+00:00"
1005 | },
1006 | {
1007 | "name": "phpunit/phpunit-mock-objects",
1008 | "version": "2.3.8",
1009 | "source": {
1010 | "type": "git",
1011 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1012 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
1013 | },
1014 | "dist": {
1015 | "type": "zip",
1016 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1017 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1018 | "shasum": ""
1019 | },
1020 | "require": {
1021 | "doctrine/instantiator": "^1.0.2",
1022 | "php": ">=5.3.3",
1023 | "phpunit/php-text-template": "~1.2",
1024 | "sebastian/exporter": "~1.2"
1025 | },
1026 | "require-dev": {
1027 | "phpunit/phpunit": "~4.4"
1028 | },
1029 | "suggest": {
1030 | "ext-soap": "*"
1031 | },
1032 | "type": "library",
1033 | "extra": {
1034 | "branch-alias": {
1035 | "dev-master": "2.3.x-dev"
1036 | }
1037 | },
1038 | "autoload": {
1039 | "classmap": [
1040 | "src/"
1041 | ]
1042 | },
1043 | "notification-url": "https://packagist.org/downloads/",
1044 | "license": [
1045 | "BSD-3-Clause"
1046 | ],
1047 | "authors": [
1048 | {
1049 | "name": "Sebastian Bergmann",
1050 | "email": "sb@sebastian-bergmann.de",
1051 | "role": "lead"
1052 | }
1053 | ],
1054 | "description": "Mock Object library for PHPUnit",
1055 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1056 | "keywords": [
1057 | "mock",
1058 | "xunit"
1059 | ],
1060 | "time": "2015-10-02T06:51:40+00:00"
1061 | },
1062 | {
1063 | "name": "sebastian/comparator",
1064 | "version": "1.2.4",
1065 | "source": {
1066 | "type": "git",
1067 | "url": "https://github.com/sebastianbergmann/comparator.git",
1068 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
1069 | },
1070 | "dist": {
1071 | "type": "zip",
1072 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1073 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1074 | "shasum": ""
1075 | },
1076 | "require": {
1077 | "php": ">=5.3.3",
1078 | "sebastian/diff": "~1.2",
1079 | "sebastian/exporter": "~1.2 || ~2.0"
1080 | },
1081 | "require-dev": {
1082 | "phpunit/phpunit": "~4.4"
1083 | },
1084 | "type": "library",
1085 | "extra": {
1086 | "branch-alias": {
1087 | "dev-master": "1.2.x-dev"
1088 | }
1089 | },
1090 | "autoload": {
1091 | "classmap": [
1092 | "src/"
1093 | ]
1094 | },
1095 | "notification-url": "https://packagist.org/downloads/",
1096 | "license": [
1097 | "BSD-3-Clause"
1098 | ],
1099 | "authors": [
1100 | {
1101 | "name": "Jeff Welch",
1102 | "email": "whatthejeff@gmail.com"
1103 | },
1104 | {
1105 | "name": "Volker Dusch",
1106 | "email": "github@wallbash.com"
1107 | },
1108 | {
1109 | "name": "Bernhard Schussek",
1110 | "email": "bschussek@2bepublished.at"
1111 | },
1112 | {
1113 | "name": "Sebastian Bergmann",
1114 | "email": "sebastian@phpunit.de"
1115 | }
1116 | ],
1117 | "description": "Provides the functionality to compare PHP values for equality",
1118 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1119 | "keywords": [
1120 | "comparator",
1121 | "compare",
1122 | "equality"
1123 | ],
1124 | "time": "2017-01-29T09:50:25+00:00"
1125 | },
1126 | {
1127 | "name": "sebastian/diff",
1128 | "version": "1.4.1",
1129 | "source": {
1130 | "type": "git",
1131 | "url": "https://github.com/sebastianbergmann/diff.git",
1132 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
1133 | },
1134 | "dist": {
1135 | "type": "zip",
1136 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
1137 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
1138 | "shasum": ""
1139 | },
1140 | "require": {
1141 | "php": ">=5.3.3"
1142 | },
1143 | "require-dev": {
1144 | "phpunit/phpunit": "~4.8"
1145 | },
1146 | "type": "library",
1147 | "extra": {
1148 | "branch-alias": {
1149 | "dev-master": "1.4-dev"
1150 | }
1151 | },
1152 | "autoload": {
1153 | "classmap": [
1154 | "src/"
1155 | ]
1156 | },
1157 | "notification-url": "https://packagist.org/downloads/",
1158 | "license": [
1159 | "BSD-3-Clause"
1160 | ],
1161 | "authors": [
1162 | {
1163 | "name": "Kore Nordmann",
1164 | "email": "mail@kore-nordmann.de"
1165 | },
1166 | {
1167 | "name": "Sebastian Bergmann",
1168 | "email": "sebastian@phpunit.de"
1169 | }
1170 | ],
1171 | "description": "Diff implementation",
1172 | "homepage": "https://github.com/sebastianbergmann/diff",
1173 | "keywords": [
1174 | "diff"
1175 | ],
1176 | "time": "2015-12-08T07:14:41+00:00"
1177 | },
1178 | {
1179 | "name": "sebastian/environment",
1180 | "version": "1.3.8",
1181 | "source": {
1182 | "type": "git",
1183 | "url": "https://github.com/sebastianbergmann/environment.git",
1184 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1185 | },
1186 | "dist": {
1187 | "type": "zip",
1188 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1189 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1190 | "shasum": ""
1191 | },
1192 | "require": {
1193 | "php": "^5.3.3 || ^7.0"
1194 | },
1195 | "require-dev": {
1196 | "phpunit/phpunit": "^4.8 || ^5.0"
1197 | },
1198 | "type": "library",
1199 | "extra": {
1200 | "branch-alias": {
1201 | "dev-master": "1.3.x-dev"
1202 | }
1203 | },
1204 | "autoload": {
1205 | "classmap": [
1206 | "src/"
1207 | ]
1208 | },
1209 | "notification-url": "https://packagist.org/downloads/",
1210 | "license": [
1211 | "BSD-3-Clause"
1212 | ],
1213 | "authors": [
1214 | {
1215 | "name": "Sebastian Bergmann",
1216 | "email": "sebastian@phpunit.de"
1217 | }
1218 | ],
1219 | "description": "Provides functionality to handle HHVM/PHP environments",
1220 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1221 | "keywords": [
1222 | "Xdebug",
1223 | "environment",
1224 | "hhvm"
1225 | ],
1226 | "time": "2016-08-18T05:49:44+00:00"
1227 | },
1228 | {
1229 | "name": "sebastian/exporter",
1230 | "version": "1.2.2",
1231 | "source": {
1232 | "type": "git",
1233 | "url": "https://github.com/sebastianbergmann/exporter.git",
1234 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
1235 | },
1236 | "dist": {
1237 | "type": "zip",
1238 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
1239 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
1240 | "shasum": ""
1241 | },
1242 | "require": {
1243 | "php": ">=5.3.3",
1244 | "sebastian/recursion-context": "~1.0"
1245 | },
1246 | "require-dev": {
1247 | "ext-mbstring": "*",
1248 | "phpunit/phpunit": "~4.4"
1249 | },
1250 | "type": "library",
1251 | "extra": {
1252 | "branch-alias": {
1253 | "dev-master": "1.3.x-dev"
1254 | }
1255 | },
1256 | "autoload": {
1257 | "classmap": [
1258 | "src/"
1259 | ]
1260 | },
1261 | "notification-url": "https://packagist.org/downloads/",
1262 | "license": [
1263 | "BSD-3-Clause"
1264 | ],
1265 | "authors": [
1266 | {
1267 | "name": "Jeff Welch",
1268 | "email": "whatthejeff@gmail.com"
1269 | },
1270 | {
1271 | "name": "Volker Dusch",
1272 | "email": "github@wallbash.com"
1273 | },
1274 | {
1275 | "name": "Bernhard Schussek",
1276 | "email": "bschussek@2bepublished.at"
1277 | },
1278 | {
1279 | "name": "Sebastian Bergmann",
1280 | "email": "sebastian@phpunit.de"
1281 | },
1282 | {
1283 | "name": "Adam Harvey",
1284 | "email": "aharvey@php.net"
1285 | }
1286 | ],
1287 | "description": "Provides the functionality to export PHP variables for visualization",
1288 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1289 | "keywords": [
1290 | "export",
1291 | "exporter"
1292 | ],
1293 | "time": "2016-06-17T09:04:28+00:00"
1294 | },
1295 | {
1296 | "name": "sebastian/global-state",
1297 | "version": "1.1.1",
1298 | "source": {
1299 | "type": "git",
1300 | "url": "https://github.com/sebastianbergmann/global-state.git",
1301 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1302 | },
1303 | "dist": {
1304 | "type": "zip",
1305 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1306 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1307 | "shasum": ""
1308 | },
1309 | "require": {
1310 | "php": ">=5.3.3"
1311 | },
1312 | "require-dev": {
1313 | "phpunit/phpunit": "~4.2"
1314 | },
1315 | "suggest": {
1316 | "ext-uopz": "*"
1317 | },
1318 | "type": "library",
1319 | "extra": {
1320 | "branch-alias": {
1321 | "dev-master": "1.0-dev"
1322 | }
1323 | },
1324 | "autoload": {
1325 | "classmap": [
1326 | "src/"
1327 | ]
1328 | },
1329 | "notification-url": "https://packagist.org/downloads/",
1330 | "license": [
1331 | "BSD-3-Clause"
1332 | ],
1333 | "authors": [
1334 | {
1335 | "name": "Sebastian Bergmann",
1336 | "email": "sebastian@phpunit.de"
1337 | }
1338 | ],
1339 | "description": "Snapshotting of global state",
1340 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1341 | "keywords": [
1342 | "global state"
1343 | ],
1344 | "time": "2015-10-12T03:26:01+00:00"
1345 | },
1346 | {
1347 | "name": "sebastian/recursion-context",
1348 | "version": "1.0.2",
1349 | "source": {
1350 | "type": "git",
1351 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1352 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
1353 | },
1354 | "dist": {
1355 | "type": "zip",
1356 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
1357 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
1358 | "shasum": ""
1359 | },
1360 | "require": {
1361 | "php": ">=5.3.3"
1362 | },
1363 | "require-dev": {
1364 | "phpunit/phpunit": "~4.4"
1365 | },
1366 | "type": "library",
1367 | "extra": {
1368 | "branch-alias": {
1369 | "dev-master": "1.0.x-dev"
1370 | }
1371 | },
1372 | "autoload": {
1373 | "classmap": [
1374 | "src/"
1375 | ]
1376 | },
1377 | "notification-url": "https://packagist.org/downloads/",
1378 | "license": [
1379 | "BSD-3-Clause"
1380 | ],
1381 | "authors": [
1382 | {
1383 | "name": "Jeff Welch",
1384 | "email": "whatthejeff@gmail.com"
1385 | },
1386 | {
1387 | "name": "Sebastian Bergmann",
1388 | "email": "sebastian@phpunit.de"
1389 | },
1390 | {
1391 | "name": "Adam Harvey",
1392 | "email": "aharvey@php.net"
1393 | }
1394 | ],
1395 | "description": "Provides functionality to recursively process PHP variables",
1396 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1397 | "time": "2015-11-11T19:50:13+00:00"
1398 | },
1399 | {
1400 | "name": "sebastian/version",
1401 | "version": "1.0.6",
1402 | "source": {
1403 | "type": "git",
1404 | "url": "https://github.com/sebastianbergmann/version.git",
1405 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1406 | },
1407 | "dist": {
1408 | "type": "zip",
1409 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1410 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1411 | "shasum": ""
1412 | },
1413 | "type": "library",
1414 | "autoload": {
1415 | "classmap": [
1416 | "src/"
1417 | ]
1418 | },
1419 | "notification-url": "https://packagist.org/downloads/",
1420 | "license": [
1421 | "BSD-3-Clause"
1422 | ],
1423 | "authors": [
1424 | {
1425 | "name": "Sebastian Bergmann",
1426 | "email": "sebastian@phpunit.de",
1427 | "role": "lead"
1428 | }
1429 | ],
1430 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1431 | "homepage": "https://github.com/sebastianbergmann/version",
1432 | "time": "2015-06-21T13:59:46+00:00"
1433 | },
1434 | {
1435 | "name": "symfony/yaml",
1436 | "version": "v3.2.3",
1437 | "source": {
1438 | "type": "git",
1439 | "url": "https://github.com/symfony/yaml.git",
1440 | "reference": "e1718c6bf57e1efbb8793ada951584b2ab27775b"
1441 | },
1442 | "dist": {
1443 | "type": "zip",
1444 | "url": "https://api.github.com/repos/symfony/yaml/zipball/e1718c6bf57e1efbb8793ada951584b2ab27775b",
1445 | "reference": "e1718c6bf57e1efbb8793ada951584b2ab27775b",
1446 | "shasum": ""
1447 | },
1448 | "require": {
1449 | "php": ">=5.5.9"
1450 | },
1451 | "require-dev": {
1452 | "symfony/console": "~2.8|~3.0"
1453 | },
1454 | "suggest": {
1455 | "symfony/console": "For validating YAML files using the lint command"
1456 | },
1457 | "type": "library",
1458 | "extra": {
1459 | "branch-alias": {
1460 | "dev-master": "3.2-dev"
1461 | }
1462 | },
1463 | "autoload": {
1464 | "psr-4": {
1465 | "Symfony\\Component\\Yaml\\": ""
1466 | },
1467 | "exclude-from-classmap": [
1468 | "/Tests/"
1469 | ]
1470 | },
1471 | "notification-url": "https://packagist.org/downloads/",
1472 | "license": [
1473 | "MIT"
1474 | ],
1475 | "authors": [
1476 | {
1477 | "name": "Fabien Potencier",
1478 | "email": "fabien@symfony.com"
1479 | },
1480 | {
1481 | "name": "Symfony Community",
1482 | "homepage": "https://symfony.com/contributors"
1483 | }
1484 | ],
1485 | "description": "Symfony Yaml Component",
1486 | "homepage": "https://symfony.com",
1487 | "time": "2017-01-21T17:06:35+00:00"
1488 | },
1489 | {
1490 | "name": "webmozart/assert",
1491 | "version": "1.2.0",
1492 | "source": {
1493 | "type": "git",
1494 | "url": "https://github.com/webmozart/assert.git",
1495 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
1496 | },
1497 | "dist": {
1498 | "type": "zip",
1499 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
1500 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
1501 | "shasum": ""
1502 | },
1503 | "require": {
1504 | "php": "^5.3.3 || ^7.0"
1505 | },
1506 | "require-dev": {
1507 | "phpunit/phpunit": "^4.6",
1508 | "sebastian/version": "^1.0.1"
1509 | },
1510 | "type": "library",
1511 | "extra": {
1512 | "branch-alias": {
1513 | "dev-master": "1.3-dev"
1514 | }
1515 | },
1516 | "autoload": {
1517 | "psr-4": {
1518 | "Webmozart\\Assert\\": "src/"
1519 | }
1520 | },
1521 | "notification-url": "https://packagist.org/downloads/",
1522 | "license": [
1523 | "MIT"
1524 | ],
1525 | "authors": [
1526 | {
1527 | "name": "Bernhard Schussek",
1528 | "email": "bschussek@gmail.com"
1529 | }
1530 | ],
1531 | "description": "Assertions to validate method input/output with nice error messages.",
1532 | "keywords": [
1533 | "assert",
1534 | "check",
1535 | "validate"
1536 | ],
1537 | "time": "2016-11-23T20:04:58+00:00"
1538 | }
1539 | ],
1540 | "aliases": [],
1541 | "minimum-stability": "stable",
1542 | "stability-flags": [],
1543 | "prefer-stable": false,
1544 | "prefer-lowest": false,
1545 | "platform": {
1546 | "php": ">=5.5.9"
1547 | },
1548 | "platform-dev": []
1549 | }
1550 |
--------------------------------------------------------------------------------
/config/report.php:
--------------------------------------------------------------------------------
1 | [
5 | 'phantom' => [
6 | 'debug' => false,
7 | 'ignore-ssl-errors' => true,
8 | 'load-images' => true,
9 | 'ssl-protocol' => 'any'
10 | ],
11 |
12 | // 72 dpi (web) 595 X 842 pixels
13 | // 300 dpi (print) = 2480 X 3508 pixels
14 | // 600 dpi (print) = 4960 X 7016 pixels
15 | 'viewport' => [
16 | 'larger' => '3508',
17 | 'smaller' => '2480'
18 | ],
19 |
20 | 'page' => [
21 | 'margin' => '{top: "20px", right: "20px", bottom: "20px", left: "20px"}',
22 |
23 | //Options = ['landscape', 'portrait']
24 | 'orientation' => 'portrait',
25 |
26 | //Options = ['A4', 'A3', 'Letter']
27 | 'format' => 'A4'
28 | ],
29 |
30 | 'footer' => [
31 | 'height' => '25px',
32 | ],
33 |
34 | 'header' => [
35 | 'height' => '45px',
36 | ]
37 | ],
38 | 'image' => [
39 | 'phantom' => [
40 | 'debug' => false,
41 | 'ignore-ssl-errors' => true,
42 | 'load-images' => true,
43 | 'ssl-protocol' => 'any'
44 | ],
45 |
46 | // 72 dpi (web) 595 X 842 pixels
47 | // 300 dpi (print) = 2480 X 3508 pixels
48 | // 600 dpi (print) = 4960 X 7016 pixels
49 | 'viewport' => [
50 | 'larger' => '842',
51 | 'smaller' => '595'
52 | ],
53 |
54 | 'page' => [
55 | 'margin' => '{top: "20px", right: "20px", bottom: "20px", left: "20px"}',
56 |
57 | //Options = ['landscape', 'portrait']
58 | 'orientation' => 'portrait',
59 |
60 | //Options = ['BMP', 'JPG', 'JPEG', 'PNG']
61 | 'format' => 'JPG'
62 | ],
63 |
64 | 'footer' => [
65 | 'height' => '25px',
66 | ],
67 |
68 | 'header' => [
69 | 'height' => '45px',
70 | ]
71 | ],
72 | 'html' => [
73 | ]
74 | ];
75 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 |
3 | services:
4 | web:
5 | image: fireguard/php-nginx
6 | ports:
7 | - "80:80"
8 | environment:
9 | GIT_EMAIL: ''
10 | GIT_USER_NAME: ''
11 | volumes:
12 | - ./:/project
13 |
--------------------------------------------------------------------------------
/examples/report-boleto.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fireguard/report/482534bd1ca4606ddf7466555cbb737c0b1ab806/examples/report-boleto.pdf
--------------------------------------------------------------------------------
/examples/report1-html.php:
--------------------------------------------------------------------------------
1 | ';
7 | $header.= ' THE MANAGEMENT REPORT TITLE';
8 | $header.= '';
9 |
10 | $footer = '';
11 | $footer.= ' Page @{{ numPage }} of @{{ totalPages }}';
12 | $footer.= '
';
13 |
14 | $report = new \Fireguard\Report\Report($html, $header, $footer);
15 | $exporter = new \Fireguard\Report\Exporters\HtmlExporter();
16 |
17 | // Option 1
18 | // Return with Symfony\Component\HttpFoundation\Response
19 | $file = $exporter
20 | ->response($report)
21 | ->send();
22 |
23 | // Option 2
24 | // Manual Return
25 | $file = $exporter->generate($report);
26 | echo file_get_contents($file);
27 |
--------------------------------------------------------------------------------
/examples/report1-image.php:
--------------------------------------------------------------------------------
1 | ';
7 | $header.= ' THE MANAGEMENT REPORT TITLE';
8 | $header.= '';
9 |
10 | $footer = '';
11 | $footer.= ' Page @{{ numPage }} of @{{ totalPages }}';
12 | $footer.= '
';
13 |
14 | $report = new \Fireguard\Report\Report($html, $header, $footer);
15 | $exporter = new \Fireguard\Report\Exporters\ImageExporter('', 'report1-to-image');
16 |
17 | // Option 1
18 | // Return with Symfony\Component\HttpFoundation\Response
19 | $file = $exporter->setOrientation('landscape')
20 | ->setFormat('PNG')
21 | ->response($report)
22 | ->send();
23 |
24 | // Option 2
25 | // Manual Return
26 | $file = $exporter->setOrientation('landscape')
27 | ->setFormat('PNG')
28 | ->generate($report);
29 |
30 | header('Content-type: image/jpg');
31 | header('Content-Length: ' . filesize($file));
32 | @readfile($file);
33 |
--------------------------------------------------------------------------------
/examples/report1-pdf.php:
--------------------------------------------------------------------------------
1 | ';
7 | $header.= ' THE MANAGEMENT REPORT TITLE';
8 | $header.= '';
9 |
10 | $footer = '';
11 | $footer.= ' Page @{{ numPage }} of @{{ totalPages }}';
12 | $footer.= '
';
13 |
14 | $report = new \Fireguard\Report\Report($html, $header, $footer);
15 | $exporter = new \Fireguard\Report\Exporters\PdfExporter('', 'report1-to-pdf');
16 |
17 | // Option 1
18 | // Return with Symfony\Component\HttpFoundation\Response
19 | $exporter
20 | ->setOrientation('landscape')
21 | ->setFormat('A3')
22 | ->setMargin('0px')
23 | ->response($report)
24 | ->send();
25 |
26 |
27 | // Option 2
28 | // Manual Return
29 | $file = $exporter->setOrientation('landscape')
30 | ->setFormat('A3')
31 | ->setMargin('0px')
32 | ->generate($report);
33 |
34 | header('Content-type: application/pdf');
35 | header('Content-Disposition: inline; filename="report1-to-pdf.pdf"');
36 | header('Content-Transfer-Encoding: binary');
37 | header('Content-Length: ' . filesize($file));
38 | header('Accept-Ranges: bytes');
39 |
40 | @readfile($file);
41 |
--------------------------------------------------------------------------------
/examples/report1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Fireguard
7 |
8 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | Days |
45 | In Sales Office |
46 | Out Sales Office |
47 | In Office Visits |
48 | Out Side Calls |
49 | Others |
50 | Total |
51 |
52 |
53 |
54 |
55 | Monday |
56 | $14.00 |
57 | $23.00 |
58 | $4.00 |
59 | $45.00 |
60 | $10.00 |
61 | $96.00 |
62 |
63 |
64 | Tuesday |
65 | $14.00 |
66 | $23.00 |
67 | $4.00 |
68 | $45.00 |
69 | $10.00 |
70 | $96.00 |
71 |
72 |
73 | Wednesday |
74 | $14.00 |
75 | $23.00 |
76 | $4.00 |
77 | $45.00 |
78 | $10.00 |
79 | $96.00 |
80 |
81 |
82 | Thursday |
83 | $14.00 |
84 | $23.00 |
85 | $4.00 |
86 | $45.00 |
87 | $10.00 |
88 | $96.00 |
89 |
90 |
91 | Friday |
92 | $14.00 |
93 | $23.00 |
94 | $4.00 |
95 | $45.00 |
96 | $10.00 |
97 | $96.00 |
98 |
99 |
100 | Saturday |
101 | $14.00 |
102 | $23.00 |
103 | $4.00 |
104 | $45.00 |
105 | $10.00 |
106 | $96.00 |
107 |
108 |
109 | Sunday |
110 | $14.00 |
111 | $23.00 |
112 | $4.00 |
113 | $45.00 |
114 | $10.00 |
115 | $96.00 |
116 |
117 |
118 | Total |
119 | $14.00 |
120 | $23.00 |
121 | $4.00 |
122 | $45.00 |
123 | $10.00 |
124 | $96.00 |
125 |
126 |
127 |
128 |
129 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/
14 |
15 |
16 |
17 |
18 | ./src/Report/
19 |
20 |
21 | ./vendor
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/Report/Contracts/ExporterInterface.php:
--------------------------------------------------------------------------------
1 | configure($config);
63 | $this->setPath($path);
64 | $this->setFileName($fileName);
65 | }
66 |
67 | /**
68 | * @return string
69 | */
70 | public function getPath()
71 | {
72 | return $this->path;
73 | }
74 |
75 | /**
76 | * @param string $path
77 | * @param unix_permission $mode Permission
78 | * @return ExporterInterface
79 | */
80 | public function setPath($path, $mode = 0777)
81 | {
82 | $tmpPath = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
83 | if ( empty($path)
84 | || ( !file_exists($path) && !mkdir($path, $mode, true) )
85 | // || ( !empty($this->fileName) && !(touch($tmpPath.$this->getFileName(), $mode)))
86 | ) {
87 | $this->path = sys_get_temp_dir().DIRECTORY_SEPARATOR;
88 | return $this;
89 | }
90 |
91 | $this->path = $tmpPath;
92 | return $this;
93 | }
94 |
95 | /**
96 | * @return string
97 | */
98 | public function getFileName()
99 | {
100 | return $this->fileName;
101 | }
102 |
103 | /**
104 | * @param $fileName
105 | * @return ExporterInterface
106 | */
107 | public function setFileName($fileName)
108 | {
109 | $tmpFileName = $fileName.$this->extension;
110 | if ( empty($fileName)
111 | || (file_exists($this->getPath().$tmpFileName) && !is_writable($this->getPath().$tmpFileName) )
112 | ) {
113 | $this->fileName = 'report-'.sha1(uniqid(rand(), true));
114 | return $this;
115 | }
116 | $this->fileName = $fileName;
117 | return $this;
118 | }
119 |
120 | /**
121 | * @return string
122 | */
123 | public function getFullPath()
124 | {
125 | return $this->getPath().$this->getFileName().$this->extension;
126 | }
127 |
128 | /**
129 | * @return int
130 | */
131 | public function getTimeout()
132 | {
133 | return $this->timeout;
134 | }
135 |
136 | /**
137 | * @param int $timeout
138 | * @return ExporterInterface
139 | */
140 | public function setTimeout($timeout)
141 | {
142 | $this->timeout = $timeout;
143 | return $this;
144 | }
145 |
146 | /**
147 | * @return array
148 | */
149 | public function getConfigDefaultOptions()
150 | {
151 | return $this->configDefaultOptions;
152 | }
153 |
154 | /**
155 | * @param array $options
156 | * @return ExporterInterface
157 | */
158 | public function setConfigDefaultOptions($options)
159 | {
160 | $this->configDefaultOptions = $options;
161 | return $this;
162 | }
163 |
164 | /**
165 | * @return array
166 | */
167 | public function getConfigValidOptions()
168 | {
169 | return $this->configValidOptions;
170 | }
171 |
172 | /**
173 | * @param array $options
174 | * @return ExporterInterface
175 | */
176 | public function setConfigValidOptions(array $options)
177 | {
178 | $this->configValidOptions = $options;
179 | return $this;
180 | }
181 |
182 | public function getDefaultConfiguration()
183 | {
184 | $ds = DIRECTORY_SEPARATOR;
185 | $path = __DIR__.$ds.'..'.$ds.'..'.$ds.'..'.$ds.'config'.$ds.'report.php';
186 | return file_exists($path) ? include $path : [];
187 | }
188 |
189 | /**
190 | * Compress html e js removed comments e break lines
191 | * @param $buffer
192 | * @return mixed
193 | */
194 | public function compress($buffer)
195 | {
196 | // remove comments
197 | $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
198 |
199 | // remove tabs, spaces, newlines, etc.
200 | $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), ' ', $buffer);
201 | return trim($buffer);
202 | }
203 |
204 | /**
205 | * @param array $config
206 | * @return ExporterInterface
207 | */
208 | abstract public function configure(array $config);
209 |
210 | /**
211 | * @param ReportInterface $report
212 | * @return string
213 | */
214 | abstract public function generate(ReportInterface $report);
215 |
216 |
217 | /**
218 | * @return string
219 | */
220 | abstract public function getMimeType();
221 |
222 |
223 | /**
224 | * @param boolean $forceDownload
225 | * @param ReportInterface $report
226 | * @return Response
227 | */
228 | public function response(ReportInterface $report, $forceDownload = false)
229 | {
230 | $file = $this->generate($report);
231 |
232 | $response = new Response( file_get_contents($file) , Response::HTTP_OK, ['Content-Type' => $this->getMimeType()]);
233 | if ($forceDownload) {
234 | $disposition = $response->headers->makeDisposition(
235 | ResponseHeaderBag::DISPOSITION_ATTACHMENT,
236 | $this->getFileName().$this->extension
237 | );
238 | $response->headers->set('Content-Disposition', $disposition);
239 | }
240 | return $response;
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/src/Report/Exporters/AbstractPhantomExporter.php:
--------------------------------------------------------------------------------
1 | 'bool',
41 | 'cookies-file' => 'string',
42 | 'disk-cache' => 'bool',
43 | 'load-images' => 'bool',
44 | 'local-storage-path' => 'string',
45 | 'local-storage-quota' => 'integer',
46 | 'local-to-remote-url-access' => 'bool',
47 | 'max-disk-cache-size' => 'integer', //in KB
48 | 'output-encoding' => 'string',
49 | 'proxy' => 'string', //192.168.1.42:8080
50 | 'proxy-type' => ['http', 'socks5', 'none'],
51 | 'proxy-auth' => 'string', //username:password
52 | 'script-encoding' => 'script',
53 | 'ssl-protocol' => [ 'sslv3', 'sslv2', 'tlsv1', 'any'],
54 | 'ssl-certificates-path' => 'string',
55 | 'web-security' => 'bool',
56 | 'webdriver' => 'string',
57 | 'webdriver-selenium-grid-hub' => 'string'
58 | ];
59 |
60 | protected function createHtmlFiles(ReportInterface $report)
61 | {
62 | $exporter = new HtmlExporter($this->getPath(), $this->fileName);
63 | $this->htmlBodyPath = $exporter->saveFile($report->getContent());
64 |
65 | $this->htmlHeader = $this->processInlineHtml($report->getHeader());
66 |
67 | $this->htmlFooter = $this->processInlineHtml($report->getFooter());
68 | }
69 |
70 | /**
71 | * @return string
72 | */
73 | public function getFormat()
74 | {
75 | return !empty($this->config['page']['format']) ? $this->config['page']['format'] : $this->format;
76 | }
77 |
78 | /**
79 | * @param string $format
80 | * @return AbstractPhantomExporter
81 | */
82 | public function setFormat($format)
83 | {
84 | if (in_array($format, $this->validFormats) ) $this->config['page']['format'] = $format;
85 | return $this;
86 | }
87 |
88 | /**
89 | * @return string
90 | */
91 | public function getOrientation()
92 | {
93 | return !empty($this->config['page']['orientation']) ? $this->config['page']['orientation'] : 'portrait';
94 | }
95 |
96 | /**
97 | * @param $orientation
98 | * @return AbstractPhantomExporter
99 | */
100 | public function setOrientation($orientation){
101 | if( in_array($orientation, ['landscape', 'portrait']) ) $this->config['page']['orientation'] = $orientation;
102 | return $this;
103 | }
104 |
105 | /**
106 | * @return string
107 | */
108 | public function getMargin()
109 | {
110 | return !empty($this->config['page']['margin'])
111 | ? $this->config['page']['margin']
112 | : '{top: "20px", right: "20px", bottom: "20px", left: "20px"}';
113 | }
114 |
115 | /**
116 | * @param string $margin
117 | * @return AbstractPhantomExporter
118 | */
119 | public function setMargin($margin)
120 | {
121 | $this->config['page']['margin'] =(str_replace('{', '', $margin) == $margin) ? '"'.$margin.'"' : $margin;
122 | return $this;
123 | }
124 |
125 | /**
126 | /**
127 | * @return string
128 | */
129 | public function getBinaryPath()
130 | {
131 | return $this->binaryPath;
132 | }
133 |
134 | /**
135 | * @param $binaryPath
136 | * @return AbstractPhantomExporter
137 | */
138 | public function setBinaryPath($binaryPath){
139 | $this->binaryPath = $binaryPath;
140 | return $this;
141 | }
142 |
143 | /**
144 | * @return array
145 | */
146 | public function getCommandOptions()
147 | {
148 | return $this->commandOptions;
149 | }
150 |
151 | /**
152 | * @param array $options
153 | * @return AbstractPhantomExporter
154 | */
155 | public function setCommandOptions(array $options)
156 | {
157 | $this->commandOptions = $options;
158 | return $this;
159 | }
160 |
161 | /**
162 | * @param string $option
163 | * @param string $value
164 | * @return AbstractPhantomExporter
165 | */
166 | public function addCommandOption($option, $value)
167 | {
168 | if ( isset($this->configValidOptions[$option])) {
169 | $validOptions = $this->configValidOptions[$option];
170 | if (is_array($validOptions) && in_array($value, $validOptions)) {
171 | $this->commandOptions[$option] = $value;
172 | return $this;
173 | }
174 | switch ($validOptions) {
175 | case 'string' :
176 | if (!empty($value)) $this->commandOptions[$option] = $value;
177 | break;
178 | case 'bool' :
179 | if (is_bool($value)) $this->commandOptions[$option] = $value;
180 | break;
181 | default:
182 | $this->commandOptions[$option] = $value;
183 | break;
184 | }
185 | }
186 |
187 | return $this;
188 | }
189 |
190 | /**
191 | * Prefix the input path for windows versions of PhantomJS
192 | * @param string $path
193 | * @param string $operationalSystem
194 | * @return string
195 | */
196 | public function prefixOsPath($path, $operationalSystem = PHP_OS)
197 | {
198 | if (strtoupper(substr($operationalSystem, 0, 3)) === 'WIN') {
199 | return 'file:///' . str_replace('\\', '/', $path);
200 | }
201 |
202 | return $path;
203 | }
204 |
205 | /**
206 | * @return string Command line string
207 | */
208 | public function mountCommandOptions()
209 | {
210 | $options = '';
211 | foreach ($this->commandOptions as $key => $value) {
212 | if ( is_bool($value) ) $value = ($value) ? 'true' : 'false';
213 | $options .= '--'.$key.'='.$value.' ';
214 | }
215 |
216 | return rtrim($options, ' ');
217 | }
218 |
219 | public function getFooterHeight()
220 | {
221 | return isset($this->config['footer']['height']) ? $this->config['footer']['height'] : '25px';
222 | }
223 |
224 | public function getHeaderHeight()
225 | {
226 |
227 | return isset($this->config['header']['height']) ? $this->config['header']['height'] : '45px';
228 | }
229 |
230 | protected function getHeaderScript()
231 | {
232 | return $this->getScript($this->htmlHeader, $this->getHeaderHeight());
233 | }
234 |
235 | protected function getFooterScript()
236 | {
237 | return $this->getScript($this->htmlFooter, $this->getFooterHeight());
238 | }
239 |
240 | protected function getScript($html, $heigth)
241 | {
242 | if (empty($html)) return '';
243 | $script = ' height: "'.$heigth.'",';
244 | $script.= ' contents: phantom.callback(function(numPage, totalPages) {';
245 | $script.= ' return "'.$html.'";"';
246 | $script.= '"})';
247 | return $script;
248 | }
249 |
250 | protected function getViewPortWidth()
251 | {
252 | $viewport = $this->config['viewport'];
253 | return $this->config['page']['orientation'] == 'landscape' ? $viewport['larger'] : $viewport['smaller'];
254 | }
255 |
256 | protected function getViewPortHeight()
257 | {
258 | $viewport = $this->config['viewport'];
259 | return $this->config['page']['orientation'] == 'landscape' ? $viewport['smaller'] : $viewport['larger'];
260 | }
261 |
262 | protected function processInlineHtml($html)
263 | {
264 | $clearHtml = str_replace('"', '\'', $html);
265 | $clearHtml = str_replace("@{{", '" + ', $clearHtml);
266 | $clearHtml = str_replace("{{", '" + ', $clearHtml);
267 | return $this->compress(str_replace("}}", ' + "', $clearHtml));
268 | }
269 |
270 | protected function saveFinishFile()
271 | {
272 | $command = implode(' ', [
273 | $this->binaryPath,
274 | $this->mountCommandOptions(),
275 | $this->mountScriptForExport(),
276 | $this->prefixOsPath($this->htmlBodyPath),
277 | $this->getFullPath()
278 | ]);
279 |
280 | $process = new Process($command, $this->getPath());
281 | $process->setTimeout($this->timeout);
282 | $process->run();
283 |
284 | if ($errorOutput = $process->getErrorOutput()) {
285 | throw new RuntimeException('PhantomJS: ' . $errorOutput);
286 | }
287 |
288 | // Remove temporary html file
289 | @unlink($this->htmlBodyPath);
290 |
291 | return $this->getFullPath();
292 | }
293 |
294 | /**
295 | * @return string Path for generated script
296 | */
297 | public function mountScriptForExport()
298 | {
299 | $script = '
300 | var fs = require("fs");
301 | var args = require("system").args;
302 | var page = require("webpage").create();
303 |
304 | page.viewportSize = { width: '.$this->getViewPortWidth().', height: '.$this->getViewPortHeight().'};
305 |
306 | page.paperSize = {
307 | format: "'.$this->getFormat().'",
308 | orientation: "'.$this->getOrientation().'",
309 | margin: '.$this->getMargin().',
310 | footer: {
311 | '.$this->getFooterScript().'
312 | },
313 | header: {
314 | '.$this->getHeaderScript().'
315 | },
316 | };
317 |
318 | page.open( args[1], function( status ) {
319 |
320 | if ( status === "success" ) {
321 | page.render( args[2] );
322 | }
323 |
324 | phantom.exit();
325 | });
326 |
327 | ';
328 | $filePath = tempnam(sys_get_temp_dir(), 'report-script-');
329 | file_put_contents($filePath, $this->compress($script));
330 | return $filePath;
331 | }
332 | }
333 |
--------------------------------------------------------------------------------
/src/Report/Exporters/HtmlExporter.php:
--------------------------------------------------------------------------------
1 | extension = '.html';
13 | $defaultConfig = $this->getDefaultConfiguration();
14 | $this->config = array_replace_recursive($defaultConfig['html'] , $config);
15 | return $this;
16 | }
17 |
18 | public function generate(ReportInterface $report)
19 | {
20 | $html = ''.$this->fileName.'';
21 | $html.= '';
22 | $html.= $this->getProcessedHeader($report).$report->getContent().$this->getProcessedFooter($report);
23 | $html.= '';
24 | return $this->saveFile($html);
25 | }
26 |
27 | /**
28 | * @return string
29 | */
30 | public function getMimeType()
31 | {
32 | return 'text/html';
33 | }
34 |
35 | public function getProcessedHeader(ReportInterface $report)
36 | {
37 | return $this->processInlineHtml($report->getHeader());
38 | }
39 |
40 | public function getProcessedFooter(ReportInterface $report)
41 | {
42 | return $this->processInlineHtml($report->getFooter());
43 | }
44 |
45 | public function saveFile($content)
46 | {
47 | file_put_contents($this->getFullPath(), $content);
48 | return $this->getFullPath();
49 | }
50 |
51 | protected function processInlineHtml($html)
52 | {
53 | $clearHtml = str_replace('"', '\'', $html);
54 | $clearHtml = str_replace("@{{", '', $clearHtml);
55 | $clearHtml = str_replace("{{", '', $clearHtml);
56 | $clearHtml = str_replace('numPage', ' 1 ', $clearHtml);
57 | $clearHtml = str_replace('totalPages', ' 1 ', $clearHtml);
58 | return $this->compress(str_replace("}}", '', $clearHtml));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Report/Exporters/ImageExporter.php:
--------------------------------------------------------------------------------
1 | extension = '.'.strtolower($this->format);
29 | $defaultConfig = $this->getDefaultConfiguration();
30 | $this->config = array_replace_recursive($defaultConfig['image'] , $config);
31 |
32 | $this->setConfigDefaultOptions($this->config['phantom']);
33 |
34 | $this->commandOptions = $this->configDefaultOptions;
35 | $this->setBinaryPath((new PhantomBinary)->getBin());
36 |
37 | return $this;
38 | }
39 |
40 | /**
41 | * @param string $format
42 | * @return AbstractPhantomExporter
43 | */
44 | public function setFormat($format)
45 | {
46 | parent::setFormat($format);
47 | $this->extension = '.'.strtolower($this->getFormat());
48 | return $this;
49 | }
50 |
51 | /**
52 | * @param ReportInterface $report
53 | * @return string
54 | */
55 | public function generate(ReportInterface $report)
56 | {
57 | $this->htmlBodyPath = $this->generateHtmlWithAllReportContent($report);
58 | return $this->saveFinishFile();
59 | }
60 |
61 | /**
62 | * @return string
63 | */
64 | public function getMimeType()
65 | {
66 | return 'image/'.mb_strtolower($this->format);
67 | }
68 |
69 | protected function generateHtmlWithAllReportContent(ReportInterface $report)
70 | {
71 | $exporter = new HtmlExporter($this->getPath(), $this->fileName);
72 | return $exporter->generate($report);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Report/Exporters/PdfExporter.php:
--------------------------------------------------------------------------------
1 | extension = '.pdf';
29 | $defaultConfig = $this->getDefaultConfiguration();
30 | $this->config = array_replace_recursive($defaultConfig['pdf'] , $config);
31 |
32 | $this->setConfigDefaultOptions($this->config['phantom']);
33 |
34 | $this->commandOptions = $this->configDefaultOptions;
35 | $this->setBinaryPath((new PhantomBinary)->getBin());
36 |
37 | return $this;
38 | }
39 |
40 | /**
41 | * @param ReportInterface $report
42 | * @return string
43 | */
44 | public function generate(ReportInterface $report)
45 | {
46 | $this->createHtmlFiles($report);
47 | return $this->saveFinishFile();
48 | }
49 |
50 | /**
51 | * @return string
52 | */
53 | public function getMimeType()
54 | {
55 | return 'application/pdf';
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Report/Laravel/ReportServiceProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
17 | __DIR__.'/../../../config/report.php' => config_path('report.php')
18 | ], 'config');
19 | }
20 |
21 | /**
22 | * Register the service provider.
23 | *
24 | * @return void
25 | */
26 | public function register()
27 | {
28 | $this->mergeConfigFrom(__DIR__.'/../../../config/report.php', 'report');
29 |
30 | $configDefaultExporter = $this->app['config']['report.default-exporter'];
31 | $defaultExporter = (class_exists($configDefaultExporter)) ? $configDefaultExporter : PdfExporter::class;
32 |
33 | $storagePath = ( !empty($this->app['config']['report.storage-path']) && file_exists($this->app['config']['report.storage-path']))
34 | ? $this->app['config']['report.storage-path']
35 | : storage_path('app');
36 |
37 | // Register Default Exporter
38 | $this->app->bind( ExporterInterface::class, $defaultExporter );
39 |
40 | $this->app->bind( ReportInterface::class, Report::class );
41 |
42 | $this->app->bind( HtmlExporter::class, function ($app) use ($storagePath) {
43 | return (new HtmlExporter())
44 | ->setPath($storagePath)
45 | ->configure($app['config']['report.html']);
46 | });
47 |
48 | $this->app->bind( PdfExporter::class, function ($app) use ($storagePath) {
49 | return (new PdfExporter())
50 | ->setPath($storagePath)
51 | ->configure($app['config']['report.pdf']);
52 | });
53 |
54 | $this->app->bind( ImageExporter::class, function ($app) use ($storagePath) {
55 | return (new ImageExporter())
56 | ->setPath($storagePath)
57 | ->configure($app['config']['report.image']);
58 | });
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/Report/Report.php:
--------------------------------------------------------------------------------
1 | content = $content;
38 | $this->header = $header;
39 | $this->footer = $footer;
40 | $this->config = $config;
41 | }
42 |
43 | /**
44 | * @return string
45 | */
46 | public function getContent()
47 | {
48 | $resources = $this->getResourcesStringInHeaderAndFooter();
49 | return $resources.$this->content;
50 | }
51 |
52 | /**
53 | * @param string $content
54 | * @return ReportInterface
55 | */
56 | public function setContent($content)
57 | {
58 | $this->content = $content;
59 | return $this;
60 | }
61 |
62 | /**
63 | * @return string
64 | */
65 | public function getHeader()
66 | {
67 | return $this->header;
68 | }
69 |
70 | /**
71 | * @param string $header
72 | * @return Report
73 | */
74 | public function setHeader($header)
75 | {
76 | $this->header = $header;
77 | return $this;
78 | }
79 |
80 | /**
81 | * @return string
82 | */
83 | public function getFooter()
84 | {
85 | return $this->footer;
86 | }
87 |
88 | /**
89 | * @param string $footer
90 | * @return Report
91 | */
92 | public function setFooter($footer)
93 | {
94 | $this->footer = $footer;
95 | return $this;
96 | }
97 |
98 | /**
99 | * @return string
100 | */
101 | public function getConfig()
102 | {
103 | return $this->config;
104 | }
105 |
106 | /**
107 | * @param string $config
108 | * @return Report
109 | */
110 | public function setConfig($config)
111 | {
112 | $this->config = $config;
113 | return $this;
114 | }
115 |
116 | protected function getResourcesStringInHeaderAndFooter()
117 | {
118 | $images = $this->getAllImagesInHeaderAndFooter();
119 | $resources = '';
120 | foreach ($images as $image) {
121 | $resources .= '
';
122 | }
123 | return $resources;
124 | }
125 |
126 | protected function getAllImagesInHeaderAndFooter()
127 | {
128 | $doc = new \DOMDocument();
129 | $html = $this->getHeader().$this->getFooter();
130 | if (!empty($html)) {
131 | libxml_use_internal_errors(true);
132 | $doc->loadHTML($html);
133 | libxml_clear_errors();
134 | $imageTags = $doc->getElementsByTagName('img');
135 |
136 | $result = [];
137 | foreach($imageTags as $tag) {
138 | $result[] = $tag->getAttribute('src');
139 | }
140 | return array_unique($result);
141 | }
142 | return [];
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/tests/Report/Exporters/AbstractExporterTest.php:
--------------------------------------------------------------------------------
1 | exporter = $this->getMockForAbstractClass(AbstractExporter::class);
15 | }
16 |
17 | public function testExporterConstructor()
18 | {
19 | $this->assertFileExists($this->exporter->getPath());
20 | $this->assertTrue( (
21 | !file_exists($this->exporter->getFullPath())
22 | || is_writable($this->exporter->getFullPath())
23 | ), 'Is not writable path generated');
24 |
25 | $tmpName = str_replace(sys_get_temp_dir(), '', tempnam(sys_get_temp_dir(), 'test-report'));
26 | $exporter = $this->getMockForAbstractClass(AbstractExporter::class, ['', $tmpName]);
27 | $this->assertEquals($tmpName, $exporter->getFileName());
28 | }
29 |
30 | public function testSetPath()
31 | {
32 | $exporter = $this->getMockForAbstractClass(AbstractExporter::class);
33 | $path = sys_get_temp_dir().DIRECTORY_SEPARATOR.sha1(time()).DIRECTORY_SEPARATOR;
34 | $exporter->setPath($path);
35 | $this->assertEquals($path, $exporter->getPath());
36 | }
37 |
38 | public function testSetFileName()
39 | {
40 | $exporter = $this->getMockForAbstractClass(AbstractExporter::class);
41 | $newName = str_replace($exporter->getPath(), '', tempnam($exporter->getPath(), 'test-report'));
42 | $exporter->setFileName($newName);
43 | $this->assertEquals($newName, $exporter->getFileName());
44 | unlink($exporter->getFullPath());
45 | }
46 |
47 | public function testGetFullPath()
48 | {
49 | $path = rtrim( $this->exporter->getPath(), DIRECTORY_SEPARATOR );
50 | $this->assertEquals($path.DIRECTORY_SEPARATOR.$this->exporter->getFileName(), $this->exporter->getFullPath());
51 | }
52 |
53 | public function testSetTimeout()
54 | {
55 | $exporter = $this->getMockForAbstractClass(AbstractExporter::class);
56 | $exporter->setTimeout(100);
57 | $this->assertEquals(100, $exporter->getTimeout());
58 | }
59 |
60 | public function testSetConfigDefaultOptions()
61 | {
62 | $exporter = new PdfExporter();
63 | $exporter->setConfigDefaultOptions([]);
64 | $this->assertEquals([], $exporter->getConfigDefaultOptions());
65 | }
66 |
67 | public function testSetConfigValidOptions()
68 | {
69 | $exporter = new PdfExporter();
70 | $exporter->setConfigValidOptions([]);
71 | $this->assertEquals([], $exporter->getConfigValidOptions());
72 | }
73 |
74 | public function testCompressHtmlAndJsStrings()
75 | {
76 | // Test Remove Space
77 | $html = 'Teste
'.PHP_EOL.'Teste';
78 | $this->assertEquals('Teste
Teste', $this->exporter->compress($html));
79 |
80 | // Test Remove Coments
81 | $comment = '/**'.PHP_EOL.'* Compress html e js removed comments e break lines'.PHP_EOL;
82 | $comment.= '* @param $buffer'.PHP_EOL.'* @return mixed'.PHP_EOL.'*/ function test()';
83 | $this->assertEquals('function test()', $this->exporter->compress($comment));
84 | }
85 |
86 | public function testGetDefaultConfiguration()
87 | {
88 | $config = $this->exporter->getDefaultConfiguration();
89 | $this->assertArrayHasKey('pdf', $config);
90 | $this->assertArrayHasKey('phantom', $config['pdf']);
91 | $this->assertArrayHasKey('html', $config);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/tests/Report/Exporters/AbstractPhantomExporterTest.php:
--------------------------------------------------------------------------------
1 | exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
20 | $tmpConfig = $this->exporter->getDefaultConfiguration();
21 | $this->configDefault = $tmpConfig['pdf'];
22 | }
23 |
24 | public function testGetDefaultOrientation()
25 | {
26 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
27 | $this->assertEquals($this->configDefault['page']['orientation'], $exporter->getOrientation());
28 | }
29 |
30 | public function testSetValidOrientation()
31 | {
32 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
33 | $exporter->setOrientation('landscape');
34 | $this->assertEquals('landscape', $exporter->getOrientation());
35 |
36 | }
37 |
38 | public function testSetInvalidOrientation()
39 | {
40 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
41 | $exporter->setOrientation('invalid-orientation');
42 | $this->assertEquals($this->configDefault['page']['orientation'], $exporter->getOrientation());
43 | }
44 |
45 | public function testGetMargin()
46 | {
47 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
48 | $this->assertEquals($this->configDefault['page']['margin'], $exporter->getMargin());
49 | }
50 |
51 | public function testSetMargin()
52 | {
53 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
54 | $exporter->setMargin('{top: "0px", right: "0px", bottom: "0px", left: "0px"}');
55 | $this->assertEquals('{top: "0px", right: "0px", bottom: "0px", left: "0px"}', $exporter->getMargin());
56 |
57 | $exporter->setMargin('5px');
58 | $this->assertEquals('"5px"', $exporter->getMargin());
59 |
60 | }
61 |
62 | public function testSetCommandOptions()
63 | {
64 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
65 | $options = [
66 | 'debug' => false,
67 | 'ignore-ssl-errors' => true,
68 | 'load-images' => true,
69 | 'ssl-protocol' => 'any'
70 | ];
71 | $exporter->setCommandOptions($options);
72 | $this->assertEquals($options, $exporter->getCommandOptions());
73 | }
74 |
75 | public function testSetBinayPath()
76 | {
77 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
78 | $exporter->setBinaryPath('/path/for/binary');
79 | $this->assertEquals('/path/for/binary', $exporter->getBinaryPath());
80 | }
81 |
82 | public function testPrefixerFilePath()
83 | {
84 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
85 |
86 | $this->assertEquals('/var/www', $exporter->prefixOsPath('/var/www', 'LINUX'));
87 |
88 | $this->assertEquals('file:///c:/www', $exporter->prefixOsPath('c:/www', 'WIN'));
89 | }
90 |
91 | public function testAddCommandOption()
92 | {
93 | $exporter = $this->getMockForAbstractClass(AbstractPhantomExporter::class);
94 | $exporter->setConfigValidOptions([
95 | 'web-security' => 'bool',
96 | 'disk-cache' => 'bool',
97 | 'local-storage-path' => 'string',
98 | 'test-option' => 'not-validated-type',
99 | 'ssl-protocol' => [ 'sslv3', 'sslv2', 'tlsv1', 'any']
100 | ]);
101 |
102 | // Ignore Invalid Option
103 | $options = $exporter->getCommandOptions();
104 | $exporter->addCommandOption('command-option-include', true);
105 | $this->assertEquals($options, $exporter->getCommandOptions());
106 |
107 | // Ignore Invalid Value
108 | $exporter->addCommandOption('web-security', 'invalid-expected-bool');
109 | $this->assertEquals($options, $exporter->getCommandOptions());
110 |
111 | // Define Valid Value for Bool
112 | $exporter->addCommandOption('disk-cache', true);
113 | $this->assertArrayHasKey('disk-cache', $exporter->getCommandOptions());
114 |
115 | // Define Valid Value for Array
116 | $exporter->addCommandOption('ssl-protocol', 'any');
117 | $options = $exporter->getCommandOptions();
118 | $this->assertArrayHasKey('ssl-protocol', $options);
119 | $this->assertEquals('any', $options['ssl-protocol']);
120 |
121 | // Define Valid Value for String
122 | $exporter->addCommandOption('local-storage-path', 'path-string');
123 | $options = $exporter->getCommandOptions();
124 | $this->assertArrayHasKey('local-storage-path', $options);
125 | $this->assertEquals('path-string', $options['local-storage-path']);
126 |
127 | // Define Valid Value for not validated format
128 | $exporter->addCommandOption('test-option', 'any-value');
129 | $options = $exporter->getCommandOptions();
130 | $this->assertArrayHasKey('test-option', $options);
131 | $this->assertEquals('any-value', $options['test-option']);
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/tests/Report/Exporters/HtmlExporterTest.php:
--------------------------------------------------------------------------------
1 | Content',
16 | '',
17 | ''
18 | );
19 | $file = $exporter->generate($report);
20 | $this->assertFileExists($file);
21 | $expectHtml = ''.$exporter->getFileName().'';
22 | $this->assertStringEqualsFile($file, $expectHtml);
23 | }
24 |
25 | public function testGenerateOnlyHeaderReportFile()
26 | {
27 | $exporter = new HtmlExporter();
28 | $report = new Report(
29 | '',
30 | ''
31 | );
32 | $file = $exporter->generate($report);
33 | $this->assertFileExists($file);
34 | $expectHtml = ''.$exporter->getFileName().'';
35 | $this->assertStringEqualsFile($file, $expectHtml);
36 | }
37 |
38 | public function testGenerateOnlyFooterReportFile()
39 | {
40 | $exporter = new HtmlExporter();
41 | $report = new Report(
42 | '',
43 | '',
44 | ''
45 | );
46 | $file = $exporter->generate($report);
47 | $this->assertFileExists($file);
48 | $expectHtml = ''.$exporter->getFileName().'';
49 | $this->assertStringEqualsFile($file, $expectHtml);
50 | }
51 |
52 | public function testCreateResponseInline()
53 | {
54 | $exporter = new HtmlExporter(null, 'test-file-name-inline');
55 | $report = new Report('');
56 | $response = $exporter->response($report);
57 |
58 | $this->assertInstanceOf(Response::class, $response);
59 |
60 | $this->assertFalse(
61 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-inline.html"'),
62 | 'Could not find header to force download'
63 | );
64 |
65 |
66 | $expectHtml = ''.$exporter->getFileName().'';
67 | $this->assertEquals($expectHtml, $response->getContent());
68 | }
69 |
70 | public function testCreateResponseForceDownload()
71 | {
72 | $exporter = new HtmlExporter(null, 'test-file-name-download');
73 | $report = new Report('');
74 | $response = $exporter->response($report, true);
75 |
76 | $this->assertInstanceOf(Response::class, $response);
77 |
78 | $this->assertTrue(
79 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-download.html"'),
80 | 'Could not find header to force download'
81 | );
82 |
83 | $expectHtml = ''.$exporter->getFileName().'';
84 | $this->assertEquals($expectHtml, $response->getContent());
85 | }
86 |
87 |
88 | public function testCreateReportFile()
89 | {
90 | $exporter = new HtmlExporter();
91 | $file = $exporter->saveFile('Aqui entra um html qualquer
');
92 | $this->assertFileExists($file);
93 | $this->assertStringEqualsFile($file, 'Aqui entra um html qualquer
');
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/tests/Report/Exporters/ImageExporterTest.php:
--------------------------------------------------------------------------------
1 | exporter = new ImageExporter();
23 | $tmpConfig = $this->exporter->getDefaultConfiguration();
24 | $this->configDefault = $tmpConfig['image'];
25 | }
26 |
27 | public function testGetDefaultFormat()
28 | {
29 | $exporter = new ImageExporter();
30 | $this->assertEquals($this->configDefault['page']['format'], $exporter->getFormat());
31 | }
32 |
33 | public function testSetValidFormat()
34 | {
35 | $exporter = new ImageExporter();
36 | $exporter->setFormat('PNG');
37 | $this->assertEquals('PNG', $exporter->getFormat());
38 | }
39 |
40 | public function testSetInvalidFormat()
41 | {
42 | $exporter = new ImageExporter();
43 | $exporter->setFormat('invalid-format');
44 | $this->assertEquals($this->configDefault['page']['format'], $exporter->getFormat());
45 | }
46 |
47 | public function testMountCommandLine()
48 | {
49 | $exporter = new ImageExporter();
50 | $options = [
51 | 'debug' => false,
52 | 'ignore-ssl-errors' => true,
53 | 'load-images' => true,
54 | 'ssl-protocol' => 'any'
55 | ];
56 | $exporter->setCommandOptions($options);
57 | $expected = '--debug=false --ignore-ssl-errors=true --load-images=true --ssl-protocol=any';
58 | $this->assertEquals($expected, $exporter->mountCommandOptions());
59 | }
60 |
61 | public function testGenerateImage()
62 | {
63 | $exporter = new ImageExporter();
64 | $report = new Report(
65 | '',
66 | '',
67 | ''
68 | );
69 | $file = $exporter->generate($report);
70 | $this->assertFileExists($file);
71 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
72 | }
73 |
74 | /**
75 | * @expectedException \RuntimeException
76 | */
77 | public function testGenerateImageExpectedException()
78 | {
79 | $exporter = new ImageExporter();
80 | $report = new Report(
81 | '',
82 | '',
83 | ''
84 | );
85 | $exporter->setBinaryPath('invalid-path');
86 | $exporter->generate($report);
87 | }
88 |
89 |
90 | public function testGeneratePdfOnlyHeader()
91 | {
92 | $exporter = new ImageExporter();
93 | $report = new Report(
94 | '',
95 | ''
96 | );
97 | $file = $exporter->generate($report);
98 | $this->assertFileExists($file);
99 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
100 | }
101 |
102 | public function testGeneratePdfOnlyFooter()
103 | {
104 | $exporter = new ImageExporter();
105 | $report = new Report(
106 | '',
107 | '',
108 | ''
109 | );
110 | $file = $exporter->generate($report);
111 | $this->assertFileExists($file);
112 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
113 | }
114 |
115 | public function testCreateResponseInline()
116 | {
117 | $exporter = new ImageExporter(null, 'test-file-name-inline');
118 | $report = new Report('');
119 | $response = $exporter->setFormat('JPG')->response($report);
120 |
121 | $this->assertInstanceOf(Response::class, $response);
122 |
123 | $this->assertFalse(
124 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-inline.jpg"'),
125 | 'Could not find header to force download'
126 | );
127 | }
128 |
129 | public function testCreateResponseForceDownload()
130 | {
131 | $exporter = new ImageExporter(null, 'test-file-name-download');
132 | $report = new Report('');
133 | $response = $exporter->setFormat('JPG')->response($report, true);
134 |
135 | $this->assertInstanceOf(Response::class, $response);
136 |
137 | $this->assertTrue(
138 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-download.jpg"'),
139 | 'Could not find header to force download'
140 | );
141 | }
142 |
143 | public function testGetFooterHeight()
144 | {
145 | $exporter = new ImageExporter();
146 | $exporter->configure(['footer' => ['height' => '0px']]);
147 | $this->assertEquals('0px', $exporter->getFooterHeight());
148 |
149 | $exporter->configure(['footer' => ['height' => '100px']]);
150 | $this->assertEquals('100px', $exporter->getFooterHeight());
151 | }
152 |
153 | public function testGetHeaderHeight()
154 | {
155 | $exporter = new PdfExporter();
156 | $exporter->configure(['header' => ['height' => '0px']]);
157 | $this->assertEquals('0px', $exporter->getHeaderHeight());
158 |
159 | $exporter->configure(['header' => ['height' => '100px']]);
160 | $this->assertEquals('100px', $exporter->getHeaderHeight());
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/tests/Report/Exporters/PdfExporterTest.php:
--------------------------------------------------------------------------------
1 | exporter = new PdfExporter();
23 | $tmpConfig = $this->exporter->getDefaultConfiguration();
24 | $this->configDefault = $tmpConfig['pdf'];
25 | }
26 |
27 | public function testGetDefaultFormat()
28 | {
29 | $exporter = new PdfExporter();
30 | $this->assertEquals($this->configDefault['page']['format'], $exporter->getFormat());
31 | }
32 |
33 | public function testSetValidFormat()
34 | {
35 | $exporter = new PdfExporter();
36 | $exporter->setFormat('A3');
37 | $this->assertEquals('A3', $exporter->getFormat());
38 |
39 | }
40 |
41 | public function testSetInvalidFormat()
42 | {
43 | $exporter = new PdfExporter();
44 | $exporter->setFormat('invalid-format');
45 | $this->assertEquals($this->configDefault['page']['format'], $exporter->getFormat());
46 | }
47 |
48 |
49 |
50 | public function testMountCommandLine()
51 | {
52 | $exporter = new PdfExporter();
53 | $options = [
54 | 'debug' => false,
55 | 'ignore-ssl-errors' => true,
56 | 'load-images' => true,
57 | 'ssl-protocol' => 'any'
58 | ];
59 | $exporter->setCommandOptions($options);
60 | $expected = '--debug=false --ignore-ssl-errors=true --load-images=true --ssl-protocol=any';
61 | $this->assertEquals($expected, $exporter->mountCommandOptions());
62 | }
63 |
64 | public function testGeneratePdf()
65 | {
66 | $exporter = new PdfExporter();
67 | $report = new Report(
68 | '',
69 | '',
70 | ''
71 | );
72 | $file = $exporter->generate($report);
73 | $this->assertFileExists($file);
74 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
75 | }
76 |
77 | /**
78 | * @expectedException \RuntimeException
79 | */
80 | public function testGeneratePdfExpectedException()
81 | {
82 | $exporter = new PdfExporter();
83 | $report = new Report(
84 | '',
85 | '',
86 | ''
87 | );
88 | $exporter->setBinaryPath('invalid-path');
89 | $exporter->generate($report);
90 | }
91 |
92 |
93 | public function testGeneratePdfOnlyHeader()
94 | {
95 | $exporter = new PdfExporter();
96 | $report = new Report(
97 | '',
98 | ''
99 | );
100 | $file = $exporter->generate($report);
101 | $this->assertFileExists($file);
102 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
103 | }
104 |
105 | public function testGeneratePdfOnlyFooter()
106 | {
107 | $exporter = new PdfExporter();
108 | $report = new Report(
109 | '',
110 | '',
111 | ''
112 | );
113 | $file = $exporter->generate($report);
114 | $this->assertFileExists($file);
115 | $this->assertTrue( filesize($file) > 1000 , 'Generate file is empty');
116 | }
117 |
118 | public function testCreateResponseInline()
119 | {
120 | $exporter = new PdfExporter(null, 'test-file-name-inline');
121 | $report = new Report('');
122 | $response = $exporter->response($report);
123 |
124 | $this->assertInstanceOf(Response::class, $response);
125 |
126 | $this->assertFalse(
127 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-inline.pdf"'),
128 | 'Could not find header to force download'
129 | );
130 | }
131 |
132 | public function testCreateResponseForceDownload()
133 | {
134 | $exporter = new PdfExporter(null, 'test-file-name-download');
135 | $report = new Report('');
136 | $response = $exporter->response($report, true);
137 |
138 | $this->assertInstanceOf(Response::class, $response);
139 |
140 | $this->assertTrue(
141 | $response->headers->contains('content-disposition', 'attachment; filename="test-file-name-download.pdf"'),
142 | 'Could not find header to force download'
143 | );
144 | }
145 |
146 | public function testGetFooterHeight()
147 | {
148 | $exporter = new PdfExporter();
149 | $exporter->configure(['footer' => ['height' => '0px']]);
150 | $this->assertEquals('0px', $exporter->getFooterHeight());
151 |
152 | $exporter->configure(['footer' => ['height' => '100px']]);
153 | $this->assertEquals('100px', $exporter->getFooterHeight());
154 | }
155 |
156 | public function testGetHeaderHeight()
157 | {
158 | $exporter = new PdfExporter();
159 | $exporter->configure(['header' => ['height' => '0px']]);
160 | $this->assertEquals('0px', $exporter->getHeaderHeight());
161 |
162 | $exporter->configure(['header' => ['height' => '100px']]);
163 | $this->assertEquals('100px', $exporter->getHeaderHeight());
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/tests/Report/ReportTest.php:
--------------------------------------------------------------------------------
1 | 'values' ]);
9 | $this->assertEquals('content value', $report->getContent());
10 | $this->assertEquals('header value', $report->getHeader());
11 | $this->assertEquals('footer value', $report->getFooter());
12 | $this->assertEquals([ 'config' => 'values' ], $report->getConfig());
13 | }
14 |
15 | public function testReportContentInConstructor()
16 | {
17 | $report = new Report('string for test text values');
18 | $this->assertEquals('string for test text values', $report->getContent());
19 |
20 | $report = new Report('test for html values
');
21 | $this->assertEquals('test for html values
', $report->getContent());
22 |
23 | $report = new Report('');
24 | $this->assertEquals('', $report->getContent());
25 | }
26 |
27 | public function testReportContentInSet()
28 | {
29 | $report = (new Report(''))->setContent('string for test text values');
30 | $this->assertEquals('string for test text values', $report->getContent());
31 |
32 | $report->setContent('test for html values
');
33 | $this->assertEquals('test for html values
', $report->getContent());
34 |
35 | $report->setContent('');
36 | $this->assertEquals('', $report->getContent());
37 | }
38 |
39 | public function testReportHeaderInConstructor()
40 | {
41 | $report = new Report('', 'string for test text values');
42 | $this->assertEquals('string for test text values', $report->getHeader());
43 |
44 | $report = new Report('', 'test for html values
');
45 | $this->assertEquals('test for html values
', $report->getHeader());
46 |
47 | $report = new Report('', '');
48 | $this->assertEquals('', $report->getHeader());
49 | }
50 |
51 | public function testReportHeaderInSet()
52 | {
53 | $report = (new Report(''))->setHeader('string for test text values');
54 | $this->assertEquals('string for test text values', $report->getHeader());
55 |
56 | $report->setHeader('test for html values
');
57 | $this->assertEquals('test for html values
', $report->getHeader());
58 |
59 | $report->setHeader('');
60 | $this->assertEquals('', $report->getHeader());
61 | }
62 |
63 | public function testReportFooterInConstructor()
64 | {
65 | $report = new Report('', '', 'string for test text values');
66 | $this->assertEquals('string for test text values', $report->getFooter());
67 |
68 | $report = new Report('', '', 'test for html values
');
69 | $this->assertEquals('test for html values
', $report->getFooter());
70 |
71 | $report = new Report('', '', '');
72 | $this->assertEquals('', $report->getFooter());
73 | }
74 |
75 | public function testReportFooterInSet()
76 | {
77 | $report = (new Report(''))->setFooter('string for test text values');
78 | $this->assertEquals('string for test text values', $report->getFooter());
79 |
80 | $report->setFooter('test for html values
');
81 | $this->assertEquals('test for html values
', $report->getFooter());
82 |
83 | $report->setFooter('');
84 | $this->assertEquals('', $report->getFooter());
85 | }
86 |
87 | public function testReportAppendImagesToHeaderAndFooterInContent()
88 | {
89 | $report = new Report('test for html values
');
90 | $report->setHeader('');
91 |
92 | $expected = '
test for html values
';
93 | $this->assertEquals($expected, $report->getContent());
94 |
95 | $report = new Report('test for html values
');
96 | $report->setFooter('');
97 |
98 | $expected = '
test for html values
';
99 | $this->assertEquals($expected, $report->getContent());
100 | }
101 |
102 | public function testReportConfigInConstructor()
103 | {
104 | $report = new Report('', '', '', [ 'size' => 10 ]);
105 | $this->assertEquals([ 'size' => 10 ], $report->getConfig());
106 |
107 | $report = new Report('', '', '', []);
108 | $this->assertEquals([], $report->getConfig());
109 | }
110 |
111 | public function testReportConfigInSet()
112 | {
113 | $report = (new Report(''))->setConfig([ 'size' => 10 ]);
114 | $this->assertEquals([ 'size' => 10 ], $report->getConfig());
115 |
116 | $report->setConfig([]);
117 | $this->assertEquals([], $report->getConfig());
118 | }
119 | }
120 |
--------------------------------------------------------------------------------