No description
Find a file
2023-04-11 14:00:26 +02:00
bin Fix upgradedbto8.2 script for sqlite databases nearly 3 years later 2023-02-01 15:10:57 +01:00
config Add default back office url in configuration, add home page 2022-09-08 10:46:46 +02:00
res Update database creation scripts, move addperpetualcs to updatedbto8.2 to include archive sql queries. 2020-05-12 16:35:53 +02:00
src Force eager loading for snapshots, fix reading Resource content multiple times 2023-04-11 14:00:26 +02:00
tests Reject closed session without open date 2023-04-11 11:23:43 +02:00
.gitignore Add missing .htaccess in version control. 2017-10-02 15:39:57 +02:00
.htaccess-sample Put config in a single system-movable ini file 2017-05-25 11:13:50 +02:00
CHANGELOG.md Version 8.9, updated changelog 2022-09-15 11:32:54 +02:00
composer.json Fix some doctrine requirements 2021-11-23 16:15:59 +01:00
README.md Add AllowEncodedSlashes notice to configure Apache. 2020-07-08 18:48:24 +02:00

Pasteque Server

https://www.pasteque.org

Presentation

Pasteque API is a POS (point of sale) project under the [GNU General Public License v3][gnu]. It is made in [PHP] with [PDO], [MySQL] and [PostgreSQL]. It is the backbone of the Pasteque suite.

Installation

Prerequisites

Please install the following packages (for a Debian 10 based system)

PHP (at least 7.0): php php-cli php-gd php-intl php-xml php-mbstring php-zip php-gnupg

With Apache: apache2 libapache2-mod-php

With Postgresql (recommended): postgresql postgresql-client php-pgsql, you will require to set md5 authentication for pasteque users instead of peer

With MariaDB (MySQL, slower): mariadb-server-10.1 mariadb-client-10.1 php-mysql

From a release package

Download a release package from https://downloads.pasteque.org/api/ or any other reliable source. These packages has all static files already generated to ease the installation process a little.

Just uncompress the archive and go to Configuration below.

From source

Clone the repository to access to the source files. The repository doesn't embed generated files and requires more steps to intall a development instance.

First install dependencies with composer.

Install a database with Doctrine. Put the following file in the root directory and name it cli-config.php

<?php
namespace Pasteque\Server;
use \Pasteque\Server\System\DAO\DoctrineDAO;

$cfg = parse_ini_file(__DIR__ . '/config/test-config.ini');
$dbInfo = ['type' => $cfg['database/type'], 'host' => $cfg['database/host'],
    'port' => $cfg['database/port'], 'name' => $cfg['database/name'],
    'user' => $cfg['database/user'], 'password' => $cfg['database/password']];
$dao = new DoctrineDAO($dbInfo, ['debug' => false]);
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($dao->getEntityManager());

Then copy /config/test-config-sample.ini to /config/test-config.ini. Edit this file to point to the empty database to install.

Use php vendor/bin/doctrine orm:schema-tool:update --force to install the database structure. No data are provided yet.

Generate proxies with php vendor/bin/doctrine orm:generate-proxies then make the directory src/generated writeable by your web server user.

Configuration

Once all the files are installed, copy /config/config-sample.ini to config/config.ini and edit it to your liking.

