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