Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUPH-87 | Encapsulate Symfony Expression Language #52

Open
wants to merge 28 commits into
base: move-tokenizer-rules-to-di
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3c712c1
Can cache container as a runtime option.
rhift Nov 11, 2019
b735929
HOTFIX | Reference correct Bradfab version in Upgrading doc
jpmarcotte Jan 9, 2020
875334f
HOTFIX | Use correct namespace in S/R reference
jpmarcotte Jan 9, 2020
79beccb
Merge pull request #44 from neighborhoods/HOTFIX-bradfab-eol-beta9
jpmarcotte Jan 13, 2020
c0f2711
Merge pull request #45 from neighborhoods/HOTFIX-template-namespace
jpmarcotte Jan 13, 2020
a585662
BUPH-93 | add tests for GlobalTemplateTrees
jpmarcotte Jan 15, 2020
de2cbe5
BUPH-93 | support multiple template trees
jpmarcotte Jan 15, 2020
2fe07bd
BUPH-93 | use named directory trees
jpmarcotte Jan 15, 2020
e86db82
BUPH-93 | update README to include Multiple Template Tree usage
jpmarcotte Jan 15, 2020
2b7b583
BUPH-103 | add support for Fablet-defined Template Tree preferences
jpmarcotte Jan 16, 2020
651d928
Update buphalo
rhift Jan 21, 2020
37f4c2a
Update makephar
rhift Jan 21, 2020
28c74dc
Update upgrade
rhift Jan 21, 2020
91975f7
Merge pull request #48 from neighborhoods/bugfix/bin-scripts-director…
jpmarcotte Jan 21, 2020
74cd8ca
BUPH-104 | add test for per-actor template trees
jpmarcotte Feb 1, 2020
fb43844
BUPH-104 | support per-actor preferred template trees
jpmarcotte Feb 1, 2020
8e58116
BUPH-103 | use snake_case for fab file preferred_template_trees
jpmarcotte Feb 1, 2020
2ba0917
Merge branch 'BUPH-103-per-file-template-ordering' into BUPH-104-per-…
jpmarcotte Feb 1, 2020
c274d36
BUPH-104 | use updated key for fab file preferred_template_trees
jpmarcotte Feb 1, 2020
c7bf854
Merge pull request #31 from neighborhoods/can-cache-container-as-runt…
jpmarcotte Feb 3, 2020
848a2cb
BUPH-93 | move template name default to interface const
jpmarcotte Feb 26, 2020
80efa44
Merge pull request #46 from neighborhoods/BUPH-93-multiple-template-t…
jpmarcotte Feb 26, 2020
dfd44db
Merge pull request #49 from neighborhoods/BUPH-103-per-file-template-…
jpmarcotte Feb 26, 2020
24b02e1
Merge branch 'master' into BUPH-104-per-actor-template-ordering
jpmarcotte Feb 26, 2020
661ea96
BUPH-104 | strongly type actor preferred template trees
jpmarcotte Feb 26, 2020
d4e386e
BUPH-104 | strongly type returns for actor preferred template trees
jpmarcotte Feb 26, 2020
4358828
Merge pull request #50 from neighborhoods/BUPH-104-per-actor-template…
jpmarcotte Feb 26, 2020
46b172b
Encapsulate Symfony Expression Language
Apr 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Buphalo leverages an environment variable API for runtime options. The following
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=/PATH/TO/SOURCE/DIRECTORY \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=/PATH/TO/FABRICATION/DIRECTORY \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=VENDOR\\PRODUCT\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=/PATH/TO/TEMPLATE/TREE/DIRECTORY \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=TreeName:/PATH/TO/TEMPLATE/TREE/DIRECTORY \
php bin/v1/buphalo
```

Expand All @@ -41,7 +41,7 @@ For example, in order to Buphalo Buphalo (assuming Buphalo is installed as a com
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=$PWD/vendor/neighborhoods/buphalo/src/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=$PWD/vendor/neighborhoods/buphalo/fab/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=Neighborhoods\\Buphalo\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=buphalo:$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
php vendor/bin/v1/buphalo
```

