Skip to content
This repository has been archived by the owner on Feb 6, 2020. It is now read-only.

Created tool to inject factory maps into configuration #161

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions bin/create-factory-map
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env php
<?php
/**
* @link http://github.com/zendframework/zend-servicemanager for the canonical source repository
* @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be 2018?

* @license http://framework.zend.com/license/new-bsd New BSD License
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May use https?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*/

namespace Zend\ServiceManager;

// Setup/verify autoloading
if (file_exists($a = getcwd() . '/vendor/autoload.php')) {
require $a;
} elseif (file_exists($a = __DIR__ . '/../../../autoload.php')) {
require $a;
} elseif (file_exists($a = __DIR__ . '/../vendor/autoload.php')) {
require $a;
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$autoload = array_filter(
    [
        getcwd() . '/autoload.php',
        __DIR__ . '/../../../autoload.php',
        __DIR__ . '/../vendor/autoload.php',
    ],
    'is_file'
);

fwrite(STDERR, 'Cannot locate autoloader; please run "composer install"' . PHP_EOL);
exit(1);
}

$command = new Tool\FactoryMapperCommand($argv[0]);
$status = $command(array_slice($argv, 1));
exit($status);
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"container-interop/container-interop-implementation": "^1.1"
},
"bin": [
"bin/create-factory-map",
"bin/generate-deps-for-config-factory",
"bin/generate-factory-for-class"
],
Expand Down
50 changes: 50 additions & 0 deletions doc/book/console-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,53 @@ $ ./vendor/bin/generate-factory-for-class \

The class generated implements `Zend\ServiceManager\Factory\FactoryInterface`,
and is generated within the same namespace as the originating class.

## create-factory-map

```bash
Usage:

create-factory-map [-h|--help|help] <configFile> <className> <factoryName> [<key>]

Arguments:

-h|--help|help This usage message
<configFile> Path to an config file in which to map the factory.
If the file does not exist, it will be created. If
it does exist, it must return an array.
<className> Name of the class to map to a factory.
<factoryName> Name of the factory class to use with <className>.
[<key>] (Optional) The top-level configuration key under which
the factory map should appear; defaults to
"service_manager".

Reads the provided configuration file, creating it if necessary, and
injects it with a mapping of the given class to its factory. If key is
provided, the factory configuration will be injected under that key, and
not the default "service_manager" key.
```

This utility maps the given class to the given factory, writing it to the
specified configuration file. If a key is given, then the mapping will occur
under that top-level key (the default is the `service_manager` key).

As an example, if using this to map a controller for a zend-mvc application, you
might use:

```bash
$ ./vendor/bin/create-factory-map \
> module/Application/config/module.config.php \
> "Application\\Controller\\PingController" \
> "Zend\\Mvc\Controller\\LazyControllerAbstractFactory" \
> controllers
```

For Expressive, you might do the following to map middleware to a factory:

```bash
$ ./vendor/bin/create-factory-map \
> config/autoload/routes.global.php \
> "Application\\Middleware\\PingMiddleware" \
> "Zend\\ServiceManager\\AbstractFactory\\ReflectionBasedAbstractFactory" \
> dependencies
```
88 changes: 1 addition & 87 deletions src/Tool/ConfigDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,7 @@

class ConfigDumper
{
const CONFIG_TEMPLATE = <<<EOC
<?php
/**
* This file generated by %s.
* Generated %s
*/

return %s;
EOC;
use ConfigDumperTrait;

/**
* @param array $config
Expand Down Expand Up @@ -151,82 +143,4 @@ public function createFactoryMappings(array $config, $className)
$config['service_manager']['factories'][$className] = ConfigAbstractFactory::class;
return $config;
}

/**
* @param array $config
* @return string
*/
public function dumpConfigFile(array $config)
{
$prepared = $this->prepareConfig($config);
return sprintf(
self::CONFIG_TEMPLATE,
get_class($this),
date('Y-m-d H:i:s'),
$prepared
);
}

/**
* @param array|Traversable $config
* @param int $indentLevel
* @return string
*/
private function prepareConfig($config, $indentLevel = 1)
{
$indent = str_repeat(' ', $indentLevel * 4);
$entries = [];
foreach ($config as $key => $value) {
$key = $this->createConfigKey($key);
$entries[] = sprintf(
'%s%s%s,',
$indent,
$key ? sprintf('%s => ', $key) : '',
$this->createConfigValue($value, $indentLevel)
);
}

$outerIndent = str_repeat(' ', ($indentLevel - 1) * 4);

return sprintf(
"[\n%s\n%s]",
implode("\n", $entries),
$outerIndent
);
}

/**
* @param string|int|null $key
* @return null|string
*/
private function createConfigKey($key)
{
if (is_string($key) && class_exists($key)) {
return sprintf('\\%s::class', $key);
}

if (is_int($key)) {
return null;
}

return sprintf("'%s'", $key);
}

/**
* @param mixed $value
* @param int $indentLevel
* @return string
*/
private function createConfigValue($value, $indentLevel)
{
if (is_array($value) || $value instanceof Traversable) {
return $this->prepareConfig($value, $indentLevel + 1);
}

if (is_string($value) && class_exists($value)) {
return sprintf('\\%s::class', $value);
}

return var_export($value, true);
}
}
101 changes: 101 additions & 0 deletions src/Tool/ConfigDumperTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
/**
* @link http://github.com/zendframework/zend-servicemanager for the canonical source repository
* @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\ServiceManager\Tool;

use Traversable;

trait ConfigDumperTrait
{
private $configTemplate = <<<EOC
<?php
/**
* This file generated by %s.
* Generated %s
*/

return %s;
EOC;

/**
* @param array $config
* @return string
*/
public function dumpConfigFile(array $config)
{
$prepared = $this->prepareConfig($config);
return sprintf(
$this->configTemplate,
get_class($this),
date('Y-m-d H:i:s'),
$prepared
);
}

/**
* @param array|Traversable $config
* @param int $indentLevel
* @return string
*/
private function prepareConfig($config, $indentLevel = 1)
{
$indent = str_repeat(' ', $indentLevel * 4);
$entries = [];
foreach ($config as $key => $value) {
$key = $this->createConfigKey($key);
$entries[] = sprintf(
'%s%s%s,',
$indent,
$key ? sprintf('%s => ', $key) : '',
$this->createConfigValue($value, $indentLevel)
);
}

$outerIndent = str_repeat(' ', ($indentLevel - 1) * 4);

return sprintf(
"[\n%s\n%s]",
implode("\n", $entries),
$outerIndent
);
}

/**
* @param string|int|null $key
* @return null|string
*/
private function createConfigKey($key)
{
if (is_string($key) && class_exists($key)) {
return sprintf('\\%s::class', $key);
}

if (is_int($key)) {
return null;
}

return sprintf("'%s'", $key);
}

/**
* @param mixed $value
* @param int $indentLevel
* @return string
*/
private function createConfigValue($value, $indentLevel)
{
if (is_array($value) || $value instanceof Traversable) {
return $this->prepareConfig($value, $indentLevel + 1);
}

if (is_string($value) && class_exists($value)) {
return sprintf('\\%s::class', $value);
}

return var_export($value, true);
}
}
Loading