For a single-user instance, you can edit all the ident/single/* and database/single/*entries to your liking.

For a shared instance, switch core_ident and core_database to inifile. The ini files shares the same structure as the previous entries, without the prefixes ident/single and database/single (i.e. only password= and type=, host= etc).

Also set jwt_secret to some random string.

Make sure the web server user can read the config file and the user ini files.

Database initialization

To initialize the database, use the sql scripts in res/database/<type>/schema.sql. The default data required for a running instance are not yet included, you can find a script at https://downloads.pasteque.org/api/scripts/

GPG initialization

GPG signing is required to conform to the LF2016. It enables signing archives to make sure they cannot be modified when stored outside Pasteque.

To disable GPG, set gpg/enabled to false (for testing purposes or when conformity is not required) in your configuration file. When disabled, archive generation is not available.

GPG must be installed. Check GnuPG website if it is not already installed.

Then you should create a dedicated key for signing archives. PHP requires the key to have no passphrase to be able to generate archives automatically. Check guides on GnuPG's website again to create or import one.

For example to create a key in a dedicated keyring:

gpg --homedir <pasteque>/config/gpg --full-generate-key

or to import them

gpg --homedir <pasteque>/config/gpg --import <public key file>
gpg --homedir <pasteque>/config/gpg --import <secret key file>

If everything went well, you should see your key and it's fingerprint with

gpg --homedir <pasteque>/config/gpg --list-keys

In your configuration file put the fingerprint of your key in gpg/fingerprint. If you used an other homedir, you must also change gpg/path.

Archives are not generated from http requests as they would probably not fit in the limit of the web server. Set a cron task to run php bin/createarchive.php <user id> to generate archives outside the web server or run the script manually.

Web server configuration

Apache

Make your web server point to /src/http/public. Make sure AllowOverride All is set for this directory for the .htaccess in there to work. To be able to accept references with / inside them, allow encoded urls. In your site-enabled config file under VirtualHost put:

<Directory /path/to/pasteque/src/http/public>
	AllowOverride All
</Directory>
AllowEncodedSlashes NoDecode

Also check that the rewrite mod is enabled, it should be listed in the mods-enabled directory of your Apache server.

You should now call an API: http(s)://<url_to_pasteque>/api/<route>

Check your installation by requesting http(s)://<url_to_pasteque>/fiscal/ you should be prompted to login, and you should be able to log if the user and database are correctly set.

PHP standalone server

This method is not recommended but could help in certain cases, mostly for developpement and debugging. Or when no server at all could be installed.

Start the PHP standalone server running src/http/public/index.php with the command php -S <host>:<port> src/http/public/index.php. Like php -S localhost:8080 src/http/public/index.php or php -S 192.168.1.0:8080 src/http/public/index.php.

Install clients

Once the API is up and running, all is required now is some clients to connect to it. Pick a cash register client (Desktop or Android) and a backoffice client (admin or jsadmin) and you are ready to go.

Contributing

Software architecture

/bin         Some php cli scripts to manage your instance.
/config      All the ini files, copy and edit the samples to configure your server.
/res         Business data, like default data and database schemes.
/src         The code of Pasteque server.
/src/lib     Internal code of Pasteque
/src/http    External access (HTTP).
/src/http/public This is the directory your web server must point to.
/tests       The tests of Pasteque server, see tests/README to run the tests
/vendor      Third party libraries. Use composer to install them.

Internal code

Relative to /src/lib

/API                The API classes and methods. This is what can be called from outside.
/Model              The model declarations with annotations.
/System             The non-business underlying code to run the API.
/System/API         The magic under API calls lays here.
/System/SysModules  How to read user login and database credentials.
/System/DAO         The code relative to DAO (the Doctrine layer)
AppContext          Read from the config file to run the server from external code.

External code

Relative to /src/http.

/middlewares   Slim middlewares, including token management.
/public        The files opened to public access. Contains index.php and .htaccess.
/routes        Slim routes, one file per api

All routes are documented with Swagger. They are called through a given URL which contains the parameters.

Routes then make a internal call and transform the response back to HTTP. The routes must be all defined explicitely and annotated for Swagger to be able to generate the documentation.

How do I

Call an API from the external layer

An API call is made from \Pasteque\Server\System\API\APICaller::run. It takes the application context, the class name, the method name and arguments as parameters.

All the public methods from all classes from \Pasteque\Server\API namespace can be requested. Parameters can either be a flat array like a regular method call, or a named parameter call with an associative array.

You can call getToken($user, $password) from LoginAPI either with APICaller::run($app, 'login', 'getToken', ['myLogin', 'MyPassword']) or APICaller::run($app, 'login', 'getToken', ['password' => 'myPassword', 'user' => 'myLogin']).

The API name is case insensitive and the suffix "API" from the class name can be ommited. $app is the AppContext initialized in the external layer and shared across the layer.

It will return a \Pasteque\Server\System\API\APIResult with it's status and object content. To pass the content to the outside, use $response->getStructContent() or $response->toJson() to obtain raw data and not DAO-proxied objects.

Call an API from outside

Look at the documentation for the URL to provide to the server. Authenticate with the login api and pass the fetched token for further calls. The HTTP layer put the token in a cookie to ease access. You can also use GET, POST or HTTP header to pass it.

Create an API

Add a new class which name ends by "API" and must have only the first letter capitalized into /src/lib/API, set the desired methods public and that's it. The API layer will magically map your code, do the parameters binding and format the response from and for the external layer.

The API classes takes a DAO object from constructor (see /src/lib/System/DAO/DAO.php) to access to the database. It is also provided by the API layer.

The method opened to the outside must then be mapped by a route un Slim.

Edit a model

The models inside /src/lib/Model has annotations for Swagger and Doctrine. When editing a model, the fields will be automatically mapped by the DAO. Doctrine requires to declare attributes protected and add a getter and a setter. You will also have to list the primitive-typed fields and reference fields from both static methods getDirectFieldNames and getAssociationFieldNames. This is required to generate raw data output for the external layer because Doctrine uses proxies for each model attribute.

If the editions have an impact on the behaviour of the API, you will require to edit the corresponding API in /src/lib/API. Otherwise it will be automatically passed to the output and can be searchable without any further edit.

Add internal features

For all the things relative to the database, see /src/lib/System/DAO: DAO.php for the general interface and DoctrineDAO.php for the implementation. The actual DAO instance is provided by DAOFactory to the API layer.

The database access is provided by a system module. See /src/lib/System/SysModules/Database/DBModule.php for the general interface. The implementations are provided by SystModuleFactory. This is the same scheme for account data with IdentModule.

The AppContext will glue all these tools to pass them afterward to the API. Given an ini configuration file, it will fetch the corresponding system modules and DAO.

Swagger and OAS

We use Open API Specification (OAS, see https://www.openapis.org/) and http://swagger.io tools to generate the API documentation.

The JSON file is located in /bin/swagg.json

You can generate it with the script generate_swagger_file.php. The JSON /bin/swagg.json will get updated

$ php generate_swagger_file.php

You can use http://petstore.swagger.io and submit your own swagg.json file or you can either install swagger-UI, read the docs at https://swagger.io/docs/swagger-tools/#swagger-ui-documentation-29