1<?php
2
3declare(strict_types=1);
4
5namespace DI;
6
7use DI\Definition\ArrayDefinitionExtension;
8use DI\Definition\EnvironmentVariableDefinition;
9use DI\Definition\Helper\AutowireDefinitionHelper;
10use DI\Definition\Helper\CreateDefinitionHelper;
11use DI\Definition\Helper\FactoryDefinitionHelper;
12use DI\Definition\Reference;
13use DI\Definition\StringDefinition;
14use DI\Definition\ValueDefinition;
15
16if (! function_exists('DI\value')) {
17    /**
18     * Helper for defining a value.
19     *
20     * @param mixed $value
21     */
22    function value($value) : ValueDefinition
23    {
24        return new ValueDefinition($value);
25    }
26}
27
28if (! function_exists('DI\create')) {
29    /**
30     * Helper for defining an object.
31     *
32     * @param string|null $className Class name of the object.
33     *                               If null, the name of the entry (in the container) will be used as class name.
34     */
35    function create(string $className = null) : CreateDefinitionHelper
36    {
37        return new CreateDefinitionHelper($className);
38    }
39}
40
41if (! function_exists('DI\autowire')) {
42    /**
43     * Helper for autowiring an object.
44     *
45     * @param string|null $className Class name of the object.
46     *                               If null, the name of the entry (in the container) will be used as class name.
47     */
48    function autowire(string $className = null) : AutowireDefinitionHelper
49    {
50        return new AutowireDefinitionHelper($className);
51    }
52}
53
54if (! function_exists('DI\factory')) {
55    /**
56     * Helper for defining a container entry using a factory function/callable.
57     *
58     * @param callable $factory The factory is a callable that takes the container as parameter
59     *                          and returns the value to register in the container.
60     */
61    function factory($factory) : FactoryDefinitionHelper
62    {
63        return new FactoryDefinitionHelper($factory);
64    }
65}
66
67if (! function_exists('DI\decorate')) {
68    /**
69     * Decorate the previous definition using a callable.
70     *
71     * Example:
72     *
73     *     'foo' => decorate(function ($foo, $container) {
74     *         return new CachedFoo($foo, $container->get('cache'));
75     *     })
76     *
77     * @param callable $callable The callable takes the decorated object as first parameter and
78     *                           the container as second.
79     */
80    function decorate($callable) : FactoryDefinitionHelper
81    {
82        return new FactoryDefinitionHelper($callable, true);
83    }
84}
85
86if (! function_exists('DI\get')) {
87    /**
88     * Helper for referencing another container entry in an object definition.
89     */
90    function get(string $entryName) : Reference
91    {
92        return new Reference($entryName);
93    }
94}
95
96if (! function_exists('DI\env')) {
97    /**
98     * Helper for referencing environment variables.
99     *
100     * @param string $variableName The name of the environment variable.
101     * @param mixed $defaultValue The default value to be used if the environment variable is not defined.
102     */
103    function env(string $variableName, $defaultValue = null) : EnvironmentVariableDefinition
104    {
105        // Only mark as optional if the default value was *explicitly* provided.
106        $isOptional = 2 === func_num_args();
107
108        return new EnvironmentVariableDefinition($variableName, $isOptional, $defaultValue);
109    }
110}
111
112if (! function_exists('DI\add')) {
113    /**
114     * Helper for extending another definition.
115     *
116     * Example:
117     *
118     *     'log.backends' => DI\add(DI\get('My\Custom\LogBackend'))
119     *
120     * or:
121     *
122     *     'log.backends' => DI\add([
123     *         DI\get('My\Custom\LogBackend')
124     *     ])
125     *
126     * @param mixed|array $values A value or an array of values to add to the array.
127     *
128     * @since 5.0
129     */
130    function add($values) : ArrayDefinitionExtension
131    {
132        if (! is_array($values)) {
133            $values = [$values];
134        }
135
136        return new ArrayDefinitionExtension($values);
137    }
138}
139
140if (! function_exists('DI\string')) {
141    /**
142     * Helper for concatenating strings.
143     *
144     * Example:
145     *
146     *     'log.filename' => DI\string('{app.path}/app.log')
147     *
148     * @param string $expression A string expression. Use the `{}` placeholders to reference other container entries.
149     *
150     * @since 5.0
151     */
152    function string(string $expression) : StringDefinition
153    {
154        return new StringDefinition($expression);
155    }
156}
157