PHPackages                             ftrotter/zzermelo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. ftrotter/zzermelo

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

ftrotter/zzermelo
=================

ZZermelo, a PHP reporting engine for Laravel

v2.0.3(4y ago)010Apache-2.0JavaScriptPHP &gt;=7.2.0

Since Jul 27Pushed 4mo agoCompare

[ Source](https://github.com/ftrotter/ZZermelo)[ Packagist](https://packagist.org/packages/ftrotter/zzermelo)[ RSS](/packages/ftrotter-zzermelo/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (7)Versions (30)Used By (0)

ZZermelo Reporting Engine
=========================

[](#zzermelo-reporting-engine)

A PHP reporting engine that works especially well with Laravel, built with love at [Care Set Systems](http://careset.com)

Reporting Approach
------------------

[](#reporting-approach)

The basic idea in ZZermelo is to let report authors think exclusively in SQL SELECT statements, and to allow ZZermelo to handle the translation of the data that results from queries into complex and rich web interfaces. There are plenty of good tools available to help build SELECT statements, and there are thousands of excellent resources available to learn how to use the SELECT query functions in SQL. And if you know how to use SQL SELECT statements, then with ZZermelo, you can automatically create complex and interactive web-based reports.

Generally, this happens using the ability of SQL to have aliases for the output of specific variables. For most of the reporting engines, you can have one or many SQL queries that output into specific aliased columns that ZZermelo understands. And then the reporting engine will automatically populate a web-based data view with the data output. For instance, the card-based layout engine allows you to populate rows of data into BootStrap Cards. Almost every portion of the Bootstrap Card can be populated by using column names that correspond to the css classes supported inside the [bootstrap card component](https://getbootstrap.com/docs/4.0/components/card/#kitchen-sink).

The exception to this approach is the tabular data viewer. Here, you can output anything you want from your SELECT statement and ZZermelo will do its best to create a online auto-paging tabular view of your data using the [DataTables](https://datatables.net/) javascript project.

Core Reporting features
-----------------------

[](#core-reporting-features)

- Write SQL, automatically get a web-based report
- Decorate each row in the report with links, buttons, JS and other bootstrap-based HTML goodness.
- Control the entire web report using a single PHP file, which contains SQL and web interface decorations.
- GET/POST/JSON/URL parameters are all available as local functions/variables in the single file. This allows the SQL to be heavily modified based on the paramaters passed in to the specific report url.
- Automatically support server side data paging, allows engine to report against very large databases
- Any report data can be downloaded in CSV file(s)
- Report automatically generates JSON data source that can be used as an API
- Supports Laravel's Blade templating engine out of the box (with more effort supports any front end templating engine).

We have a [feature roadmap](FullFeature.md) if you want to see where we are going and an extended list of Zermello Reporting features.

ScreenShot that explains everything
-----------------------------------

[](#screenshot-that-explains-everything)

!\[ZZermelo Data Flow Diagram\]( Set/ZZermelo/master/documentation/ZZermeloScreenShot.png)

Architecture
------------

[](#architecture)

Read the [Architecture diagram](documentation/Architecture.md)ZZermelo is doing the hard work of translating "mere SQL" into something that can consistently and with minimal impact on performance be loaded into a single browser session. ZZermelo understands how to push the hard work to the MariaDB/MySQL server, ensuring that the browser gets its data in dribbles. The backend is having to do a huge amount of work in order make that happen.

Some queries will legitimately take hours for the backend to run, even when the resulting data is only a few hundred rows of results. In order to support these heavy loads, ZZermelo understands how to cache results. It always caches the results, but for most queries, it always refreshes the cache on every browser call.

You, the user, get to control how this works. Look at the [Controlling the Cache](documentation/ControlCaching.md) documentation to see how.

How to get started using it
---------------------------

[](#how-to-get-started-using-it)

### Prerequisites

[](#prerequisites)

You will need a modern LAMP server with at least php 7.2 and at least Laravel 5.5 [Complete Prerequisites](documentation/Prerequisites.md)Once the prerequisites are completed you should be able to check URLs on host system's browser at URL: homestead.test

### Installation

[](#installation)

Look in [Basic Installation](documentation/BasicInstall.md) for complete installation instructions and database setup.

For a quick start, assuming your Laravel instance already has access to the DB that it needs

```
    composer require careset/zzermelo
    php artisan zzermelo:install
```

This will install and configure zzermelo, and create an app/Reports for you to add reports too.

Next, you should test your routes...

```
    $ php artisan route:list | grep ZZermelo
|        | GET|HEAD | ZZermelo/{report_key}                                 |
|        | GET|HEAD | ZZermeloCard/{report_key}                             |
|        | GET|HEAD | ZZermeloGraph/{report_key}                            |
|        | GET|HEAD | api/ZZermelo/{report_key}/Download/{parameters?}      |
|        | GET|HEAD | api/ZZermelo/{report_key}/Summary/{parameters?}       |
|        | GET|HEAD | api/ZZermelo/{report_key}/{parameters?}               |
|        | GET|HEAD | api/ZZermeloGraph/{report_key}/Download/{parameters?} |
|        | GET|HEAD | api/ZZermeloGraph/{report_key}/{parameters?}          |
```

### Running Example

[](#running-example)

We provide example reports, and the schema and data needed to run those reports. This is a good place to start if you are just exploring the system. Read, [Running the Examples](documentation/RunExample.md)

### Configuration Notes

[](#configuration-notes)

1. Edit the file `config/zzermelo.php` to change core zzermelo setting these values are explained there and in [Configuration Documentation](documentation/ConfigFile.md)s
2. Edit the file `config/zzermelobladetabular.php` to change settings specific to zzermelo blade tabular view package.
3. Earlier in the Basic Installation you've already created an app/Reports directory. If desired, you can create a differently named report directory, but you must also change the namespace. Change the REPORT\_NAMESPACE setting in config/zzermelo.php to something else...

```
/**
 * Namespace of the report where it will attempt to load from
 */
'REPORT_NAMESPACE' =>env("REPORT_NAMESPACE","app\Reports"),
```

... like "ZZermelo" and then create a ~/code/zzermelo-demo/app/ZZermelo directory to place your example report in. Note: you will also need to change the namespace of Northwind\*Reports.php files to "namespace app\\ZZermelo;" if you change the REPORT\_NAMESPACE. 4. To configure middleware, you may add, or edit the MIDDLEWARE config setting in your config/zzermelo.php file. This will run the configured middleware on each API request. For example, if you have enabled [Laravel's Authentication](https://laravel.com/docs/5.6/authentication#protecting-routes)and wish to protect the ZZermelo routes using the auth middleware, you may add the string "auth" to the MIDDLEWARE array in order to exeute the auth middleware on each API request to the ZZermelo API. Similarly, for the front-end view packages like zzermelobladetabular, you may add the "auth" string to the TABULAR\_MIDDLEWARE array in zzermelobladetabular.php to enable authentication on that route.

### Update to New Version of zzermelo

[](#update-to-new-version-of-zzermelo)

In project home dir:

composer update careset/zzermelo php artisan zzermelo:install

When you install the zzermelobladetabular package, Just Say No to 'replace' all those files EXCEPT: 'The \[zzermelo/tabular.blade.php\] view already exists' Y (replace it!) 'The \[zzermelo/layouts/tabular.blade.php\] view already exists.' Y (replace it!)

### Uninstall ZZermelo

[](#uninstall-zzermelo)

You can uninstall the composer packages by running 'composer remove' to remove the requirements in composer.json, and to remove the packages from the vendor directory. In project home dir:

```
    composer remove careset/zzermelo
    composer clear-cache
```

Make your first Report
----------------------

[](#make-your-first-report)

1. In order to get your first report, you need to create a report file. The easiest way to create an new report file is to run:

`php artisan zzermelo:make_tabular [YourNewReportName]`

To understand what this does, take a look at the example report model below.

2. Edit the new file `/app/ZZermelo/[YourNewReportName]` (or, with the defaults mentioned in the instructions, `/app/Reports/[YourNewReportName]`) You must fill in a reasonable GetSQL() function that returns either a single SQL text string, or an array of SQL text strings.
3. Point your browser to
4. Enjoy seeing your data in an automatically pagable [Datatables](https://datatables.net/) display!!
5. Various functions and constants in the report file can dramatically change how the report is displayed on the front end. Use them to change the reports (a good first hack is to use the MapRow function to link one report to another report)

Features / Function Reference
-----------------------------

[](#features--function-reference)

#### Basics

[](#basics)

**GetSQL()**This is the core of the report. Implement this function in your report child class, adding your SQL query to populate the report. The column names in your SELECT statement become the headers of your report by default.

**GetReportName()**Implement this function to return the title of the report.

**GetReportDescription()**Implement this function, and the returned string will be printed in the description block below title of the report. The string is not escaped, and is passed raw to the report, so it is possible to print HTML (form elements, for example)

**GetReportFooter()**Implement this function to return a string that will be displayed within the footer tag at the bottom of the report layout. The string is not escaped, and is passed raw to the report, so it is possible to print HTML (form elements, for example)

**GetReportFooterClass()**Implement this class to add specific class to your footer. Add "fixed" to make your footer fixed to the bottom, and add "centered" to center your footer content. For example, implement this function to return "fixed centered" for your footer to be fixed, and it's content centered.

#### Row and Header Manipulation

[](#row-and-header-manipulation)

**MapRow(array $row, int $row\_number)**Implement this method to modify tabular cell content. When displaying to the tabular view, your report child class can chose to modify the content of each row cell.

**OverrideHeader(array &amp;$format, array &amp;$tags)**Implement this method to verride a default column format or add additional column tag to be sent back to the front end

#### Cache Configuration

[](#cache-configuration)

**isCacheEnabled()**Turn caching on and off. Default is to return *false* which means cache is off. If you set this function to return *true*, this will enable the caching. **Creating** the cache table always happens, but when the cache is enabled, the cache is used to answer subsequent queries rather than re-running the original query. This can cause confusing results (i.e. changing the underlying data does not change the content of the report when the cache is used) and as a result, it is off by default. But for many large and slow queries, caching is nessecary.

**howLongToCacheInSeconds()**If cache is enabled, we use this setting to configure how long we wish to retain the cached report, before re-running the original query.

**getCacheDatabaseSource()**Specify a location where we want our report to point to, overriding the automatically-generated cache table name. With this property, the report developer can specify the source for the cache database. You may want to use this if you're data is ending up in a specific, known location, and you want to point your report at it. You can either implement this function in your report, or set the property $CACHE\_DATABASE\_SOURCE using this structure:

```
    protected $CACHE_DATABASE_SOURCE = [
        'database' => '_zzermelo_cache_overload',
        'table' => 'northwind_cust_overload'
    ];
```

#### Add custom Javascript

[](#add-custom-javascript)

**GetReportJS()**Implement this function to return a string that will be placed in a script tag before the closing body tag of the report. Do not include script tags. This function should return JS code only. The string is not escaped, and is passed raw to the report.

#### Turn on the SQL Print view

[](#turn-on-the-sql-print-view)

**isSQLPrintEnabled()**Will turn on the ability to visit the report using the /ZZermeloSQL/ url and instead of running the report, a helpful debugging screen will be presented, showing what SQL would have been returned by GetSQL() in a pretty-printed manner. This is very helpful for debugging inputs. It does require that SQL view be enabled in the /config/zzermelo.php file to work, however.

### API functions available in GetSQL()

[](#api-functions-available-in-getsql)

**getInput($key = null)**Use this function to get the value of of a GET parameter passed to the report. You can use this in your GetSQL() function to affect your query based on additional parameters passed in the request query string.

**setInput($key, $new\_value)**A useful but dangerous function that allows for specific reports to override the input that comes from a user before it is used. Use this carefuly, since this will make changing the setting in the user interface not function properly. TODO (have the UX note that a setting is frozen)

**setDefaultInput($key, $new\_value)**This will set a input variable to starting value.. until the value is reset in the UX. (unlike setInput it will not override user values)

**setDefaultSortOrder($sort\_array)**This is a helper function for setInput() that allows to set a default order in the UI on tabular (and tabular derived) views. The sort\_array argument takes the form: $sort\_order = \[ \['order\_count' =&gt; 'desc'\], \['name' =&gt; 'asc'\] \];

This would result in listing the rows with the most orders at the top and when several rows had the same number of orders would be listed alphabetically

**pushViewVariable($key, $value)**Use this function to pass a variable to the view without going through request/response cycle. The key parameter is a string, and will be available on the view template as a php variable. For example, if you have the following in your GetSQL() function:

`$this->pushViewVariable('extra_var',true)`

then your variable will be available in the view as $extra\_var with a value of 'true'.

```
@if ($extra_var === true)
ExtraVar Is True!
@endif
```

### Example Report Model

[](#example-report-model)

To see full list of functions and variables, please see the ZZermeloReport model - &lt; Set/ZZermelo/blob/master/src/Care Set/ZZermelo/Models/ZZermeloReport.php&gt;

```
