mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 07:23:13 +00:00
Merge branch 'hoa-compiler' into elastic-indexer
Conflicts: lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php
This commit is contained in:
7
Makefile
Normal file
7
Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
config:
|
||||
@php bin/console compile:configuration
|
||||
|
||||
watch:
|
||||
@echo 'config/configuration.yml' | entr make config
|
||||
|
||||
.PHONY: config watch
|
@@ -14,6 +14,7 @@ namespace KonsoleKommander;
|
||||
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
||||
use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper;
|
||||
use Alchemy\Phrasea\Command\Setup\H264MappingGenerator;
|
||||
use Alchemy\Phrasea\Command\SearchEngine\Debug\QueryParseCommand;
|
||||
use Alchemy\Phrasea\Command\SearchEngine\IndexCreateCommand;
|
||||
use Alchemy\Phrasea\Command\SearchEngine\IndexDropCommand;
|
||||
use Alchemy\Phrasea\Command\SearchEngine\IndexFull;
|
||||
@@ -127,6 +128,7 @@ if ($cli['search_engine.type'] === SearchEngineInterface::TYPE_ELASTICSEARCH) {
|
||||
$cli->command(new IndexCreateCommand());
|
||||
$cli->command(new IndexDropCommand());
|
||||
$cli->command(new IndexPopulateCommand());
|
||||
$cli->command(new QueryParseCommand());
|
||||
}
|
||||
|
||||
$cli->command(new WebsocketServer('ws-server:run'));
|
||||
|
@@ -73,7 +73,8 @@
|
||||
"vierbergenlars/php-semver" : "~2.1",
|
||||
"zend/gdata" : "~1.12.1",
|
||||
"doctrine/migrations" : "1.0.x-dev@dev",
|
||||
"willdurand/negotiation" : "~1.3"
|
||||
"willdurand/negotiation" : "~1.3",
|
||||
"hoa/compiler": "2.14.09.23"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit" : "~3.7",
|
||||
@@ -83,7 +84,9 @@
|
||||
"behat/mink-extension" : "~1.0",
|
||||
"behat/mink-goutte-driver" : "~1.0",
|
||||
"behat/mink-selenium2-driver" : "~1.0",
|
||||
"fabpot/goutte" : "~1.0"
|
||||
"fabpot/goutte" : "~1.0",
|
||||
"hoa/dispatcher": "0.14.09.23",
|
||||
"hoa/console": "2.14.09.23"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
|
766
composer.lock
generated
766
composer.lock
generated
@@ -4,22 +4,16 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "69bf40de460d2f7a3407f1b905dde913",
|
||||
"hash": "73cfb65537610dfd0edc9cf6485c4ebb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "alchemy-fr/tcpdf-clone",
|
||||
"version": "6.0.039",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/alchemy-fr/tcpdf-clone.git",
|
||||
"url": "https://github.com/alchemy-fr/tcpdf-clone",
|
||||
"reference": "2ba0248a7187f1626df6c128750650416267f0e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/alchemy-fr/tcpdf-clone/zipball/2ba0248a7187f1626df6c128750650416267f0e7",
|
||||
"reference": "2ba0248a7187f1626df6c128750650416267f0e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
@@ -66,10 +60,6 @@
|
||||
"qrcode",
|
||||
"tcpdf"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/alchemy-fr/tcpdf-clone/tree/6.0.039",
|
||||
"issues": "https://github.com/alchemy-fr/tcpdf-clone/issues"
|
||||
},
|
||||
"time": "2013-10-13 16:11:17"
|
||||
},
|
||||
{
|
||||
@@ -113,7 +103,7 @@
|
||||
"homepage": "http://www.lickmychip.com/"
|
||||
},
|
||||
{
|
||||
"name": "nlegoff",
|
||||
"name": "Nicolas Le Goff",
|
||||
"email": "legoff.n@gmail.com"
|
||||
},
|
||||
{
|
||||
@@ -301,7 +291,7 @@
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"time": "2014-07-07 16:25:07"
|
||||
"time": "2014-07-07 14:01:51"
|
||||
},
|
||||
{
|
||||
"name": "alchemy/task-manager",
|
||||
@@ -372,12 +362,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/alchemy-fr/Zippy.git",
|
||||
"reference": "08008f82957b7dc2b54574b506687b33ecfe0589"
|
||||
"reference": "d2f5e88f2436b9c1294e8819d951822abe39e9a7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/08008f82957b7dc2b54574b506687b33ecfe0589",
|
||||
"reference": "08008f82957b7dc2b54574b506687b33ecfe0589",
|
||||
"url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/d2f5e88f2436b9c1294e8819d951822abe39e9a7",
|
||||
"reference": "d2f5e88f2436b9c1294e8819d951822abe39e9a7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -426,7 +416,7 @@
|
||||
"tar",
|
||||
"zip"
|
||||
],
|
||||
"time": "2014-09-03 08:10:41"
|
||||
"time": "2014-05-05 13:39:00"
|
||||
},
|
||||
{
|
||||
"name": "cboden/ratchet",
|
||||
@@ -747,7 +737,7 @@
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
@@ -935,8 +925,7 @@
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/",
|
||||
"role": "Creator"
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
@@ -954,7 +943,7 @@
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
@@ -1008,7 +997,7 @@
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
@@ -1026,12 +1015,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/migrations.git",
|
||||
"reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021"
|
||||
"reference": "4256449c5e2603a6b6ee5a78c7c4521d4d4430b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/migrations/zipball/1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021",
|
||||
"reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021",
|
||||
"url": "https://api.github.com/repos/doctrine/migrations/zipball/4256449c5e2603a6b6ee5a78c7c4521d4d4430b8",
|
||||
"reference": "4256449c5e2603a6b6ee5a78c7c4521d4d4430b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1062,12 +1051,14 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/",
|
||||
"role": "Creator"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
}
|
||||
],
|
||||
"description": "Database Schema migrations using Doctrine DBAL",
|
||||
@@ -1076,7 +1067,7 @@
|
||||
"database",
|
||||
"migrations"
|
||||
],
|
||||
"time": "2014-08-18 18:03:07"
|
||||
"time": "2014-07-09 07:58:02"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
@@ -1213,13 +1204,13 @@
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/igorw/evenement.git",
|
||||
"reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d"
|
||||
"url": "https://github.com/igorw/evenement",
|
||||
"reference": "v1.0.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/igorw/evenement/zipball/fa966683e7df3e5dd5929d984a44abfbd6bafe8d",
|
||||
"reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d",
|
||||
"url": "https://github.com/igorw/evenement/zipball/v1.0.0",
|
||||
"reference": "v1.0.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1246,7 +1237,7 @@
|
||||
"keywords": [
|
||||
"event-dispatcher"
|
||||
],
|
||||
"time": "2012-05-30 15:01:08"
|
||||
"time": "2012-05-30 08:01:08"
|
||||
},
|
||||
{
|
||||
"name": "facebook/php-sdk",
|
||||
@@ -1299,12 +1290,12 @@
|
||||
"version": "v2.3.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Atlantic18/DoctrineExtensions.git",
|
||||
"url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
|
||||
"reference": "35adcaae1a3f50d0d5b73aa50ed8fd28ee35ce54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/35adcaae1a3f50d0d5b73aa50ed8fd28ee35ce54",
|
||||
"url": "https://api.github.com/repos/l3pp4rd/DoctrineExtensions/zipball/35adcaae1a3f50d0d5b73aa50ed8fd28ee35ce54",
|
||||
"reference": "35adcaae1a3f50d0d5b73aa50ed8fd28ee35ce54",
|
||||
"shasum": ""
|
||||
},
|
||||
@@ -1372,7 +1363,7 @@
|
||||
"tree",
|
||||
"uploadable"
|
||||
],
|
||||
"time": "2014-01-12 16:34:06"
|
||||
"time": "2013-08-18 07:18:44"
|
||||
},
|
||||
{
|
||||
"name": "goodby/csv",
|
||||
@@ -1429,7 +1420,7 @@
|
||||
"export",
|
||||
"import"
|
||||
],
|
||||
"time": "2013-11-22 19:10:34"
|
||||
"time": "2014-01-12 16:34:06"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/guzzle",
|
||||
@@ -1523,6 +1514,433 @@
|
||||
],
|
||||
"time": "2014-08-11 04:32:36"
|
||||
},
|
||||
{
|
||||
"name": "hoa/compiler",
|
||||
"version": "2.14.09.23",
|
||||
"target-dir": "Hoa/Compiler",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Compiler.git",
|
||||
"reference": "51cdc8b21d13f2fcaa3f3a0d114247534849f8cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Compiler/zipball/51cdc8b21d13f2fcaa3f3a0d114247534849f8cb",
|
||||
"reference": "51cdc8b21d13f2fcaa3f3a0d114247534849f8cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0",
|
||||
"hoa/file": "~0.0",
|
||||
"hoa/iterator": "~0.0",
|
||||
"hoa/math": "~0.0",
|
||||
"hoa/visitor": "~0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Compiler": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Compiler library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"algebraic",
|
||||
"ast",
|
||||
"compiler",
|
||||
"context-free",
|
||||
"coverage",
|
||||
"exhaustive",
|
||||
"grammar",
|
||||
"isotropic",
|
||||
"language",
|
||||
"lexer",
|
||||
"library",
|
||||
"ll1",
|
||||
"llk",
|
||||
"parser",
|
||||
"pp",
|
||||
"random",
|
||||
"regular",
|
||||
"rule",
|
||||
"sampler",
|
||||
"syntax",
|
||||
"token",
|
||||
"trace",
|
||||
"uniform"
|
||||
],
|
||||
"time": "2014-09-23 09:50:46"
|
||||
},
|
||||
{
|
||||
"name": "hoa/core",
|
||||
"version": "2.14.09.23",
|
||||
"target-dir": "Hoa/Core",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Core.git",
|
||||
"reference": "e50354e69e451478223d1d0c1ce4f5d741ea7576"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Core/zipball/e50354e69e451478223d1d0c1ce4f5d741ea7576",
|
||||
"reference": "e50354e69e451478223d1d0c1ce4f5d741ea7576",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-spl": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "ext/mbstring must be present (or a third implementation).",
|
||||
"hoa/console": "To use the `hoa` script.",
|
||||
"hoa/dispatcher": "To use the `hoa` script.",
|
||||
"hoa/router": "To use the `hoa` script."
|
||||
},
|
||||
"bin": [
|
||||
"Bin/hoa"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Core": "."
|
||||
},
|
||||
"files": [
|
||||
"Core.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Core library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"consistency",
|
||||
"core",
|
||||
"data",
|
||||
"event",
|
||||
"library",
|
||||
"listener",
|
||||
"parameter",
|
||||
"protocol"
|
||||
],
|
||||
"time": "2014-09-23 09:45:22"
|
||||
},
|
||||
{
|
||||
"name": "hoa/file",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/File",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/File.git",
|
||||
"reference": "a39f62a28256180606115416cf27774966cf73e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/File/zipball/a39f62a28256180606115416cf27774966cf73e9",
|
||||
"reference": "a39f62a28256180606115416cf27774966cf73e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0",
|
||||
"hoa/iterator": "~0.0",
|
||||
"hoa/stream": "~0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\File": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\File library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"Socket",
|
||||
"directory",
|
||||
"file",
|
||||
"finder",
|
||||
"library",
|
||||
"link",
|
||||
"temporary"
|
||||
],
|
||||
"time": "2014-09-23 09:50:42"
|
||||
},
|
||||
{
|
||||
"name": "hoa/iterator",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/Iterator",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Iterator.git",
|
||||
"reference": "1ca570cab25ca359a1a9f4b4c449d49771fc6a5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Iterator/zipball/1ca570cab25ca359a1a9f4b4c449d49771fc6a5e",
|
||||
"reference": "1ca570cab25ca359a1a9f4b4c449d49771fc6a5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Iterator": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Iterator library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"iterator",
|
||||
"library"
|
||||
],
|
||||
"time": "2014-09-23 09:50:40"
|
||||
},
|
||||
{
|
||||
"name": "hoa/math",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/Math",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Math.git",
|
||||
"reference": "b52764f602095b4595658f581a504f039cef8d56"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Math/zipball/b52764f602095b4595658f581a504f039cef8d56",
|
||||
"reference": "b52764f602095b4595658f581a504f039cef8d56",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/compiler": "~2.0",
|
||||
"hoa/core": "~2.0",
|
||||
"hoa/iterator": "~0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Math": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Math library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"arrangement",
|
||||
"combination",
|
||||
"combinatorics",
|
||||
"counting",
|
||||
"library",
|
||||
"math",
|
||||
"permutation",
|
||||
"sampler",
|
||||
"set"
|
||||
],
|
||||
"time": "2014-09-23 14:02:37"
|
||||
},
|
||||
{
|
||||
"name": "hoa/stream",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/Stream",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Stream.git",
|
||||
"reference": "eaf9bfeb633b8a6bf0fba55e9c035db431024869"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Stream/zipball/eaf9bfeb633b8a6bf0fba55e9c035db431024869",
|
||||
"reference": "eaf9bfeb633b8a6bf0fba55e9c035db431024869",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Stream": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Stream library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"Context",
|
||||
"bucket",
|
||||
"composite",
|
||||
"filter",
|
||||
"in",
|
||||
"library",
|
||||
"out",
|
||||
"protocol",
|
||||
"stream",
|
||||
"wrapper"
|
||||
],
|
||||
"time": "2014-09-23 09:50:38"
|
||||
},
|
||||
{
|
||||
"name": "hoa/visitor",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/Visitor",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Visitor.git",
|
||||
"reference": "071523b6677466979e57a9f9ef61a46b76221935"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Visitor/zipball/071523b6677466979e57a9f9ef61a46b76221935",
|
||||
"reference": "071523b6677466979e57a9f9ef61a46b76221935",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Visitor": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Visitor library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"library",
|
||||
"structure",
|
||||
"visit",
|
||||
"visitor"
|
||||
],
|
||||
"time": "2014-09-23 09:50:51"
|
||||
},
|
||||
{
|
||||
"name": "igorw/get-in",
|
||||
"version": "v1.0.2",
|
||||
@@ -1596,7 +2014,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "0.7-dev"
|
||||
"dev-develop": "0.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1623,7 +2041,7 @@
|
||||
"image processing"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/nlegoff/Imagine/tree/flatten-layer"
|
||||
"source": "https://github.com/alchemy-fr/Imagine/tree/0.6.1-flatten-layer"
|
||||
},
|
||||
"time": "2014-10-08 16:23:33"
|
||||
},
|
||||
@@ -1932,9 +2350,9 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
@@ -2249,7 +2667,7 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Steve Clay",
|
||||
"name": "Stephen Clay",
|
||||
"email": "steve@mrclay.org",
|
||||
"homepage": "http://www.mrclay.org/",
|
||||
"role": "Developer"
|
||||
@@ -2435,21 +2853,21 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/romainneutron/Imagine-Silex-Service-Provider.git",
|
||||
"reference": "a8a7862ae90419f2b23746cd8436c2310e4eb084"
|
||||
"reference": "0.1.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/romainneutron/Imagine-Silex-Service-Provider/zipball/a8a7862ae90419f2b23746cd8436c2310e4eb084",
|
||||
"reference": "a8a7862ae90419f2b23746cd8436c2310e4eb084",
|
||||
"url": "https://api.github.com/repos/romainneutron/Imagine-Silex-Service-Provider/zipball/0.1.2",
|
||||
"reference": "0.1.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"imagine/imagine": "*",
|
||||
"php": ">=5.3.3",
|
||||
"silex/silex": "~1.0"
|
||||
"silex/silex": ">=1.0,<2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/browser-kit": "~2.0"
|
||||
"symfony/browser-kit": ">=2.0,<3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -2963,7 +3381,7 @@
|
||||
"metadata"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/alchemy-fr/PHPExiftool/tree/dev"
|
||||
"source": "https://github.com/alchemy-fr/PHPExiftool/tree/0.4.1-mwg-metadata-copy"
|
||||
},
|
||||
"time": "2014-10-08 16:09:02"
|
||||
},
|
||||
@@ -3001,9 +3419,9 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
@@ -3560,7 +3978,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Phraseanet Team",
|
||||
"email": "info@alchemy.fr",
|
||||
"email": "support@alchemy.fr",
|
||||
"homepage": "http://www.phraseanet.com/"
|
||||
}
|
||||
],
|
||||
@@ -3607,9 +4025,7 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Chris Corbyn"
|
||||
@@ -4522,6 +4938,242 @@
|
||||
],
|
||||
"time": "2014-10-09 15:52:51"
|
||||
},
|
||||
{
|
||||
"name": "hoa/console",
|
||||
"version": "2.14.09.23",
|
||||
"target-dir": "Hoa/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Console.git",
|
||||
"reference": "8466f74ddb5bd323357fe5464629c948a1fd8d25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Console/zipball/8466f74ddb5bd323357fe5464629c948a1fd8d25",
|
||||
"reference": "8466f74ddb5bd323357fe5464629c948a1fd8d25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0",
|
||||
"hoa/stream": "~0.0",
|
||||
"hoa/string": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl": "To enable hoa://Event/Console/Window:resize.",
|
||||
"hoa/dispatcher": "To use the console kit.",
|
||||
"hoa/router": "To use the console kit."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Console": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Console library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"autocompletion",
|
||||
"chrome",
|
||||
"cli",
|
||||
"console",
|
||||
"cursor",
|
||||
"getoption",
|
||||
"library",
|
||||
"option",
|
||||
"parser",
|
||||
"processus",
|
||||
"readline",
|
||||
"terminfo",
|
||||
"tput",
|
||||
"window"
|
||||
],
|
||||
"time": "2014-09-23 14:17:08"
|
||||
},
|
||||
{
|
||||
"name": "hoa/dispatcher",
|
||||
"version": "0.14.09.23",
|
||||
"target-dir": "Hoa/Dispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Dispatcher.git",
|
||||
"reference": "82924823fa9cedad9775f1ab4d51075e980ac2c6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Dispatcher/zipball/82924823fa9cedad9775f1ab4d51075e980ac2c6",
|
||||
"reference": "82924823fa9cedad9775f1ab4d51075e980ac2c6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"hoa/router": "Provide routers.",
|
||||
"hoa/view": "Provide view interface."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Dispatcher": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Dispatcher library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"dispatcher",
|
||||
"kit",
|
||||
"library"
|
||||
],
|
||||
"time": "2014-09-23 14:12:43"
|
||||
},
|
||||
{
|
||||
"name": "hoa/router",
|
||||
"version": "2.14.09.23",
|
||||
"target-dir": "Hoa/Router",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/Router.git",
|
||||
"reference": "8937785aecf7ca3b6dbd5f668eb97e15c672758d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/Router/zipball/8937785aecf7ca3b6dbd5f668eb97e15c672758d",
|
||||
"reference": "8937785aecf7ca3b6dbd5f668eb97e15c672758d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\Router": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\Router library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"http",
|
||||
"library",
|
||||
"router"
|
||||
],
|
||||
"time": "2014-09-23 09:50:57"
|
||||
},
|
||||
{
|
||||
"name": "hoa/string",
|
||||
"version": "2.14.09.23",
|
||||
"target-dir": "Hoa/String",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hoaproject/String.git",
|
||||
"reference": "c385ffb1382d919c63ab97acd6f62058179c5f2a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hoaproject/String/zipball/c385ffb1382d919c63ab97acd6f62058179c5f2a",
|
||||
"reference": "c385ffb1382d919c63ab97acd6f62058179c5f2a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"hoa/core": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "To get a better Hoa\\String::toAscii() and Hoa\\String::compareTo()."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Hoa\\String": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Enderlin",
|
||||
"email": "ivan.enderlin@hoa-project.net"
|
||||
},
|
||||
{
|
||||
"name": "Hoa community",
|
||||
"homepage": "http://hoa-project.net/"
|
||||
}
|
||||
],
|
||||
"description": "The Hoa\\String library.",
|
||||
"homepage": "http://hoa-project.net/",
|
||||
"keywords": [
|
||||
"library",
|
||||
"search",
|
||||
"string",
|
||||
"unicode"
|
||||
],
|
||||
"time": "2014-09-23 09:55:55"
|
||||
},
|
||||
{
|
||||
"name": "instaclick/php-webdriver",
|
||||
"version": "1.4.0",
|
||||
|
90
grammar/arithmetic.pp
Normal file
90
grammar/arithmetic.pp
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Hoa
|
||||
//
|
||||
//
|
||||
// @license
|
||||
//
|
||||
// New BSD License
|
||||
//
|
||||
// Copyright © 2007-2014, Ivan Enderlin. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Hoa nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Grammar \Hoa\Math\Arithmetic.
|
||||
//
|
||||
// Provide a grammar for arithmetic expressions.
|
||||
//
|
||||
// @author Stéphane Py <py.stephane1@gmail.com>
|
||||
// @author Sébastien Houze <s@verylastroom.com>
|
||||
// @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
|
||||
// @copyright Copyright © 2007-2014 Stéphane Py, Sébastien Houze, Ivan Enderlin.
|
||||
// @license New BSD License
|
||||
//
|
||||
|
||||
|
||||
%skip space \s
|
||||
%token bracket_ \(
|
||||
%token _bracket \)
|
||||
%token comma ,
|
||||
%token number (0|[1-9]\d*)(\.\d+)?([eE][\+\-]?\d+)?
|
||||
%token plus \+
|
||||
%token minus \-|−
|
||||
%token times \*|×
|
||||
%token div /|÷
|
||||
%token constant [A-Z_]+[A-Z0-9_]+
|
||||
%token id \w+
|
||||
|
||||
expression:
|
||||
primary() ( ::plus:: #addition expression() )?
|
||||
|
||||
primary:
|
||||
secondary() ( ::minus:: #substraction expression() )?
|
||||
|
||||
secondary:
|
||||
ternary() ( ::times:: #multiplication expression() )?
|
||||
|
||||
ternary:
|
||||
term() ( ::div:: #division expression() )?
|
||||
|
||||
term:
|
||||
( ::bracket_:: expression() ::_bracket:: #group )
|
||||
| number()
|
||||
| constant()
|
||||
| variable()
|
||||
| ( ::minus:: #negative | ::plus:: ) term()
|
||||
| function()
|
||||
|
||||
number:
|
||||
<number>
|
||||
|
||||
constant:
|
||||
<constant>
|
||||
|
||||
#variable:
|
||||
<id>
|
||||
|
||||
#function:
|
||||
<id> ::bracket_::
|
||||
( expression() ( ::comma:: expression() )* )?
|
||||
::_bracket::
|
36
grammar/json.pp
Normal file
36
grammar/json.pp
Normal file
@@ -0,0 +1,36 @@
|
||||
%skip space \s
|
||||
|
||||
%token true true
|
||||
%token false false
|
||||
%token null null
|
||||
%token quote_ " -> string
|
||||
%token string:escaped \\(["\\/bfnrt]|u[0-9a-fA-F]{4})
|
||||
%token string:string [^"\\]+
|
||||
%token string:_quote " -> default
|
||||
%token brace_ {
|
||||
%token _brace }
|
||||
%token bracket_ \[
|
||||
%token _bracket \]
|
||||
%token colon :
|
||||
%token comma ,
|
||||
%token number \-?(0|[1-9]\d*)(\.\d+)?([eE][\+\-]?\d+)?
|
||||
|
||||
value:
|
||||
<true> | <false> | <null> | string() | object() | array() | number()
|
||||
|
||||
string:
|
||||
::quote_::
|
||||
<string>
|
||||
::_quote::
|
||||
|
||||
number:
|
||||
<number>
|
||||
|
||||
#object:
|
||||
::brace_:: pair() ( ::comma:: pair() )* ::_brace::
|
||||
|
||||
#pair:
|
||||
string() ::colon:: value()
|
||||
|
||||
#array:
|
||||
::bracket_:: value() ( ::comma:: value() )* ::_bracket::
|
47
grammar/query.pp
Normal file
47
grammar/query.pp
Normal file
@@ -0,0 +1,47 @@
|
||||
%skip space \s
|
||||
|
||||
%token bracket_ \(
|
||||
%token _bracket \)
|
||||
%token quote_ " -> string
|
||||
%token string:string [^"]+
|
||||
%token string:_quote " -> default
|
||||
%token in IN
|
||||
%token and AND
|
||||
%token or OR
|
||||
%token except EXCEPT
|
||||
%token word [^\s\(\)]+
|
||||
|
||||
// relative order of precedence is NOT > XOR > AND > OR
|
||||
|
||||
#query:
|
||||
primary()
|
||||
|
||||
primary:
|
||||
secondary() ( ::except:: #except primary() )?
|
||||
|
||||
secondary:
|
||||
ternary() ( ::or:: #or primary() )?
|
||||
|
||||
ternary:
|
||||
quaternary() ( ::and:: #and primary() )?
|
||||
|
||||
quaternary:
|
||||
term() ( ::in:: #in word() )?
|
||||
|
||||
term:
|
||||
( ::bracket_:: primary() ::_bracket:: ) | text()
|
||||
|
||||
#text:
|
||||
( word() | keyword() | symbol() )+
|
||||
|
||||
word:
|
||||
<word> | string()
|
||||
|
||||
string:
|
||||
::quote_:: <string> ::_quote::
|
||||
|
||||
keyword:
|
||||
<in> | <except> | <and> | <or>
|
||||
|
||||
symbol:
|
||||
::bracket_:: | ::_bracket::
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\SearchEngine\Debug;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class QueryParseCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('searchengine:query:parse')
|
||||
->setDescription('Debug a search query')
|
||||
->addArgument(
|
||||
'query',
|
||||
InputArgument::REQUIRED,
|
||||
'The query to debug'
|
||||
)
|
||||
->addOption(
|
||||
'compiler-dump',
|
||||
'd',
|
||||
InputOption::VALUE_NONE,
|
||||
'Output underlying compiler AST before visitor processing'
|
||||
)
|
||||
->addOption(
|
||||
'no-compiler-postprocessing',
|
||||
'p',
|
||||
InputOption::VALUE_NONE,
|
||||
'Prevent AST optimization before visitor processing'
|
||||
)
|
||||
->addOption(
|
||||
'raw',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Only output query dump'
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$string = $input->getArgument('query');
|
||||
$raw = $input->getOption('raw');
|
||||
|
||||
if (!$raw) {
|
||||
$output->writeln(sprintf('Parsing search query: <comment>%s</comment>', $string));
|
||||
$output->writeln(str_repeat('-', 20));
|
||||
}
|
||||
|
||||
$postprocessing = !$input->getOption('no-compiler-postprocessing');
|
||||
|
||||
$parser = $this->container['query_parser'];
|
||||
if ($input->getOption('compiler-dump')) {
|
||||
$dump = $parser->dump($string, $postprocessing);
|
||||
} else {
|
||||
$query = $parser->parse($string, $postprocessing);
|
||||
$dump = $query->dump();
|
||||
}
|
||||
|
||||
if (!$raw) {
|
||||
$output->writeln($dump);
|
||||
} else {
|
||||
$output->write($dump);
|
||||
}
|
||||
}
|
||||
}
|
@@ -18,10 +18,13 @@ use Alchemy\Phrasea\SearchEngine\Elastic\ElasticSearchEngine;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryParser;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
||||
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine;
|
||||
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngineSubscriber;
|
||||
use Elasticsearch\Client;
|
||||
use Hoa\Compiler\Llk\Llk;
|
||||
use Hoa\File\Read;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
use Silex\Application;
|
||||
@@ -126,6 +129,21 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
|
||||
$app['elasticsearch.options']['index']
|
||||
);
|
||||
});
|
||||
|
||||
$app['query_parser.grammar_path'] = function ($app) {
|
||||
$configPath = ['registry', 'searchengine', 'query-grammar-path'];
|
||||
$grammarPath = $app['conf']->get($configPath, 'grammar/query.pp');
|
||||
$projectRoot = '../../../../..';
|
||||
|
||||
return realpath(implode('/', [__DIR__, $projectRoot, $grammarPath]));
|
||||
};
|
||||
|
||||
$app['query_parser'] = $app->share(function ($app) {
|
||||
$grammarPath = $app['query_parser.grammar_path'];
|
||||
$parser = Llk::load(new Read($grammarPath));
|
||||
|
||||
return new QueryParser($parser);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
|
@@ -2,48 +2,19 @@
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
|
||||
class AndExpression extends Node
|
||||
class AndExpression extends BinaryOperator
|
||||
{
|
||||
protected $members = array();
|
||||
|
||||
public function __construct(Node $left, Node $right)
|
||||
{
|
||||
$this->members[] = $left;
|
||||
$this->members[] = $right;
|
||||
}
|
||||
|
||||
public function getMembers()
|
||||
{
|
||||
return $this->members;
|
||||
}
|
||||
protected $operator = 'AND';
|
||||
|
||||
public function getQuery($fields = ['_all'])
|
||||
{
|
||||
$rules = array();
|
||||
foreach ($this->members as $member) {
|
||||
$rules[] = $member->getQuery($fields);
|
||||
}
|
||||
$left = $this->left->getQuery($fields);
|
||||
$right = $this->right->getQuery($fields);
|
||||
|
||||
return array(
|
||||
'bool' => array(
|
||||
'must' => count($rules) > 1 ? $rules : $rules[0]
|
||||
'must' => array($left, $right)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%s)', implode(' AND ', $this->members));
|
||||
}
|
||||
|
||||
public function isFullTextOnly()
|
||||
{
|
||||
foreach ($this->members as $member) {
|
||||
if (!$member->isFullTextOnly()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
|
||||
abstract class BinaryOperator extends Node
|
||||
{
|
||||
protected $left;
|
||||
protected $right;
|
||||
protected $operator = 'BIN_OP';
|
||||
|
||||
public function __construct(Node $left, Node $right)
|
||||
{
|
||||
$this->left = $left;
|
||||
$this->right = $right;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%s %s %s)', $this->left, $this->operator, $this->right);
|
||||
}
|
||||
|
||||
public function isFullTextOnly()
|
||||
{
|
||||
return $this->left->isFullTextOnly()
|
||||
&& $this->right->isFullTextOnly();
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
|
||||
class ExceptExpression extends BinaryOperator
|
||||
{
|
||||
protected $operator = 'EXCEPT';
|
||||
|
||||
public function getQuery($fields = ['_all'])
|
||||
{
|
||||
$left = $this->left->getQuery($fields);
|
||||
$right = $this->right->getQuery($fields);
|
||||
|
||||
return array(
|
||||
'bool' => array(
|
||||
'must' => $left,
|
||||
'must_not' => $right
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
|
||||
class KeywordNode extends Node
|
||||
class FieldNode extends Node
|
||||
{
|
||||
protected $keyword;
|
||||
|
@@ -7,9 +7,9 @@ class InExpression extends Node
|
||||
protected $field;
|
||||
protected $expression;
|
||||
|
||||
public function __construct(KeywordNode $keyword, $expression)
|
||||
public function __construct(FieldNode $field, $expression)
|
||||
{
|
||||
$this->field = $keyword;
|
||||
$this->field = $field;
|
||||
$this->expression = $expression;
|
||||
}
|
||||
|
||||
|
@@ -2,48 +2,19 @@
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
|
||||
class OrExpression extends Node
|
||||
class OrExpression extends BinaryOperator
|
||||
{
|
||||
protected $members = array();
|
||||
|
||||
public function __construct(Node $left, Node $right)
|
||||
{
|
||||
$this->members[] = $left;
|
||||
$this->members[] = $right;
|
||||
}
|
||||
|
||||
public function getMembers()
|
||||
{
|
||||
return $this->members;
|
||||
}
|
||||
protected $operator = 'OR';
|
||||
|
||||
public function getQuery($fields = ['_all'])
|
||||
{
|
||||
$rules = array();
|
||||
foreach ($this->members as $member) {
|
||||
$rules[] = $member->getQuery($fields);
|
||||
}
|
||||
$left = $this->left->getQuery($fields);
|
||||
$right = $this->right->getQuery($fields);
|
||||
|
||||
return array(
|
||||
'bool' => array(
|
||||
'should' => count($rules) > 1 ? $rules : $rules[0]
|
||||
'should' => array($left, $right)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%s)', implode(' OR ', $this->members));
|
||||
}
|
||||
|
||||
public function isFullTextOnly()
|
||||
{
|
||||
foreach ($this->members as $member) {
|
||||
if (!$member->isFullTextOnly()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -8,9 +8,10 @@ class QuotedTextNode extends TextNode
|
||||
{
|
||||
return array(
|
||||
'multi_match' => array(
|
||||
'type' => 'phrase',
|
||||
'fields' => $fields,
|
||||
'query' => $this->text,
|
||||
'operator' => 'and'
|
||||
// 'operator' => 'and'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@@ -30,4 +30,9 @@ class TextNode extends Node
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getText()
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\SearchQuery;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
|
||||
@@ -270,8 +271,8 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
public function query($string, $offset, $perPage, SearchEngineOptions $options = null)
|
||||
{
|
||||
$options = $options ?: new SearchEngineOptions();
|
||||
$parser = new QueryParser();
|
||||
$ast = $parser->parse($string);
|
||||
|
||||
$searchQuery = $this->app['query_parser']->parse($string);
|
||||
|
||||
// Contains the full thesaurus paths to search on
|
||||
$pathsToFilter = [];
|
||||
@@ -279,9 +280,9 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
$collectFields = [];
|
||||
|
||||
// Only search in thesaurus for full text search
|
||||
if ($ast->isFullTextOnly()) {
|
||||
if ($searchQuery->isFullTextOnly()) {
|
||||
$termFields = $this->expendToAnalyzedFieldsNames('value', null, $this->app['locale']);
|
||||
$termsQuery = $ast->getQuery($termFields);
|
||||
$termsQuery = $searchQuery->getElasticsearchQuery($termFields);
|
||||
|
||||
$params = $this->createTermQueryParams($termsQuery, $options);
|
||||
$terms = $this->doExecute('search', $params);
|
||||
@@ -313,7 +314,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
$recordQuery = [
|
||||
'bool' => [
|
||||
'should' => [
|
||||
$ast->getQuery($recordFields)
|
||||
$searchQuery->getElasticsearchQuery($recordFields)
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -376,7 +377,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
$results[] = new \record_adapter($this->app, $databoxId, $recordId, $n++);
|
||||
}
|
||||
|
||||
$query['_ast'] = (string) $ast;
|
||||
$query['_ast'] = $searchQuery->dump();
|
||||
$query['_paths'] = $pathsToFilter;
|
||||
$query['_richFields'] = $collectFields;
|
||||
$query['query'] = json_encode($params);
|
||||
|
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Exception;
|
||||
|
||||
class QueryException extends Exception
|
||||
{
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
class NodeTypes
|
||||
{
|
||||
// Tree node types
|
||||
const QUERY = '#query';
|
||||
const IN_EXPR = '#in';
|
||||
const AND_EXPR = '#and';
|
||||
const OR_EXPR = '#or';
|
||||
const EXCEPT_EXPR = '#except';
|
||||
const FIELD = '#field';
|
||||
const TEXT = '#text';
|
||||
// Token types for leaf nodes
|
||||
const TOKEN_WORD = 'word';
|
||||
const TOKEN_STRING = 'string';
|
||||
}
|
37
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/Query.php
Normal file
37
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/Query.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Node;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\AndOperator;
|
||||
use Hoa\Compiler\Llk\TreeNode;
|
||||
|
||||
class Query
|
||||
{
|
||||
private $root;
|
||||
|
||||
public function __construct(Node $root)
|
||||
{
|
||||
$this->root = $root;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method seems weird to me, the implementation returns true when the
|
||||
* query doesn't contain IN statements, but that doesn't define a full text
|
||||
* search.
|
||||
*/
|
||||
public function isFullTextOnly()
|
||||
{
|
||||
return $this->root->isFullTextOnly();
|
||||
}
|
||||
|
||||
public function getElasticsearchQuery($fields = array())
|
||||
{
|
||||
return $this->root->getQuery($fields);
|
||||
}
|
||||
|
||||
public function dump()
|
||||
{
|
||||
return $this->root->__toString();
|
||||
}
|
||||
}
|
108
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/QueryParser.php
Normal file
108
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/QueryParser.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||
use Hoa\Compiler\Exception\Exception as CompilerException;
|
||||
use Hoa\Compiler\Llk\Parser;
|
||||
use Hoa\Compiler\Llk\TreeNode;
|
||||
use Hoa\Compiler\Visitor\Dump as DumpVisitor;
|
||||
use Hoa\Visitor\Visit;
|
||||
|
||||
class QueryParser
|
||||
{
|
||||
private $parser;
|
||||
|
||||
private static $leftAssociativeOperators = array(
|
||||
NodeTypes::AND_EXPR,
|
||||
NodeTypes::OR_EXPR,
|
||||
NodeTypes::EXCEPT_EXPR
|
||||
);
|
||||
|
||||
public function __construct(Parser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Query object from a string
|
||||
*/
|
||||
public function parse($string, $postprocessing = true)
|
||||
{
|
||||
return $this->visitString($string, new QueryVisitor(), $postprocessing);
|
||||
}
|
||||
|
||||
public function dump($string, $postprocessing = true)
|
||||
{
|
||||
return $this->visitString($string, new DumpVisitor(), $postprocessing);
|
||||
}
|
||||
|
||||
private function visitString($string, Visit $visitor, $postprocessing = true)
|
||||
{
|
||||
try {
|
||||
$ast = $this->parser->parse($string);
|
||||
} catch (CompilerException $e) {
|
||||
throw new QueryException('Provided query is not valid', 0, $e);
|
||||
}
|
||||
|
||||
if ($postprocessing) {
|
||||
$this->fixOperatorAssociativity($ast);
|
||||
}
|
||||
|
||||
return $visitor->visit($ast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the tree to restore left-associativity of some operators
|
||||
*
|
||||
* @param TreeNode $root AST root node
|
||||
*/
|
||||
private function fixOperatorAssociativity(TreeNode &$root)
|
||||
{
|
||||
switch ($root->getChildrenNumber()) {
|
||||
case 0:
|
||||
// Leaf nodes can't be rotated, and have no childs
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// We only want to rotate tree contained in the left associative
|
||||
// subset of operators
|
||||
$rootType = $root->getId();
|
||||
if (!in_array($rootType, self::$leftAssociativeOperators)) {
|
||||
break;
|
||||
}
|
||||
// Do not break operator precedence
|
||||
$pivot = $root->getChild(1);
|
||||
if ($pivot->getId() !== $rootType) {
|
||||
break;
|
||||
}
|
||||
$this->leftRotateTree($root);
|
||||
break;
|
||||
}
|
||||
|
||||
// Recursively fix tree branches
|
||||
$children = $root->getChildren();
|
||||
foreach ($children as $index => $_) {
|
||||
$this->fixOperatorAssociativity($children[$index]);
|
||||
}
|
||||
$root->setChildren($children);
|
||||
}
|
||||
|
||||
private function leftRotateTree(TreeNode &$root)
|
||||
{
|
||||
// Pivot = Root.Left
|
||||
$pivot = $root->getChild(1);
|
||||
// Root.Right = Pivot.Left
|
||||
$children = $root->getChildren();
|
||||
$children[1] = $pivot->getChild(0); // Pivot, rotation side
|
||||
$root->setChildren($children);
|
||||
// Pivot.Left = Root
|
||||
$children = $pivot->getChildren();
|
||||
$children[0] = $root;
|
||||
$pivot->setChildren($children);
|
||||
// Root = Pivot
|
||||
$root = $pivot;
|
||||
}
|
||||
}
|
||||
|
132
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/QueryVisitor.php
Normal file
132
lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/QueryVisitor.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
use Hoa\Visitor\Element;
|
||||
use Hoa\Visitor\Visit;
|
||||
|
||||
class QueryVisitor implements Visit
|
||||
{
|
||||
public function visit(Element $element, &$handle = null, $eldnah = null)
|
||||
{
|
||||
if (null !== $value = $element->getValue()) {
|
||||
return $this->visitToken($value['token'], $value['value']);
|
||||
}
|
||||
|
||||
return $this->visitNode($element);
|
||||
}
|
||||
|
||||
private function visitToken($token, $value)
|
||||
{
|
||||
switch ($token) {
|
||||
case NodeTypes::TOKEN_WORD:
|
||||
return new AST\TextNode($value);
|
||||
|
||||
case NodeTypes::TOKEN_STRING:
|
||||
return new AST\QuotedTextNode($value);
|
||||
|
||||
default:
|
||||
// Generic handling off other tokens for unresctricted text
|
||||
return new AST\TextNode($value);
|
||||
}
|
||||
}
|
||||
|
||||
private function visitNode(Element $element)
|
||||
{
|
||||
switch ($element->getId()) {
|
||||
case NodeTypes::QUERY:
|
||||
return $this->visitQuery($element);
|
||||
|
||||
case NodeTypes::IN_EXPR:
|
||||
return $this->visitInNode($element);
|
||||
|
||||
case NodeTypes::AND_EXPR:
|
||||
return $this->visitAndNode($element);
|
||||
|
||||
case NodeTypes::OR_EXPR:
|
||||
return $this->visitOrNode($element);
|
||||
|
||||
case NodeTypes::EXCEPT_EXPR:
|
||||
return $this->visitExceptNode($element);
|
||||
|
||||
case NodeTypes::TEXT:
|
||||
return $this->visitText($element);
|
||||
|
||||
default:
|
||||
throw new \Exception(sprintf('Unknown node type "%s".', $element->getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private function visitQuery(Element $element)
|
||||
{
|
||||
foreach ($element->getChildren() as $child) {
|
||||
$root = $child->accept($this);
|
||||
}
|
||||
return new Query($root);
|
||||
}
|
||||
|
||||
private function visitInNode(Element $element)
|
||||
{
|
||||
if ($element->getChildrenNumber() !== 2) {
|
||||
throw new \Exception('IN expression can only have 2 childs.');
|
||||
}
|
||||
$expression = $element->getChild(0)->accept($this);
|
||||
$field = new AST\FieldNode($element->getChild(1)->getValue()['value']);
|
||||
return new AST\InExpression($field, $expression);
|
||||
}
|
||||
|
||||
private function visitAndNode(Element $element)
|
||||
{
|
||||
return $this->handleBinaryOperator($element, function($left, $right) {
|
||||
return new AST\AndExpression($left, $right);
|
||||
});
|
||||
}
|
||||
|
||||
private function visitOrNode(Element $element)
|
||||
{
|
||||
return $this->handleBinaryOperator($element, function($left, $right) {
|
||||
return new AST\OrExpression($left, $right);
|
||||
});
|
||||
}
|
||||
|
||||
private function visitExceptNode(Element $element)
|
||||
{
|
||||
return $this->handleBinaryOperator($element, function($left, $right) {
|
||||
return new AST\ExceptExpression($left, $right);
|
||||
});
|
||||
}
|
||||
|
||||
private function handleBinaryOperator(Element $element, \Closure $factory)
|
||||
{
|
||||
if ($element->getChildrenNumber() !== 2) {
|
||||
throw new \Exception('Binary expression can only have 2 childs.');
|
||||
}
|
||||
$left = $element->getChild(0)->accept($this);
|
||||
$right = $element->getChild(1)->accept($this);
|
||||
|
||||
return $factory($left, $right);
|
||||
}
|
||||
|
||||
private function visitText(Element $element)
|
||||
{
|
||||
$root = null;
|
||||
foreach ($element->getChildren() as $child) {
|
||||
$node = $child->accept($this);
|
||||
if ($root) {
|
||||
// Merge text nodes together, but not with quoted ones
|
||||
if ($root instanceof AST\TextNode &&
|
||||
!$root instanceof AST\QuotedTextNode &&
|
||||
!$node instanceof AST\QuotedTextNode) {
|
||||
$root = new AST\TextNode(sprintf('%s %s', $root->getText(), $node->getText()));
|
||||
} else {
|
||||
$root = new AST\AndExpression($root, $node);
|
||||
}
|
||||
} else {
|
||||
$root = $node;
|
||||
}
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user