• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aimeos / aimeos-core / 4f8b7e8d-5595-43b2-ba5c-df9921830178

17 May 2026 07:32AM UTC coverage: 92.581%. Remained the same
4f8b7e8d-5595-43b2-ba5c-df9921830178

push

circleci

aimeos
Fixed PHPStan issues

896 of 980 new or added lines in 165 files covered. (91.43%)

35 existing lines in 29 files now uncovered.

9734 of 10514 relevant lines covered (92.58%)

80.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/src/MShop/Plugin/Manager/Base.php
1
<?php
2

3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2026
7
 * @package MShop
8
 * @subpackage Plugin
9
 */
10

11

12
namespace Aimeos\MShop\Plugin\Manager;
13

14

15
/**
16
 * Abstract class for plugin managers.
17
 *
18
 * @package MShop
19
 * @subpackage Service
20
 */
21
abstract class Base
22
        extends \Aimeos\MShop\Common\Manager\Base
23
{
24
        private array $plugins = [];
25

26
        /**
27
         * Returns the plugin provider which is responsible for the plugin item.
28
         *
29
         * @param \Aimeos\MShop\Plugin\Item\Iface $item Plugin item object
30
         * @param string $type Plugin type code
31
         * @return \Aimeos\MShop\Plugin\Provider\Iface Returns the decoratad plugin provider object
32
         * @throws \LogicException If provider couldn't be found
33
         */
34
        public function getProvider( \Aimeos\MShop\Plugin\Item\Iface $item, string $type ) : \Aimeos\MShop\Plugin\Provider\Iface
35
        {
36
                $type = ucwords( $type );
466✔
37
                $context = $this->context();
466✔
38
                $names = explode( ',', $item->getProvider() );
466✔
39

40
                if( ctype_alnum( $type ) === false ) {
466✔
41
                        throw new \LogicException( sprintf( 'Invalid characters in type name "%1$s"', $type ), 400 );
×
42
                }
43

44
                if( ( $provider = array_shift( $names ) ) === null ) {
466✔
45
                        throw new \LogicException( sprintf( 'Provider in "%1$s" not available', $item->getProvider() ), 400 );
×
46
                }
47

48
                if( ctype_alnum( $provider ) === false ) {
466✔
49
                        throw new \LogicException( sprintf( 'Invalid characters in provider name "%1$s"', $provider ), 400 );
×
50
                }
51

52
                $classname = '\Aimeos\MShop\Plugin\Provider\\' . $type . '\\' . $provider;
466✔
53
                $interface = \Aimeos\MShop\Plugin\Provider\Factory\Iface::class;
466✔
54

55
                // @phpstan-ignore argument.type
56
                $provider = \Aimeos\Utils::create( $classname, [$context, $item], $interface );
466✔
57

58
                /** mshop/plugin/provider/order/decorators
59
                 * Adds a list of decorators to all order plugin provider objects automatcally
60
                 *
61
                 * Decorators extend the functionality of a class by adding new aspects
62
                 * (e.g. log what is currently done), executing the methods of the underlying
63
                 * class only in certain conditions (e.g. only for logged in users) or
64
                 * modify what is returned to the caller.
65
                 *
66
                 * This option allows you to wrap decorators
67
                 * ("\Aimeos\MShop\Plugin\Provider\Decorator\*") around the order provider.
68
                 *
69
                 *  mshop/plugin/provider/order/decorators = array( 'decorator1' )
70
                 *
71
                 * This would add the decorator named "decorator1" defined by
72
                 * "\Aimeos\MShop\Plugin\Provider\Decorator\Decorator1" to all order provider
73
                 * objects.
74
                 *
75
                 * @type array List of decorator names
76
                 * @since 2014.03
77
                 * @see mshop/plugin/provider/order/decorators
78
                 */
79
                $decorators = $context->config()->get( 'mshop/plugin/provider/' . $item->getType() . '/decorators', [] );
466✔
80

81
                // @phpstan-ignore argument.type
82
                $provider = $this->addPluginDecorators( $item, $provider, $names );
466✔
83
                // @phpstan-ignore argument.type
84
                $provider = $this->addPluginDecorators( $item, $provider, (array) $decorators );
466✔
85

86
                return $provider->setObject( $provider );
466✔
87
        }
88

89

90
        /**
91
         * Registers plugins to the given publisher.
92
         *
93
         * @param \Aimeos\MShop\Order\Item\Iface $publisher Publisher object
94
         * @param string $type Unique plugin type code
95
         * @return static Manager object for chaining method calls
96
         */
97
        public function register( \Aimeos\MShop\Order\Item\Iface $publisher, string $type ) : static
98
        {
99
                if( !isset( $this->plugins[$type] ) )
466✔
100
                {
101
                        $search = $this->object()->filter( true );
466✔
102

103
                        $expr = array(
466✔
104
                                $search->compare( '==', 'plugin.type', $type ),
466✔
105
                                $search->getConditions(),
466✔
106
                        );
466✔
107

108
                        // @phpstan-ignore argument.type
109
                        $search->setConditions( $search->and( $expr ) );
466✔
110
                        // @phpstan-ignore argument.type
111
                        $search->setSortations( array( $search->sort( '+', 'plugin.position' ) ) );
466✔
112

113
                        $this->plugins[$type] = [];
466✔
114

115
                        foreach( $this->object()->search( $search ) as $item ) {
466✔
116
                                // @phpstan-ignore argument.type
117
                                $this->plugins[$type][$item->getId()] = $this->getProvider( $item, $type );
466✔
118
                        }
119
                }
120

121
                foreach( $this->plugins[$type] as $plugin ) {
466✔
122
                        $plugin->register( $publisher );
466✔
123
                }
124

125
                return $this;
466✔
126
        }
127

128

129
        /**
130
         *
131
         * @param \Aimeos\MShop\Plugin\Item\Iface $pluginItem Plugin item object
132
         * @param \Aimeos\MShop\Plugin\Provider\Iface $provider Plugin provider object
133
         * @param array $names List of decorator names that should be wrapped around the plugin provider object
134
         * @return \Aimeos\MShop\Plugin\Provider\Iface Plugin provider object
135
         */
136
        protected function addPluginDecorators( \Aimeos\MShop\Plugin\Item\Iface $pluginItem,
137
                \Aimeos\MShop\Plugin\Provider\Iface $provider, array $names ) : \Aimeos\MShop\Plugin\Provider\Iface
138
        {
139
                $context = $this->context();
466✔
140
                $classprefix = '\Aimeos\MShop\Plugin\Provider\Decorator\\';
466✔
141

142
                foreach( $names as $name )
466✔
143
                {
144
                        if( ctype_alnum( (string) $name ) === false )
466✔
145
                        {
146
                                $msg = $context->translate( 'mshop', 'Invalid characters in class name "%1$s"' );
×
NEW
147
                                throw new \Aimeos\MShop\Plugin\Exception( sprintf( $msg, (string) $name ) );
×
148
                        }
149

150
                        $classname = $classprefix . $name;
466✔
151
                        $interface = \Aimeos\MShop\Plugin\Provider\Decorator\Iface::class;
466✔
152

153
                        $provider = \Aimeos\Utils::create( $classname, [$context, $pluginItem, $provider], $interface );
466✔
154
                }
155

156
                // @phpstan-ignore return.type
157
                return $provider;
466✔
158
        }
159
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc