@@ -39,19 +39,26 @@ abstract class AbstractValueExporter implements ValueExporterInterface
39
39
protected $ formatterInterface = FormatterInterface::class;
40
40
41
41
/**
42
- * An array of arrays of formatters by priority .
42
+ * An array of priorities by formatter class .
43
43
*
44
44
* @var array[]
45
45
*/
46
46
private $ formatters = array ();
47
47
48
48
/**
49
- * A sorted array of formatters.
49
+ * An array of formatters instances sorted by priority or null .
50
50
*
51
- * @var FormatterInterface[]
51
+ * @var FormatterInterface[]|null
52
52
*/
53
53
private $ sortedFormatters ;
54
54
55
+ /**
56
+ * An array of cached formatters instances by class.
57
+ *
58
+ * @var FormatterInterface[]
59
+ */
60
+ private $ cachedFormatters = array ();
61
+
55
62
/**
56
63
* Takes {@link FormatterInterface} as arguments.
57
64
*
@@ -72,23 +79,19 @@ final public function addFormatters(array $formatters)
72
79
foreach ($ formatters as $ formatter ) {
73
80
if (is_array ($ formatter )) {
74
81
$ priority = (int ) $ formatter [1 ];
75
- $ formatter = $ formatter [0 ];
82
+ $ formatterClass = $ formatter [0 ];
76
83
} else {
77
84
$ priority = 0 ;
85
+ $ formatterClass = $ formatter ;
78
86
}
79
87
80
- $ formatterClass = get_class ($ formatter );
81
-
82
- if (!$ formatter instanceof $ this ->formatterInterface ) {
88
+ if (!in_array ($ this ->formatterInterface , class_implements ($ formatterClass ), true )) {
83
89
throw new InvalidFormatterException ($ formatterClass , static ::class, $ this ->formatterInterface );
84
90
}
85
91
86
- if (in_array (ExpandedFormatterTrait::class, class_uses ($ formatterClass ), true )) {
87
- $ formatter ->setExporter ($ this );
88
- }
89
-
90
- // Using the class as key prevents duplicate
91
- $ this ->formatters [$ priority ][$ formatterClass ] = $ formatter ;
92
+ // Using the class as key prevents duplicate and allows to
93
+ // dynamically change the priority
94
+ $ this ->formatters [$ formatterClass ] = $ priority ;
92
95
}
93
96
}
94
97
@@ -98,8 +101,24 @@ final public function addFormatters(array $formatters)
98
101
final protected function formatters ()
99
102
{
100
103
if (null === $ this ->sortedFormatters ) {
101
- krsort ($ this ->formatters );
102
- $ this ->sortedFormatters = call_user_func_array ('array_merge ' , $ this ->formatters );
104
+ arsort ($ this ->formatters );
105
+
106
+ foreach (array_keys ($ this ->formatters ) as $ formatterClass ) {
107
+ if (isset ($ this ->cachedFormatters [$ formatterClass ])) {
108
+ $ this ->sortedFormatters [] = $ this ->cachedFormatters [$ formatterClass ];
109
+
110
+ continue ;
111
+ }
112
+
113
+ $ formatter = new $ formatterClass ();
114
+
115
+ if (in_array (ExpandedFormatterTrait::class, class_uses ($ formatterClass ), true )) {
116
+ /** @var ExpandedFormatterTrait $formatter */
117
+ $ formatter ->setExporter ($ this );
118
+ }
119
+
120
+ $ this ->sortedFormatters [] = $ this ->cachedFormatters [$ formatterClass ] = $ formatter ;
121
+ }
103
122
}
104
123
105
124
return $ this ->sortedFormatters ;
0 commit comments