mirror of
https://github.com/envoyr/nginx-configurator.git
synced 2026-04-28 04:06:18 +00:00
Initial commit
This commit is contained in:
4
.coveralls.yml
Normal file
4
.coveralls.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# for php-coveralls
|
||||||
|
src_dir: src
|
||||||
|
coverage_clover: tests/coverage/clover.xml
|
||||||
|
json_path: tests/coverage/coveralls-upload.json
|
||||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/app/config/parameters.yml
|
||||||
|
/build/
|
||||||
|
/var/*
|
||||||
|
!/var/.gitkeep
|
||||||
|
/vendor/
|
||||||
|
/web/bundles/
|
||||||
|
/.sonar/
|
||||||
|
/.idea/
|
||||||
|
/bin/*
|
||||||
|
!/bin/console
|
||||||
|
!/bin/symfony_requirements
|
||||||
|
/tests/coverage/*
|
||||||
|
!tests/coverage/.gitkeep
|
||||||
|
/tests/pdepend/*
|
||||||
|
!tests/pdepend/.gitkeep
|
||||||
|
/docker/rebuild/build/*
|
||||||
|
!/docker/rebuild/build/.gitkeep
|
||||||
|
/docker/rebuild/partials/*
|
||||||
|
!/docker/rebuild/partials/.gitkeep
|
||||||
|
/docker/rebuild/resources/*
|
||||||
|
!/docker/rebuild/resources/.gitkeep
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Madkom S.A.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
233
README.md
Normal file
233
README.md
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
NGINX Configurator
|
||||||
|
==================
|
||||||
|
|
||||||
|
PHP Library for NGINX configuration parser/generator
|
||||||
|
|
||||||
|

|
||||||
|
[](https://travis-ci.org/madkom/nginx-configurator)
|
||||||
|
[](https://packagist.org/packages/madkom/nginx-configurator)
|
||||||
|
[](https://packagist.org/packages/madkom/nginx-configurator)
|
||||||
|
[](https://packagist.org/packages/madkom/nginx-configurator)
|
||||||
|
[](https://coveralls.io/github/madkom/nginx-configurator?branch=master)
|
||||||
|
[](https://codeclimate.com/github/madkom/nginx-configurator)
|
||||||
|
[](https://codeclimate.com/github/madkom/nginx-configurator)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
This library can parse and generate NGINX configuration files.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install with Composer
|
||||||
|
|
||||||
|
```
|
||||||
|
composer require madkom/nginx-configurator
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
This library requires *PHP* in `~7` version.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Parsing configuration string:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Builder;
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Parser;
|
||||||
|
|
||||||
|
require 'vendor/autoload.php';
|
||||||
|
|
||||||
|
$config = <<<CONFIG
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
root /data/www/web;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/www;
|
||||||
|
}
|
||||||
|
|
||||||
|
# pass the PHP scripts to FastCGI server listening on the php-fpm socket
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CONFIG;
|
||||||
|
|
||||||
|
$parser = new Parser();
|
||||||
|
$defaultConfig = $parser->parse($config);
|
||||||
|
/** @var Server $defaultServers[] */
|
||||||
|
$defaultServers = $defaultConfig->search(function (Node $node) {
|
||||||
|
return $node instanceof Server;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$builder = new Builder();
|
||||||
|
if (count($defaultServers) > 0) {
|
||||||
|
/** @var Server $defaultServer */
|
||||||
|
foreach ($defaultServers as $defaultServer) {
|
||||||
|
$builder->appendServerNode($defaultServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Generating configuration string:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Builder;
|
||||||
|
use Madkom\NginxConfigurator\Config\Location;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Literal;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$builder = new Builder();
|
||||||
|
|
||||||
|
$server = $builder->addServerNode(80);
|
||||||
|
$server->append(new Directive('error_log', [new Param('/var/log/nginx/error.log'), new Param('debug')]));
|
||||||
|
$server->append(new Location(new Param('/test'), null, [
|
||||||
|
new Directive('error_page', [new Param('401'), new Param('@unauthorized')]),
|
||||||
|
new Directive('set', [new Param('$auth_user'), new Literal('none')]),
|
||||||
|
new Directive('auth_request', [new Param('/auth')]),
|
||||||
|
new Directive('proxy_pass', [new Param('http://test-service')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('/auth'), null, [
|
||||||
|
new Directive('proxy_pass', [new Param('http://auth-service:9999')]),
|
||||||
|
new Directive('proxy_bind', [new Param('$server_addr')]),
|
||||||
|
new Directive('proxy_redirect', [new Param('http://$host'), new Param('https://$host')]),
|
||||||
|
new Directive('proxy_set_header', [new Param('Content-Length'), new Literal("")]),
|
||||||
|
new Directive('proxy_pass_request_body', [new Param('off')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('@unauthorized'), null, [
|
||||||
|
new Directive('return', [new Param('302'), new Param('/login?backurl=$request_uri')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('/login'), null, [
|
||||||
|
new Directive('expires', [new Param('-1')]),
|
||||||
|
new Directive('proxy_pass', [new Param('http://identity-provider-service')]),
|
||||||
|
new Directive('proxy_bind', [new Param('$server_addr')]),
|
||||||
|
new Directive('proxy_redirect', [new Param('http://$host'), new Param('https://$host')]),
|
||||||
|
new Directive('proxy_set_header', [new Param('Content-Length'), new Literal("")]),
|
||||||
|
new Directive('proxy_pass_request_body', [new Param('off')]),
|
||||||
|
]));
|
||||||
|
|
||||||
|
print($builder->dump());
|
||||||
|
```
|
||||||
|
|
||||||
|
Generated configuration output:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80 default ipv6only=on;
|
||||||
|
error_log /var/log/nginx/error.log debug;
|
||||||
|
location /test {
|
||||||
|
error_page 401 @unauthorized;
|
||||||
|
set $auth_user "none";
|
||||||
|
auth_request /auth;
|
||||||
|
proxy_pass http://test-service;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /auth {
|
||||||
|
proxy_pass http://auth-service:9999;
|
||||||
|
proxy_bind $server_addr;
|
||||||
|
proxy_redirect http://$host https://$host;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @unauthorized {
|
||||||
|
return 302 /login?backurl=$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /login {
|
||||||
|
expires -1;
|
||||||
|
proxy_pass http://identity-provider-service;
|
||||||
|
proxy_bind $server_addr;
|
||||||
|
proxy_redirect http://$host https://$host;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
There are also methods to read and dump file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Builder;
|
||||||
|
use Madkom\NginxConfigurator\Config\Location;
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Literal;
|
||||||
|
use Madkom\NginxConfigurator\Parser;
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$parser = new Parser();
|
||||||
|
$builder = new Builder();
|
||||||
|
|
||||||
|
$configuration = $parser->parseFile('default.conf');
|
||||||
|
|
||||||
|
/** @var Server $servers[] */
|
||||||
|
$servers = $configuration->search(function (Node $node) {
|
||||||
|
return $node instanceof Server;
|
||||||
|
});
|
||||||
|
if (count($servers) > 0) {
|
||||||
|
/** @var Server $server */
|
||||||
|
foreach ($servers as $server) {
|
||||||
|
$builder->appendServerNode($server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->dumpFile('generated.conf');
|
||||||
|
```
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
* [ ] Implement comments parsing
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Madkom S.A.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
35
composer.json
Normal file
35
composer.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "madkom/nginx-configurator",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "http://madkom.pl/",
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"require": {
|
||||||
|
"madkom/collection": "^1.0",
|
||||||
|
"ferno/loco": "@dev",
|
||||||
|
"madkom/uri": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpspec/phpspec": "^2.5",
|
||||||
|
"phpunit/phpunit": "~4"
|
||||||
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "git@github.com:madkom/loco.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Madkom\\NginxConfigurator\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michał Brzuchalski",
|
||||||
|
"email": "m.brzuchalski@madkom.pl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"bin-dir": "bin/"
|
||||||
|
}
|
||||||
|
}
|
||||||
40
examples/build.php
Normal file
40
examples/build.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Builder;
|
||||||
|
use Madkom\NginxConfigurator\Config\Location;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Literal;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$builder = new Builder();
|
||||||
|
|
||||||
|
$server = $builder->addServerNode(80);
|
||||||
|
$server->append(new Directive('error_log', [new Param('/var/log/nginx/error.log'), new Param('debug')]));
|
||||||
|
$server->append(new Location(new Param('/test'), null, [
|
||||||
|
new Directive('error_page', [new Param('401'), new Param('@unauthorized')]),
|
||||||
|
new Directive('set', [new Param('$auth_user'), new Literal('none')]),
|
||||||
|
new Directive('auth_request', [new Param('/auth')]),
|
||||||
|
new Directive('proxy_pass', [new Param('http://test-service')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('/auth'), null, [
|
||||||
|
new Directive('proxy_pass', [new Param('http://auth-service:9999')]),
|
||||||
|
new Directive('proxy_bind', [new Param('$server_addr')]),
|
||||||
|
new Directive('proxy_redirect', [new Param('http://$host'), new Param('https://$host')]),
|
||||||
|
new Directive('proxy_set_header', [new Param('Content-Length'), new Literal("")]),
|
||||||
|
new Directive('proxy_pass_request_body', [new Param('off')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('@unauthorized'), null, [
|
||||||
|
new Directive('return', [new Param('302'), new Param('/login?backurl=$request_uri')]),
|
||||||
|
]));
|
||||||
|
$server->append(new Location(new Param('/login'), null, [
|
||||||
|
new Directive('expires', [new Param('-1')]),
|
||||||
|
new Directive('proxy_pass', [new Param('http://identity-provider-service')]),
|
||||||
|
new Directive('proxy_bind', [new Param('$server_addr')]),
|
||||||
|
new Directive('proxy_redirect', [new Param('http://$host'), new Param('https://$host')]),
|
||||||
|
new Directive('proxy_set_header', [new Param('Content-Length'), new Literal("")]),
|
||||||
|
new Directive('proxy_pass_request_body', [new Param('off')]),
|
||||||
|
]));
|
||||||
|
|
||||||
|
print($builder->dump());
|
||||||
25
examples/default.conf
Normal file
25
examples/default.conf
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
root /data/www/web;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/www;
|
||||||
|
}
|
||||||
|
|
||||||
|
# pass the PHP scripts to FastCGI server listening on the php-fpm socket
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
examples/parse.php
Normal file
54
examples/parse.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Builder;
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Node\Node;
|
||||||
|
use Madkom\NginxConfigurator\Parser;
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$config = <<<CONFIG
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
root /data/www/web;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/www;
|
||||||
|
}
|
||||||
|
|
||||||
|
# pass the PHP scripts to FastCGI server listening on the php-fpm socket
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files \$uri =404;
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CONFIG;
|
||||||
|
|
||||||
|
$parser = new Parser();
|
||||||
|
$defaultConfig = $parser->parse($config);
|
||||||
|
|
||||||
|
/** @var Server $defaultServers[] */
|
||||||
|
$defaultServers = $defaultConfig->search(function (Node $node) {
|
||||||
|
return $node instanceof Server;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$builder = new Builder();
|
||||||
|
if (count($defaultServers) > 0) {
|
||||||
|
/** @var Server $defaultServer */
|
||||||
|
foreach ($defaultServers as $defaultServer) {
|
||||||
|
$builder->appendServerNode($defaultServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
phpcs.xml
Normal file
11
phpcs.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ruleset name="Selective Standard">
|
||||||
|
<description>Project Coding Standard</description>
|
||||||
|
<file>./src</file>
|
||||||
|
<rule ref="Generic.Files.LineLength">
|
||||||
|
<properties>
|
||||||
|
<property phpcs-only="true" name="lineLimit" value="130"/>
|
||||||
|
<property phpcbf-only="true" name="lineLimit" value="150"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
||||||
5
phpspec.yml
Normal file
5
phpspec.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
suites:
|
||||||
|
types:
|
||||||
|
namespace: Madkom\NginxConfigurator
|
||||||
|
psr4_prefix: Madkom\NginxConfigurator
|
||||||
|
spec_path: tests
|
||||||
27
phpunit.xml
Normal file
27
phpunit.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
|
||||||
|
backupGlobals="false"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Application Test Suite">
|
||||||
|
<directory suffix="Test.php">./tests/phpunit/</directory>
|
||||||
|
<exclude>./vendor</exclude>
|
||||||
|
<exclude>./app</exclude>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<filter>
|
||||||
|
<blacklist>
|
||||||
|
<directory suffix=".php">./vendor</directory>
|
||||||
|
<directory suffix=".php">./app</directory>
|
||||||
|
<directory suffix=".php">./bin</directory>
|
||||||
|
<directory suffix=".php">./tests</directory>
|
||||||
|
<file>./var/bootstrap.php.cache</file>
|
||||||
|
</blacklist>
|
||||||
|
</filter>
|
||||||
|
<php>
|
||||||
|
<server name="KERNEL_DIR" value="./app/" />
|
||||||
|
</php>
|
||||||
|
|
||||||
|
</phpunit>
|
||||||
93
src/Builder.php
Normal file
93
src/Builder.php
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 18.04.16
|
||||||
|
* Time: 11:06
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Config\Upstream;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
use Madkom\NginxConfigurator\Node\RootNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Builder
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Builder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RootNode Holds configuration root node
|
||||||
|
*/
|
||||||
|
protected $rootNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
$this->rootNode = new RootNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $port
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function addServerNode(int $port) : Server
|
||||||
|
{
|
||||||
|
$listenIPv4 = new Directive('listen', [new Param($port)]);
|
||||||
|
$listenIPv6 = new Directive('listen', [new Param("[::]:{$port}"), new Param('default'), new Param('ipv6only=on')]);
|
||||||
|
$httpNode = new Server([$listenIPv4, $listenIPv6]);
|
||||||
|
$this->rootNode->append($httpNode);
|
||||||
|
|
||||||
|
return $httpNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Server $server
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function appendServerNode(Server $server) : Server
|
||||||
|
{
|
||||||
|
$this->rootNode->append($server);
|
||||||
|
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Upstream $upstream
|
||||||
|
* @return Upstream
|
||||||
|
*/
|
||||||
|
public function appendUpstreamNode(Upstream $upstream) : Upstream
|
||||||
|
{
|
||||||
|
$this->rootNode->append($upstream);
|
||||||
|
|
||||||
|
return $upstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function dump() : string
|
||||||
|
{
|
||||||
|
return (string)$this->rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function dumpFile(string $filename) : bool
|
||||||
|
{
|
||||||
|
return file_put_contents($filename, $this->dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Config/Events.php
Normal file
28
src/Config/Events.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 20:55
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Config;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Events
|
||||||
|
* @package Madkom\NginxConfigurator\Config
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Events extends Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Events constructor.
|
||||||
|
* @param Directive[] $directives
|
||||||
|
*/
|
||||||
|
public function __construct(array $directives = [])
|
||||||
|
{
|
||||||
|
parent::__construct('events', $directives);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Config/Http.php
Normal file
28
src/Config/Http.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 20:57
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Config;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Http
|
||||||
|
* @package Madkom\NginxConfigurator\Config
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Http extends Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Http constructor.
|
||||||
|
* @param Directive[] $directives
|
||||||
|
*/
|
||||||
|
public function __construct(array $directives = [])
|
||||||
|
{
|
||||||
|
parent::__construct('http', $directives);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/Config/Location.php
Normal file
71
src/Config/Location.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 21:01
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Config;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Literal;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Location
|
||||||
|
* @package Madkom\NginxConfigurator\Config
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Location extends Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds location match
|
||||||
|
* @var Param
|
||||||
|
*/
|
||||||
|
private $location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds location match modifier
|
||||||
|
* @var Param
|
||||||
|
*/
|
||||||
|
private $match;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location constructor.
|
||||||
|
* @param Param $location
|
||||||
|
* @param Param $match
|
||||||
|
* @param array $directives
|
||||||
|
*/
|
||||||
|
public function __construct(Param $location, Param $match = null, array $directives = [])
|
||||||
|
{
|
||||||
|
$this->location = $location;
|
||||||
|
$this->match = $match;
|
||||||
|
parent::__construct('location', $directives);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
"{$this->name} %s %s {\n\t%s\n}\n",
|
||||||
|
$this->match,
|
||||||
|
$this->location,
|
||||||
|
implode("\n\t", (array)$this->childNodes->getIterator())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Param
|
||||||
|
*/
|
||||||
|
public function getLocation() : string
|
||||||
|
{
|
||||||
|
return (string)$this->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Param
|
||||||
|
*/
|
||||||
|
public function getMatch() : string
|
||||||
|
{
|
||||||
|
return (string)$this->match;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/Config/Server.php
Normal file
27
src/Config/Server.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 21:00
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Config;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Server
|
||||||
|
* @package Madkom\NginxConfigurator\Config
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Server extends Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Server constructor.
|
||||||
|
* @param array $directives
|
||||||
|
*/
|
||||||
|
public function __construct(array $directives = [])
|
||||||
|
{
|
||||||
|
parent::__construct('server', $directives);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/Config/Upstream.php
Normal file
51
src/Config/Upstream.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 21:07
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Config;
|
||||||
|
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Upstream
|
||||||
|
* @package Madkom\NginxConfigurator\Config
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Upstream extends Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds upstream name
|
||||||
|
* @var Param
|
||||||
|
*/
|
||||||
|
private $upstream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upstream constructor.
|
||||||
|
* @param Param $upstream
|
||||||
|
* @param Directive[] $directives
|
||||||
|
*/
|
||||||
|
public function __construct(Param $upstream, array $directives = [])
|
||||||
|
{
|
||||||
|
$this->upstream = $upstream;
|
||||||
|
parent::__construct('upstream', $directives);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() : string
|
||||||
|
{
|
||||||
|
return (string)$this->upstream->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
"{$this->name} %s {\n\t%s\n}\n",
|
||||||
|
$this->upstream,
|
||||||
|
implode("\n\t", (array)$this->childNodes->getIterator())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/Exception/GrammarException.php
Normal file
20
src/Exception/GrammarException.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 10.04.16
|
||||||
|
* Time: 09:12
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GrammarException
|
||||||
|
* @package Madkom\NginxConfigurator\Exception
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class GrammarException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
20
src/Exception/UnrecognizedContextException.php
Normal file
20
src/Exception/UnrecognizedContextException.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 13.04.16
|
||||||
|
* Time: 09:22
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UnrecognizedContextException
|
||||||
|
* @package Madkom\NginxConfigurator\Exception
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class UnrecognizedContextException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
42
src/Node/Context.php
Normal file
42
src/Node/Context.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 20:53
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Context
|
||||||
|
* @package Madkom\NginxConfigurator\Node
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
abstract class Context extends Node
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Context constructor.
|
||||||
|
* @param string $name
|
||||||
|
* @param Directive[] $directives
|
||||||
|
*/
|
||||||
|
public function __construct($name, array $directives = [])
|
||||||
|
{
|
||||||
|
parent::__construct($name);
|
||||||
|
foreach ($directives as $directive) {
|
||||||
|
$this->append($directive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
$childStrings = [];
|
||||||
|
foreach ($this->childNodes as $childNode) {
|
||||||
|
$childStrings[] = implode("\n\t", explode("\n", (string)$childNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
"{$this->name} {\n\t%s\n}\n",
|
||||||
|
implode("\n\t", $childStrings)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/Node/Directive.php
Normal file
77
src/Node/Directive.php
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 06.04.16
|
||||||
|
* Time: 13:40
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
use Madkom\Collection\CustomTypedCollection;
|
||||||
|
use Traversable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Directive
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Directive extends Node
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds directive name
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name;
|
||||||
|
/**
|
||||||
|
* Holds param collection
|
||||||
|
* @var CustomTypedCollection|Param[]
|
||||||
|
*/
|
||||||
|
protected $params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directive constructor.
|
||||||
|
* @param string $name
|
||||||
|
* @param array $params
|
||||||
|
*/
|
||||||
|
public function __construct(string $name, array $params = [])
|
||||||
|
{
|
||||||
|
parent::__construct($name);
|
||||||
|
$this->params = new class($params) extends CustomTypedCollection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves collection type
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getType() : string
|
||||||
|
{
|
||||||
|
return Param::class;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve directive name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName() : string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve params iterator
|
||||||
|
* @return Traversable|Param[]
|
||||||
|
*/
|
||||||
|
public function getParams() : Traversable
|
||||||
|
{
|
||||||
|
return $this->params->getIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return sprintf("{$this->name} %s;", implode(' ', (array)$this->params->getIterator()));
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/Node/Literal.php
Normal file
24
src/Node/Literal.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 10:32
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Literal
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Literal extends Param
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return '"' . addslashes($this->value) . '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
122
src/Node/Node.php
Normal file
122
src/Node/Node.php
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 06.04.16
|
||||||
|
* Time: 13:23
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
use Countable;
|
||||||
|
use IteratorAggregate;
|
||||||
|
use Madkom\Collection\CustomTypedCollection;
|
||||||
|
use Traversable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Node
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
abstract class Node implements Countable, IteratorAggregate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds parent node
|
||||||
|
* @var Node
|
||||||
|
*/
|
||||||
|
protected $parent;
|
||||||
|
/**
|
||||||
|
* Holds node name
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = '';
|
||||||
|
/**
|
||||||
|
* Holds node children
|
||||||
|
* @var CustomTypedCollection
|
||||||
|
*/
|
||||||
|
protected $childNodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node constructor.
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->childNodes = new class extends CustomTypedCollection {
|
||||||
|
/**
|
||||||
|
* Retrieves collection type
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getType() : string
|
||||||
|
{
|
||||||
|
return Node::class;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append new child node
|
||||||
|
* @param Node $node
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function append(Node $node) : bool
|
||||||
|
{
|
||||||
|
$node->parent = $this;
|
||||||
|
|
||||||
|
return $this->childNodes->add($node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove child node
|
||||||
|
* @param Node $node
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function remove(Node $node) : bool
|
||||||
|
{
|
||||||
|
return $this->childNodes->remove($node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for specified nodes
|
||||||
|
* @param callable $checker
|
||||||
|
* @return CustomTypedCollection
|
||||||
|
*/
|
||||||
|
public function search(callable $checker) : CustomTypedCollection
|
||||||
|
{
|
||||||
|
return $this->childNodes->filter($checker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count elements of an object
|
||||||
|
* @link http://php.net/manual/en/countable.count.php
|
||||||
|
* @return int The custom count as an integer.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* The return protocol is cast to an integer.
|
||||||
|
* @since 5.1.0
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->childNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an external iterator
|
||||||
|
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
|
||||||
|
* @return Traversable An instance of an object implementing <b>Iterator</b> or
|
||||||
|
* <b>Traversable</b>
|
||||||
|
* @since 5.0.0
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return $this->childNodes->getIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return (string)implode("\n", (array)$this->childNodes->getIterator());
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/Node/Param.php
Normal file
47
src/Node/Param.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 10:31
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Param
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Param
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Param constructor.
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function __construct(string $value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve param value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getValue() : string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Node/RootNode.php
Normal file
28
src/Node/RootNode.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 08.04.16
|
||||||
|
* Time: 21:18
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RootNode
|
||||||
|
* @package Madkom\NginxConfigurator\node
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class RootNode extends Node
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* RootNode constructor.
|
||||||
|
* @param Node[] $nodes
|
||||||
|
*/
|
||||||
|
public function __construct(array $nodes = [])
|
||||||
|
{
|
||||||
|
parent::__construct('');
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$this->append($node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
220
src/Parser.php
Normal file
220
src/Parser.php
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: mbrzuchalski
|
||||||
|
* Date: 06.04.16
|
||||||
|
* Time: 13:01
|
||||||
|
*/
|
||||||
|
namespace Madkom\NginxConfigurator;
|
||||||
|
|
||||||
|
use Ferno\Loco\ConcParser;
|
||||||
|
use Ferno\Loco\Grammar;
|
||||||
|
use Ferno\Loco\GreedyMultiParser;
|
||||||
|
use Ferno\Loco\GreedyStarParser;
|
||||||
|
use Ferno\Loco\LazyAltParser;
|
||||||
|
use Ferno\Loco\ParseFailureException;
|
||||||
|
use Ferno\Loco\RegexParser;
|
||||||
|
use Ferno\Loco\StringParser;
|
||||||
|
use Madkom\NginxConfigurator\Config\Events;
|
||||||
|
use Madkom\NginxConfigurator\Config\Http;
|
||||||
|
use Madkom\NginxConfigurator\Config\Location;
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Config\Upstream;
|
||||||
|
use Madkom\NginxConfigurator\Exception\GrammarException;
|
||||||
|
use Madkom\NginxConfigurator\Exception\UnrecognizedContextException;
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Literal;
|
||||||
|
use Madkom\NginxConfigurator\Node\Param;
|
||||||
|
use Madkom\NginxConfigurator\Node\RootNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Parser
|
||||||
|
* @package Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
*/
|
||||||
|
class Parser extends Grammar
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds parsed filename
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $filename;
|
||||||
|
/**
|
||||||
|
* Holds parsed string
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct('syntax', [
|
||||||
|
'syntax' => new GreedyStarParser(new LazyAltParser(['directive', 'section'])),
|
||||||
|
'sections' => new GreedyMultiParser('section', 0, 2),
|
||||||
|
'section' => new ConcParser(
|
||||||
|
[
|
||||||
|
'section-name',
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
new LazyAltParser(['params', new LazyAltParser(['space', 'opt-space'])]),
|
||||||
|
new StringParser('{'),
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
new GreedyMultiParser(new LazyAltParser(['directive', 'section']), 0, null),
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
new StringParser('}'),
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
],
|
||||||
|
[$this, 'parseSection']
|
||||||
|
),
|
||||||
|
'section-name' => new RegexParser('/^[a-z0-9\_]+/i'),
|
||||||
|
|
||||||
|
'directives' => new GreedyMultiParser('directive', 0, null),
|
||||||
|
'directive' => new LazyAltParser([
|
||||||
|
new ConcParser([
|
||||||
|
'directive-name',
|
||||||
|
'semicolon',
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
], [$this, 'parseDirective']),
|
||||||
|
new ConcParser([
|
||||||
|
'directive-name',
|
||||||
|
'space',
|
||||||
|
'params',
|
||||||
|
'semicolon',
|
||||||
|
new LazyAltParser(['space', 'opt-space']),
|
||||||
|
], [$this, 'parseDirective'])
|
||||||
|
]),
|
||||||
|
'directive-name' => new RegexParser('/^[a-z0-9\_]+/i'),
|
||||||
|
|
||||||
|
'params' => new GreedyMultiParser(new ConcParser(['param', 'opt-space'], function ($param, $space) {
|
||||||
|
return $param;
|
||||||
|
}), 0, null),
|
||||||
|
'param' => new LazyAltParser(['literal', 'param-name']),
|
||||||
|
'param-name' => new RegexParser('/^[^\s\r\n\{\}\;\"\']+/i', function ($match) {
|
||||||
|
return new Param($match);
|
||||||
|
}),
|
||||||
|
'literal' => new LazyAltParser([
|
||||||
|
new RegexParser('/^"([^"]*)"/', function ($match0, $match1) {
|
||||||
|
return new Literal($match1);
|
||||||
|
}),
|
||||||
|
new RegexParser("/^'([^']*)'/", function ($match0, $match1) {
|
||||||
|
return new Literal($match1);
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
|
||||||
|
'semicolon' => new StringParser(';', function () {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
'space' => new GreedyStarParser('whitespace/comment', function () {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
'whitespace/comment' => new LazyAltParser(['whitespace', 'comment'], function () {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
'comment' => new RegexParser("/^#+([^\r\n]*)/", function () {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
'whitespace' => new RegexParser("/^[ \t\r\n]+/"),
|
||||||
|
'opt-space' => new RegexParser("/^[ \t\r\n]?/"),
|
||||||
|
'eol' => new LazyAltParser([new StringParser("\r"), new StringParser("\n")], function () {
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
], function (array $nodes = []) {
|
||||||
|
return new RootNode($nodes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses config file
|
||||||
|
* @param string $filename
|
||||||
|
* @return mixed
|
||||||
|
* @throws ParseFailureException
|
||||||
|
*/
|
||||||
|
public function parseFile(string $filename) : RootNode
|
||||||
|
{
|
||||||
|
$this->content = null;
|
||||||
|
$this->filename = $filename;
|
||||||
|
|
||||||
|
return $this->parse(file_get_contents($filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses string
|
||||||
|
* @param string $string
|
||||||
|
* @return mixed
|
||||||
|
* @throws ParseFailureException
|
||||||
|
*/
|
||||||
|
public function parse($string) : RootNode
|
||||||
|
{
|
||||||
|
$this->content = $string;
|
||||||
|
$this->filename = null;
|
||||||
|
|
||||||
|
return parent::parse($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses section entries
|
||||||
|
* @param string $section Section name
|
||||||
|
* @param null $space0 Ignored
|
||||||
|
* @param Param[] $params Params collection
|
||||||
|
* @param null $open Ignored
|
||||||
|
* @param null $space1 Ignored
|
||||||
|
* @param Directive[] $directives Directives collection
|
||||||
|
* @return Context
|
||||||
|
* @throws GrammarException
|
||||||
|
* @throws UnrecognizedContextException
|
||||||
|
*/
|
||||||
|
protected function parseSection($section, $space0 = null, $params, $open = null, $space1 = null, $directives) : Context
|
||||||
|
{
|
||||||
|
switch ($section) {
|
||||||
|
case 'server':
|
||||||
|
return new Server($directives);
|
||||||
|
|
||||||
|
case 'http':
|
||||||
|
return new Http($directives);
|
||||||
|
|
||||||
|
case 'location':
|
||||||
|
$modifier = null;
|
||||||
|
if (sizeof($params) == 2) {
|
||||||
|
list($modifier, $location) = $params;
|
||||||
|
} elseif (sizeof($params) == 1) {
|
||||||
|
$location = $params[0];
|
||||||
|
} else {
|
||||||
|
throw new GrammarException(
|
||||||
|
sprintf(
|
||||||
|
"Location context missing in %s",
|
||||||
|
$this->filename ? var_export($this->filename, true) : var_export($this->content, true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new Location($location, $modifier, $directives);
|
||||||
|
|
||||||
|
case 'events':
|
||||||
|
return new Events($directives);
|
||||||
|
|
||||||
|
case 'upstream':
|
||||||
|
list($upstream) = $params;
|
||||||
|
return new Upstream($upstream, $directives);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnrecognizedContextException(
|
||||||
|
sprintf(
|
||||||
|
"Unrecognized context: {$section} found in %s",
|
||||||
|
$this->filename ? var_export($this->filename, true) : var_export($this->content, true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses directive
|
||||||
|
* @param string $name
|
||||||
|
* @param null $space
|
||||||
|
* @param array $params
|
||||||
|
* @return Directive
|
||||||
|
*/
|
||||||
|
protected function parseDirective(string $name, $space = null, $params = []) : Directive
|
||||||
|
{
|
||||||
|
return new Directive($name, is_null($params) ? [] : $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
0
tests/coverage/.gitkeep
Normal file
0
tests/coverage/.gitkeep
Normal file
187
tests/spec/ParserSpec.php
Normal file
187
tests/spec/ParserSpec.php
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace spec\Madkom\NginxConfigurator;
|
||||||
|
|
||||||
|
use Ferno\Loco\ParseFailureException;
|
||||||
|
use Madkom\NginxConfigurator\Config\Location;
|
||||||
|
use Madkom\NginxConfigurator\Config\Server;
|
||||||
|
use Madkom\NginxConfigurator\Node\Context;
|
||||||
|
use Madkom\NginxConfigurator\Node\Directive;
|
||||||
|
use Madkom\NginxConfigurator\Node\Node;
|
||||||
|
use Madkom\NginxConfigurator\Node\RootNode;
|
||||||
|
use Madkom\NginxConfigurator\Parser;
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use PHPUnit_Framework_Assert as Assert;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Traversable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ParserSpec
|
||||||
|
* @package spec\Madkom\NginxConfigurator
|
||||||
|
* @author Michał Brzuchalski <m.brzuchalski@madkom.pl>
|
||||||
|
* @mixin Parser
|
||||||
|
*/
|
||||||
|
class ParserSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
function it_is_initializable()
|
||||||
|
{
|
||||||
|
$this->shouldHaveType('Madkom\NginxConfigurator\Parser');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ParseFailureException
|
||||||
|
*/
|
||||||
|
function it_can_parse_directive()
|
||||||
|
{
|
||||||
|
/** @var RootNode $root */
|
||||||
|
$root = $this->parse(<<<EOF
|
||||||
|
internal;
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
$root->shouldReturnAnInstanceOf(RootNode::class);
|
||||||
|
|
||||||
|
$directives = $root->search(function (Node $node) {
|
||||||
|
return $node;
|
||||||
|
})->getWrappedObject();
|
||||||
|
/** @var Directive $directive */
|
||||||
|
foreach ($directives as $directive) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Assert::assertEquals($directive->getName(), 'internal');
|
||||||
|
Assert::assertInstanceOf(Traversable::class, $directive->getParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_can_parse_multiple_directives_with_params()
|
||||||
|
{
|
||||||
|
$root = $this->parse(<<<EOF
|
||||||
|
internal;
|
||||||
|
## comment with two hashes
|
||||||
|
sendfile off; # comment after directive
|
||||||
|
#comment beetween directives
|
||||||
|
set \$true 1;
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
$root->shouldReturnAnInstanceOf(RootNode::class);
|
||||||
|
|
||||||
|
$directives = $root->search(function (Node $node) {
|
||||||
|
return $node;
|
||||||
|
})->getWrappedObject();
|
||||||
|
/** @var Directive $directive */
|
||||||
|
foreach ($directives as $index => $directive) {
|
||||||
|
switch ($index) {
|
||||||
|
case 0:
|
||||||
|
Assert::assertEquals($directive->getName(), 'internal');
|
||||||
|
Assert::assertInstanceOf(Traversable::class, $directive->getParams());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Assert::assertEquals($directive->getName(), 'sendfile');
|
||||||
|
Assert::assertInstanceOf(Traversable::class, $directive->getParams());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Assert::assertEquals($directive->getName(), 'set');
|
||||||
|
Assert::assertInstanceOf(Traversable::class, $directive->getParams());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_can_parse_multiple_directives_with_params_in_context()
|
||||||
|
{
|
||||||
|
$root = $this->parse(<<<EOF
|
||||||
|
server {
|
||||||
|
internal;
|
||||||
|
## comment with two hashes
|
||||||
|
sendfile off; # comment after directive
|
||||||
|
#comment beetween directives
|
||||||
|
set \$true 1;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
$root->shouldReturnAnInstanceOf(RootNode::class);
|
||||||
|
|
||||||
|
$contexts = $root->search(function (Node $node) {
|
||||||
|
return $node;
|
||||||
|
})->getWrappedObject();
|
||||||
|
/** @var Context $context */
|
||||||
|
foreach ($contexts as $index => $context) {
|
||||||
|
switch ($index) {
|
||||||
|
case 0:
|
||||||
|
Assert::assertInstanceOf(Server::class, $context);
|
||||||
|
/** @var Directive $directive */
|
||||||
|
foreach ($context as $index => $directive) {
|
||||||
|
switch ($index) {
|
||||||
|
case 0:
|
||||||
|
Assert::assertEquals('internal', $directive->getName());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Assert::assertEquals('sendfile', $directive->getName());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Assert::assertEquals('set', $directive->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_can_parse_multiple_directives_with_params_in_multiple_contexts()
|
||||||
|
{
|
||||||
|
$root = $this->parse(<<<EOF
|
||||||
|
server {
|
||||||
|
internal;
|
||||||
|
## comment with two hashes
|
||||||
|
sendfile off; # comment after directive
|
||||||
|
#comment beetween directives
|
||||||
|
set \$true 1;
|
||||||
|
|
||||||
|
location ~ /app {
|
||||||
|
set \$true 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendfile off;
|
||||||
|
|
||||||
|
events {
|
||||||
|
sendfile off;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
$root->shouldReturnAnInstanceOf(RootNode::class);
|
||||||
|
|
||||||
|
$contexts = $root->search(function (Node $node) {
|
||||||
|
return $node;
|
||||||
|
})->getWrappedObject();
|
||||||
|
/** @var Context $context */
|
||||||
|
foreach ($contexts as $index => $context) {
|
||||||
|
switch ($index) {
|
||||||
|
case 0:
|
||||||
|
Assert::assertInstanceOf(Server::class, $context);
|
||||||
|
/** @var Directive $directive */
|
||||||
|
foreach ($context as $index => $directive) {
|
||||||
|
switch ($index) {
|
||||||
|
case 0:
|
||||||
|
Assert::assertEquals('internal', $directive->getName());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Assert::assertEquals('sendfile', $directive->getName());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Assert::assertEquals('set', $directive->getName());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Assert::assertInstanceOf(Location::class, $directive);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
Assert::assertInstanceOf(Directive::class, $context);
|
||||||
|
Assert::assertEquals('sendfile', $context->getName());
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user