@@ -23,15 +23,20 @@ abstract class AbstractResolver implements ResolverInterface
2323 */
2424 private $ solutionOptions = [];
2525
26- public function addSolution ($ name , $ solution , $ options = [])
26+ /**
27+ * @var array
28+ */
29+ private $ fullyLoadedSolutions = [];
30+
31+ public function addSolution ($ name , callable $ solutionFunc , array $ solutionFuncArgs = [], array $ options = [])
2732 {
28- if (!$ this ->supportsSolution ($ solution )) {
29- throw new UnsupportedResolverException (
30- sprintf ('Resolver "%s" must be "%s" "%s" given. ' , $ name , $ this ->supportedSolutionClass (), get_class ($ solution ))
31- );
32- }
33+ $ this ->fullyLoadedSolutions [$ name ] = false ;
34+ $ this ->solutions [$ name ] = function () use ($ name , $ solutionFunc , $ solutionFuncArgs ) {
35+ $ solution = call_user_func_array ($ solutionFunc , $ solutionFuncArgs );
36+ $ this ->checkSolution ($ name , $ solution );
3337
34- $ this ->solutions [$ name ] = $ solution ;
38+ return $ solution ;
39+ };
3540 $ this ->solutionOptions [$ name ] = $ options ;
3641
3742 return $ this ;
@@ -44,15 +49,15 @@ public function addSolution($name, $solution, $options = [])
4449 */
4550 public function getSolution ($ name )
4651 {
47- return isset ($ this ->solutions [$ name ]) ? $ this ->solutions [ $ name] : null ;
52+ return isset ($ this ->solutions [$ name ]) ? $ this ->loadSolution ( $ name) : null ;
4853 }
4954
5055 /**
5156 * @return array
5257 */
5358 public function getSolutions ()
5459 {
55- return $ this ->solutions ;
60+ return $ this ->loadSolutions () ;
5661 }
5762
5863 /**
@@ -65,6 +70,44 @@ public function getSolutionOptions($name)
6570 return isset ($ this ->solutionOptions [$ name ]) ? $ this ->solutionOptions [$ name ] : [];
6671 }
6772
73+ /**
74+ * @param string $name
75+ *
76+ * @return mixed
77+ */
78+ private function loadSolution ($ name )
79+ {
80+ if ($ this ->fullyLoadedSolutions [$ name ]) {
81+ return $ this ->solutions [$ name ];
82+ } else {
83+ $ loader = $ this ->solutions [$ name ];
84+ $ this ->solutions [$ name ] = $ loader ();
85+ $ this ->fullyLoadedSolutions [$ name ] = true ;
86+ $ this ->postLoadSolution ($ this ->solutions [$ name ]);
87+
88+ return $ this ->solutions [$ name ];
89+ }
90+ }
91+
92+ /**
93+ * @return mixed[]
94+ */
95+ private function loadSolutions ()
96+ {
97+ foreach ($ this ->solutions as $ name => &$ solution ) {
98+ $ solution = $ this ->loadSolution ($ name );
99+ }
100+
101+ return $ this ->solutions ;
102+ }
103+
104+ /**
105+ * @param mixed $solution
106+ */
107+ protected function postLoadSolution ($ solution )
108+ {
109+ }
110+
68111 /**
69112 * @param mixed $solution
70113 *
@@ -77,6 +120,15 @@ protected function supportsSolution($solution)
77120 return null === $ supportedClass || $ solution instanceof $ supportedClass ;
78121 }
79122
123+ protected function checkSolution ($ name , $ solution )
124+ {
125+ if (!$ this ->supportsSolution ($ solution )) {
126+ throw new UnsupportedResolverException (
127+ sprintf ('Resolver "%s" must be "%s" "%s" given. ' , $ name , $ this ->supportedSolutionClass (), get_class ($ solution ))
128+ );
129+ }
130+ }
131+
80132 /**
81133 * default return null to accept mixed type.
82134 *
0 commit comments