Expand All @@ -55,7 +55,7 @@ environment variable. As an env var this is "typed" as a CSV. It is then cast to
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=$PWD/vendor/neighborhoods/buphalo/src/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=$PWD/vendor/neighborhoods/buphalo/fab/v1 \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=Neighborhoods\\Buphalo\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=buphalo:$PWD/vendor/neighborhoods/buphalo/template-tree/V1 \
Neighborhoods_Buphalo_V1_FabricationFile_Map_BuilderInterface__FinderFileNames=Connection.buphalo.v1.fabrication.yml,Connection2.buphalo.v1.fabrication.yml
php vendor/bin/v1/buphalo
```
Expand Down Expand Up @@ -189,11 +189,23 @@ actors:
### Adding A New Or Updating An Existing Template
* Copy Buphalo's `template-tree` directory to your software product's root directory if you have not done so already.
* Add or change the appropriate PHP and dependency injection service definition YAML files in the position that you want them under your `template-tree/v1` directory.
* Be sure to update your environmental varaible to the following (or the equivalent if you used a different path for the copied directory)
* Be sure to update your environmental variable to the following (or the equivalent if you used a different path for the copied directory)
```bash
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/v1 \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=TreeName:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/v1 \
```

### Using Multiple Template Trees
* Buphalo supports using multiple template trees.
* If using multiple trees, each template tree MUST be named by including a "TreeName:" prefix to the directory path
* If using a single template tree, the template tree identifier MAY be left unnamed.
* Separate each path identifier with a comma
* Buphalo will attempt to look through the template tree directories in the order specified, and will use the first matching template it finds
* example:
```
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=primary:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/primary,secondary:/PATH/TO/SOFTWARE_PRODUCT/ROOT/template-tree/secondary \
```


## Definitions

### Fabrication File
Expand Down
2 changes: 1 addition & 1 deletion bin/v1/buphalo
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
declare(strict_types=1);
error_reporting(E_ALL);

include_once __DIR__ . 'buphalo.php';
include_once __DIR__ . '/buphalo.php';
12 changes: 12 additions & 0 deletions bin/v1/generate-symfony-expression-language.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

cd "$(dirname "$0")" || exit
cd ../..
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__SourceDirectoryPath=$PWD/src \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__FabricationDirectoryPath=$PWD/fab \
Neighborhoods_Buphalo_V1_TargetApplication_BuilderInterface__NamespacePrefix=Neighborhoods\\Buphalo\\ \
Neighborhoods_Buphalo_V1_TemplateTree_Map_Builder_FactoryInterface__TemplateTreeDirectoryPaths=$PWD/template-tree/V1 \
Neighborhoods_Buphalo_V1_FabricationFile_Map_BuilderInterface__FinderFileNames=\
ExpressionLanguageDecorator.buphalo.v1.fabrication.yml,\
ExpressionLanguage.buphalo.v1.fabrication.yml \
php bin/v1/buphalo
2 changes: 1 addition & 1 deletion bin/v1/makephar
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
declare(strict_types=1);
error_reporting(E_ALL);

include_once __DIR__ . 'makephar.php';
include_once __DIR__ . '/makephar.php';
2 changes: 1 addition & 1 deletion bin/v1/upgrade
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
declare(strict_types=1);
error_reporting(E_ALL);

include_once __DIR__ . 'upgrade.php';
include_once __DIR__ . '/upgrade.php';
4 changes: 2 additions & 2 deletions docker/xdebug.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ xdebug.remote_enable=On
xdebug.remote_autostart=On
xdebug.remote_connect_back=Off
xdebug.remote_mode=req
xdebug.remote_port=9001
xdebug.remote_host=docker.for.mac.localhost
xdebug.remote_port=9040
xdebug.remote_host=dockerhost
6 changes: 3 additions & 3 deletions docs/Upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This should allow you to upgrade specific files as desired in case there are iss
As such, we recommend maintaining your own template directory where it'll be easier to include your own templates
as you find the need for them.

- Do a search/replace to change all occurences of `Neighborhoods\Bradfab` in your new template directory to
- Do a search/replace to change all occurences of `Neighborhoods\Bradfab\Template` in your new template directory to
`Neighborhoods\BuphaloTemplateTree`
- Replace all `Actor` references with `PrimaryActorName`, including moving files/directories.

Expand All @@ -27,7 +27,7 @@ This should allow you to upgrade specific files as desired in case there are iss
probably ended in `Template/Actor/` (because Bradfab did not support Primary Actor Generation).
Because Buphalo *does* support Primary Actor Generation, you should probably remove `Actor/` from this variable.
- If you are using both Bradfab and Buphalo during a transition period:
- Use the bradfab `1.0.0-eol` release which has fixes to prevent it from reading Buphalo files.
- Use the bradfab `1.0.0-beta9` release which has fixes to prevent it from reading Buphalo files.
- Have your `buphalo.sh` script target a different directory than bradfab does and then merge the two directories
with something like `cp -R`.

Expand All @@ -36,4 +36,4 @@ If you find that the automatic upgrade script isn't sufficient and you need to k
let us know.
In the interim, you can delete any `.buphalo.v1.fabrication.yml` files that aren't working for you and stick with your
old bradfab files until you can get everything working in Buphalo.
(As above, you will need to upgrade bradfab to `1.0.0-eol`.)
(As above, you will need to upgrade bradfab to `1.0.0-beta9`.)
81 changes: 70 additions & 11 deletions src/V1/Actor/Template/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
use Neighborhoods\Buphalo\V1\Actor\TemplateInterface;
use Neighborhoods\Buphalo\V1\FabricationFile;
use Neighborhoods\Buphalo\V1\TemplateTree;
use Neighborhoods\Buphalo\V1\TemplateTreeInterface;
use RuntimeException;

class Builder implements BuilderInterface
{
use Factory\AwareTrait;
use Actor\AwareTrait;
use FabricationFile\Actor\AwareTrait;
use FabricationFile\AwareTrait;
use TemplateTree\Map\Repository\AwareTrait;

protected $FilePath;
Expand All @@ -32,20 +34,77 @@ public function build(): TemplateInterface
protected function getFilePath(): string
{
if ($this->FilePath === null) {
$actorTemplateFilePathCandidate = sprintf(
'%s/%s',
$this->getTemplateTreeMapRepository()->get()->current()->getDirectoryPath(),
$this->getFabricationFileActor()->getTemplateRelativeFilePath()
);
$actorTemplateFilePath = realpath($actorTemplateFilePathCandidate);
if ($actorTemplateFilePath === false) {
throw new RuntimeException(
sprintf('The actor template file [%s] does not exist.', $actorTemplateFilePathCandidate)
);
$actorTemplateFilePathCandidates = $this->buildActorTemplateFilePathCandidates();
foreach($actorTemplateFilePathCandidates as $actorTemplateFilePathCandidate) {
$actorTemplateFilePath = realpath($actorTemplateFilePathCandidate);
if ($actorTemplateFilePath !== false) {
$this->FilePath = $actorTemplateFilePath;
return $this->FilePath;
}
}
$this->FilePath = $actorTemplateFilePath;

throw new RuntimeException(
sprintf('No actor template file was found, checked: %s', implode(',', $actorTemplateFilePathCandidates))
);
}

return $this->FilePath;
}

private function buildActorTemplateFilePathCandidates(): array
{
$actorTemplateFilePathCandidates = [];

$templateTreeMap = $this->getTemplateTreeMapRepository()->get();

// Let the Actor preferences be used over the Fabrication File ones
if ($this->getFabricationFileActor()->hasPreferredTemplateTrees()) {
foreach($this->getFabricationFileActor()->getPreferredTemplateTrees() as $treeName) {
if (isset($templateTreeMap[$treeName])) {
$path = $this->buildTemplatePath($templateTreeMap[$treeName]);
$actorTemplateFilePathCandidates[$path] = true;
} else {
throw new \RuntimeException(
sprintf('Template tree %s referenced in %s > %s has not been defined.',
$treeName,
$this->getFabricationFile()->getFilePath(),
$this->getFabricationFileActor()->getFileName()
)
);
}
}
}

// Let the Fabrication File preferences be used over global ones
if ($this->getFabricationFile()->hasPreferredTemplateTrees()) {
foreach ($this->getFabricationFile()->getPreferredTemplateTrees() as $treeName) {
if (isset($templateTreeMap[$treeName])) {
$path = $this->buildTemplatePath($templateTreeMap[$treeName]);
$actorTemplateFilePathCandidates[$path] = true;
} else {
throw new \RuntimeException(
sprintf('Template tree %s referenced in %s has not been defined.',
$treeName,
$this->getFabricationFile()->getFilePath()
)
);
}
}
}

foreach($templateTreeMap as $templateTree) {
$path = $this->buildTemplatePath($templateTree);
$actorTemplateFilePathCandidates[$path] = true;
}

return array_keys($actorTemplateFilePathCandidates);
}

private function buildTemplatePath(TemplateTreeInterface $templateTree): string
{
return implode(DIRECTORY_SEPARATOR, [
$templateTree->getDirectoryPath(),
$this->getFabricationFileActor()->getTemplateRelativeFilePath(),
]);
}
}
3 changes: 3 additions & 0 deletions src/V1/Actor/Template/BuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Neighborhoods\Buphalo\V1\Actor\TemplateInterface;
use Neighborhoods\Buphalo\V1\ActorInterface;
use Neighborhoods\Buphalo\V1\FabricationFile;
use Neighborhoods\Buphalo\V1\FabricationFileInterface;

interface BuilderInterface
{
Expand All @@ -14,4 +15,6 @@ public function build(): TemplateInterface;
public function setActor(ActorInterface $Actor);

public function setFabricationFileActor(FabricationFile\ActorInterface $FabricationFileActor);

public function setFabricationFile(FabricationFileInterface $FabricationFileActor);
}
1 change: 1 addition & 0 deletions src/V1/Actor/Template/Tokenizer/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function build(): TokenizerInterface
$templateBuilder = $this->getActorTemplateBuilderFactory()->create();
$templateBuilder->setActor($this->getActor());
$templateBuilder->setFabricationFileActor($this->getFabricationFileActor());
$templateBuilder->setFabricationFile($this->getFabricationFile());
$actorTemplate = $templateBuilder->build();

$annotationTokenizerBuilder = $this->getActorTemplateAnnotationTokenizerBuilderFactory()->create();
Expand Down
50 changes: 49 additions & 1 deletion src/V1/Buphalo.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace Neighborhoods\Buphalo\V1;

use InvalidArgumentException;
use LogicException;
use Neighborhoods\Buphalo\V1\Fabricator\FactoryInterface;
use Neighborhoods\Buphalo\V1\Protean;
use ReflectionClass;
Expand All @@ -11,21 +13,67 @@ class Buphalo implements BuphaloInterface
{
use Protean\Container\Builder\AwareTrait;

protected const CAN_CACHE_CONTAINER = 'Neighborhoods_Buphalo_V1_Buphalo__CanCacheContainer';

private $CanCacheContainerFromEnvironment;
private $CanCacheContainer;

public function run(): BuphaloInterface
{
/** @noinspection PhpUnhandledExceptionInspection */
$this->getProteanContainerBuilder()->setCachedContainerFileName(
sprintf(
'%s.php',
(new ReflectionClass($this))->getShortName()
)
);
$this->getProteanContainerBuilder()->setCanBuildZendExpressive(false);
$this->getProteanContainerBuilder()->setCanCacheContainer(false);
$this->getProteanContainerBuilder()->setCanCacheContainer($this->getCanCacheContainer());
$this->getProteanContainerBuilder()->registerServiceAsPublic(FactoryInterface::class);
/** @var FabricatorInterface $fabricator */
$fabricator = $this->getProteanContainerBuilder()->build()->get(FactoryInterface::class)->create();
$fabricator->fabricate();

return $this;
}

public function getCanCacheContainer(): bool
{
if ($this->CanCacheContainer === null) {
$this->CanCacheContainer = $this->getCanCacheContainerFromEnvironment();
}

return $this->CanCacheContainer;
}

public function setCanCacheContainer(bool $CanCacheContainer): BuphaloInterface
{
if ($this->CanCacheContainer !== null) {
throw new LogicException('Can Cache Container is already set.');
}

$this->CanCacheContainer = $CanCacheContainer;

return $this;
}

protected function getCanCacheContainerFromEnvironment(): bool
{
if (isset($_ENV[self::CAN_CACHE_CONTAINER])) {
if ($_ENV[self::CAN_CACHE_CONTAINER] === 'true' || $_ENV[self::CAN_CACHE_CONTAINER] === 'false') {
$this->CanCacheContainerFromEnvironment = (bool)$_ENV[self::CAN_CACHE_CONTAINER];
} else {
throw new InvalidArgumentException(
sprintf('%s is not boolean. Given "%s"',
self::CAN_CACHE_CONTAINER,
$_ENV[self::CAN_CACHE_CONTAINER]
)
);
}
} else {
$this->CanCacheContainerFromEnvironment = false;
}

return $this->CanCacheContainerFromEnvironment;
}
}
26 changes: 26 additions & 0 deletions src/V1/FabricationFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class FabricationFile implements FabricationFileInterface
protected $RelativeDirectoryPath;
protected $DirectoryPath;
protected $Actors;
protected $PreferredTemplateTrees;

public function getActors(): Actor\MapInterface
{
Expand Down Expand Up @@ -155,4 +156,29 @@ public function setDirectoryPath(string $DirectoryPath): FabricationFileInterfac

return $this;
}

public function getPreferredTemplateTrees(): array
{
if ($this->PreferredTemplateTrees === null) {
throw new \LogicException('FabricationFile PreferredTemplateTrees has not been set.');
}

return $this->PreferredTemplateTrees;
}

public function hasPreferredTemplateTrees(): bool
{
return $this->PreferredTemplateTrees !== null;
}

public function setPreferredTemplateTrees(string ...$PreferredTemplateTrees): FabricationFileInterface
{
if ($this->PreferredTemplateTrees !== null) {
throw new \LogicException('FabricationFile PreferredTemplateTrees is already set.');
}

$this->PreferredTemplateTrees = $PreferredTemplateTrees;

return $this;
}
}
Loading