aimeos /
ai-admin-jsonadm
| 1 | <?php |
||||
| 2 | |||||
| 3 | /** |
||||
| 4 | * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0 |
||||
| 5 | * @copyright Aimeos (aimeos.org), 2015-2025 |
||||
| 6 | * @package Admin |
||||
| 7 | * @subpackage JsonAdm |
||||
| 8 | */ |
||||
| 9 | |||||
| 10 | |||||
| 11 | namespace Aimeos\Admin; |
||||
| 12 | |||||
| 13 | |||||
| 14 | /** |
||||
| 15 | * Factory which can create all JSON API clients |
||||
| 16 | * |
||||
| 17 | * @package Admin |
||||
| 18 | * @subpackage JsonAdm |
||||
| 19 | */ |
||||
| 20 | class JsonAdm |
||||
| 21 | { |
||||
| 22 | /** admin/jsonadm/name |
||||
| 23 | * Class name of the used JSON API client implementation |
||||
| 24 | * |
||||
| 25 | * Each default JSON API client can be replace by an alternative imlementation. |
||||
| 26 | * To use this implementation, you have to set the last part of the class |
||||
| 27 | * name as configuration value so the client factory knows which class it |
||||
| 28 | * has to instantiate. |
||||
| 29 | * |
||||
| 30 | * For example, if the name of the default class is |
||||
| 31 | * |
||||
| 32 | * \Aimeos\Admin\JsonAdm\Standard |
||||
| 33 | * |
||||
| 34 | * and you want to replace it with your own version named |
||||
| 35 | * |
||||
| 36 | * \Aimeos\Admin\JsonAdm\Mycntl |
||||
| 37 | * |
||||
| 38 | * then you have to set the this configuration option: |
||||
| 39 | * |
||||
| 40 | * admin/jsonadm/name = Mycntl |
||||
| 41 | * |
||||
| 42 | * The value is the last part of your own class name and it's case sensitive, |
||||
| 43 | * so take care that the configuration value is exactly named like the last |
||||
| 44 | * part of the class name. |
||||
| 45 | * |
||||
| 46 | * The allowed characters of the class name are A-Z, a-z and 0-9. No other |
||||
| 47 | * characters are possible! You should always start the last part of the class |
||||
| 48 | * name with an upper case character and continue only with lower case characters |
||||
| 49 | * or numbers. Avoid chamel case names like "MyCntl"! |
||||
| 50 | * |
||||
| 51 | * @param string Last part of the class name |
||||
| 52 | * @since 2015.12 |
||||
| 53 | * @category Developer |
||||
| 54 | */ |
||||
| 55 | |||||
| 56 | /** admin/jsonadm/decorators/excludes |
||||
| 57 | * Excludes decorators added by the "common" option from the JSON API clients |
||||
| 58 | * |
||||
| 59 | * Decorators extend the functionality of a class by adding new aspects |
||||
| 60 | * (e.g. log what is currently done), executing the methods of the underlying |
||||
| 61 | * class only in certain conditions (e.g. only for logged in users) or |
||||
| 62 | * modify what is returned to the caller. |
||||
| 63 | * |
||||
| 64 | * This option allows you to remove a decorator added via |
||||
| 65 | * "admin/jsonadm/common/decorators/default" before they are wrapped |
||||
| 66 | * around the Jsonadm client. |
||||
| 67 | * |
||||
| 68 | * admin/jsonadm/decorators/excludes = array( 'decorator1' ) |
||||
| 69 | * |
||||
| 70 | * This would remove the decorator named "decorator1" from the list of |
||||
| 71 | * common decorators ("\Aimeos\Admin\JsonAdm\Common\Decorator\*") added via |
||||
| 72 | * "admin/jsonadm/common/decorators/default" for the JSON API client. |
||||
| 73 | * |
||||
| 74 | * @param array List of decorator names |
||||
| 75 | * @since 2016.01 |
||||
| 76 | * @category Developer |
||||
| 77 | * @see admin/jsonadm/common/decorators/default |
||||
| 78 | * @see admin/jsonadm/decorators/global |
||||
| 79 | * @see admin/jsonadm/decorators/local |
||||
| 80 | */ |
||||
| 81 | |||||
| 82 | /** admin/jsonadm/decorators/global |
||||
| 83 | * Adds a list of globally available decorators only to the Jsonadm client |
||||
| 84 | * |
||||
| 85 | * Decorators extend the functionality of a class by adding new aspects |
||||
| 86 | * (e.g. log what is currently done), executing the methods of the underlying |
||||
| 87 | * class only in certain conditions (e.g. only for logged in users) or |
||||
| 88 | * modify what is returned to the caller. |
||||
| 89 | * |
||||
| 90 | * This option allows you to wrap global decorators |
||||
| 91 | * ("\Aimeos\Admin\Jsonadm\Common\Decorator\*") around the Jsonadm |
||||
| 92 | * client. |
||||
| 93 | * |
||||
| 94 | * admin/jsonadm/product/decorators/global = array( 'decorator1' ) |
||||
| 95 | * |
||||
| 96 | * This would add the decorator named "decorator1" defined by |
||||
| 97 | * "\Aimeos\Admin\Jsonadm\Common\Decorator\Decorator1" only to the |
||||
| 98 | * "product" Jsonadm client. |
||||
| 99 | * |
||||
| 100 | * @param array List of decorator names |
||||
| 101 | * @since 2016.01 |
||||
| 102 | * @category Developer |
||||
| 103 | * @see admin/jsonadm/common/decorators/default |
||||
| 104 | * @see admin/jsonadm/decorators/excludes |
||||
| 105 | * @see admin/jsonadm/decorators/local |
||||
| 106 | */ |
||||
| 107 | |||||
| 108 | /** admin/jsonadm/decorators/local |
||||
| 109 | * Adds a list of local decorators only to the Jsonadm client |
||||
| 110 | * |
||||
| 111 | * Decorators extend the functionality of a class by adding new aspects |
||||
| 112 | * (e.g. log what is currently done), executing the methods of the underlying |
||||
| 113 | * class only in certain conditions (e.g. only for logged in users) or |
||||
| 114 | * modify what is returned to the caller. |
||||
| 115 | * |
||||
| 116 | * This option allows you to wrap local decorators |
||||
| 117 | * ("\Aimeos\Admin\Jsonadm\Product\Decorator\*") around the Jsonadm |
||||
| 118 | * client. |
||||
| 119 | * |
||||
| 120 | * admin/jsonadm/product/decorators/local = array( 'decorator2' ) |
||||
| 121 | * |
||||
| 122 | * This would add the decorator named "decorator2" defined by |
||||
| 123 | * "\Aimeos\Admin\Jsonadm\Product\Decorator\Decorator2" only to the |
||||
| 124 | * "product" Jsonadm client. |
||||
| 125 | * |
||||
| 126 | * @param array List of decorator names |
||||
| 127 | * @since 2016.01 |
||||
| 128 | * @category Developer |
||||
| 129 | * @see admin/jsonadm/common/decorators/default |
||||
| 130 | * @see admin/jsonadm/decorators/excludes |
||||
| 131 | * @see admin/jsonadm/decorators/global |
||||
| 132 | */ |
||||
| 133 | |||||
| 134 | |||||
| 135 | private static $objects = []; |
||||
| 136 | |||||
| 137 | |||||
| 138 | /** |
||||
| 139 | * Creates the required client specified by the given path of client names. |
||||
| 140 | * |
||||
| 141 | * Clients are created by providing only the domain name, e.g. "product" |
||||
| 142 | * for the \Aimeos\Admin\JsonAdm\Product\Standard or a path of names to |
||||
| 143 | * retrieve a specific sub-client, e.g. "product/type" for the |
||||
| 144 | * \Aimeos\Admin\JsonAdm\Product\Type\Standard client. |
||||
| 145 | * |
||||
| 146 | * @param \Aimeos\MShop\ContextIface $context Context object required by clients |
||||
| 147 | * @param \Aimeos\Bootstrap $aimeos Aimeos Bootstrap object |
||||
| 148 | * @param string $path Name of the client separated by slashes, e.g "product/property" |
||||
| 149 | * @param string|null $name Name of the client implementation ("Standard" if null) |
||||
| 150 | * @return \Aimeos\Admin\JsonAdm\Iface JSON admin instance |
||||
| 151 | * @throws \Aimeos\Admin\JsonAdm\Exception If the given path is invalid |
||||
| 152 | */ |
||||
| 153 | public static function create( \Aimeos\MShop\ContextIface $context, \Aimeos\Bootstrap $aimeos, |
||||
| 154 | string $path, ?string $name = null ) : \Aimeos\Admin\JsonAdm\Iface |
||||
| 155 | { |
||||
| 156 | if( preg_match( '/^[a-z0-9\/]*$/', $path ) !== 1 ) { |
||||
| 157 | throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Invalid component path "%1$s"', $path, 400 ) ); |
||||
| 158 | } |
||||
| 159 | |||||
| 160 | empty( $path = trim( $path, '/' ) ) ?: $path .= '/'; |
||||
| 161 | |||||
| 162 | $view = $context->view(); |
||||
| 163 | $config = $context->config(); |
||||
| 164 | |||||
| 165 | if( $view->access( $config->get( 'admin/jsonadm/resource/' . $path . 'groups', [] ) ) !== true ) { |
||||
| 166 | throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Not allowed to access JsonAdm "%1$s" client', $path ), 403 ); |
||||
|
0 ignored issues
–
show
|
|||||
| 167 | } |
||||
| 168 | |||||
| 169 | $cname = $name ?: $context->config()->get( 'admin/jsonadm/' . $path . 'name', 'Standard' ); |
||||
| 170 | |||||
| 171 | $classname = '\\Aimeos\\Admin\\JsonAdm\\' . str_replace( '/', '\\', ucwords( $path, '/' ) ) . $cname; |
||||
| 172 | $interface = '\\Aimeos\\Admin\\JsonAdm\\Iface'; |
||||
| 173 | |||||
| 174 | if( class_exists( $classname ) === false ) |
||||
| 175 | { |
||||
| 176 | $cname = $name ?: $context->config()->get( 'admin/jsonadm/name', 'Standard' ); |
||||
| 177 | $classname = '\\Aimeos\\Admin\\JsonAdm\\' . $cname; |
||||
| 178 | |||||
| 179 | if( class_exists( $classname ) === false ) { |
||||
| 180 | throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Class "%1$s" not found', $classname, 404 ) ); |
||||
| 181 | } |
||||
| 182 | } |
||||
| 183 | |||||
| 184 | $client = self::createComponent( $context, $classname, $interface, $path ); |
||||
| 185 | |||||
| 186 | return $client->setAimeos( $aimeos )->setView( $view ); |
||||
|
0 ignored issues
–
show
The method
setAimeos() does not exist on Aimeos\Admin\JsonAdm\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\Admin\JsonAdm\Common\Iface or Aimeos\Admin\JsonAdm\Common\Decorator\Iface. Are you sure you never get one of those?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 187 | } |
||||
| 188 | |||||
| 189 | |||||
| 190 | /** |
||||
| 191 | * Injects a client object |
||||
| 192 | * |
||||
| 193 | * The object is returned via create() if an instance of the class |
||||
| 194 | * with the name name is requested. |
||||
| 195 | * |
||||
| 196 | * @param string $classname Full name of the class for which the object should be returned |
||||
| 197 | * @param \Aimeos\Admin\JsonAdm\Iface|null $client JSON API client object |
||||
| 198 | */ |
||||
| 199 | public static function inject( string $classname, ?\Aimeos\Admin\JsonAdm\Iface $client = null ) |
||||
| 200 | { |
||||
| 201 | self::$objects['\\' . ltrim( $classname, '\\' )] = $client; |
||||
| 202 | } |
||||
| 203 | |||||
| 204 | |||||
| 205 | /** |
||||
| 206 | * Adds the decorators to the JSON API client object |
||||
| 207 | * |
||||
| 208 | * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects |
||||
| 209 | * @param \Aimeos\Admin\JsonAdm\Common\Iface $client Client object |
||||
| 210 | * @param string $path Name of the client separated by slashes, e.g "product/property" |
||||
| 211 | * @return \Aimeos\Admin\JsonAdm\Iface Client object |
||||
| 212 | */ |
||||
| 213 | protected static function addComponentDecorators( \Aimeos\MShop\ContextIface $context, |
||||
| 214 | \Aimeos\Admin\JsonAdm\Iface $client, string $path ) : \Aimeos\Admin\JsonAdm\Iface |
||||
| 215 | { |
||||
| 216 | $config = $context->config(); |
||||
| 217 | $localClass = str_replace( '/', '\\', ucwords( $path, '/' ) ); |
||||
| 218 | |||||
| 219 | $classprefix = '\\Aimeos\\Admin\\JsonAdm\\' . ucfirst( $localClass ) . 'Decorator\\'; |
||||
| 220 | $decorators = array_reverse( $config->get( 'admin/jsonadm/' . $path . 'decorators/local', [] ) ); |
||||
| 221 | $client = self::addDecorators( $context, $client, $path, $decorators, $classprefix ); |
||||
| 222 | |||||
| 223 | $classprefix = '\\Aimeos\\Admin\\JsonAdm\\Common\\Decorator\\'; |
||||
| 224 | $decorators = array_reverse( $config->get( 'admin/jsonadm/' . $path . 'decorators/global', [] ) ); |
||||
| 225 | $client = self::addDecorators( $context, $client, $path, $decorators, $classprefix ); |
||||
| 226 | |||||
| 227 | /** admin/jsonadm/common/decorators/default |
||||
| 228 | * Configures the list of decorators applied to all JSON API clients |
||||
| 229 | * |
||||
| 230 | * Decorators extend the functionality of a class by adding new aspects |
||||
| 231 | * (e.g. log what is currently done), executing the methods of the underlying |
||||
| 232 | * class only in certain conditions (e.g. only for logged in users) or |
||||
| 233 | * modify what is returned to the caller. |
||||
| 234 | * |
||||
| 235 | * This option allows you to configure a list of decorator names that should |
||||
| 236 | * be wrapped around the original instance of all created clients: |
||||
| 237 | * |
||||
| 238 | * admin/jsonadm/common/decorators/default = array( 'decorator1', 'decorator2' ) |
||||
| 239 | * |
||||
| 240 | * This would wrap the decorators named "decorator1" and "decorator2" around |
||||
| 241 | * all client instances in that order. The decorator classes would be |
||||
| 242 | * "\Aimeos\Admin\JsonAdm\Common\Decorator\Decorator1" and |
||||
| 243 | * "\Aimeos\Admin\JsonAdm\Common\Decorator\Decorator2". |
||||
| 244 | * |
||||
| 245 | * @param array List of decorator names |
||||
| 246 | * @since 2015.12 |
||||
| 247 | * @category Developer |
||||
| 248 | */ |
||||
| 249 | $decorators = array_reverse( $config->get( 'admin/jsonadm/common/decorators/default', [] ) ); |
||||
| 250 | $excludes = $config->get( 'admin/jsonadm/' . $path . 'decorators/excludes', [] ); |
||||
| 251 | |||||
| 252 | foreach( $decorators as $key => $name ) |
||||
| 253 | { |
||||
| 254 | if( in_array( $name, $excludes ) ) { |
||||
| 255 | unset( $decorators[$key] ); |
||||
| 256 | } |
||||
| 257 | } |
||||
| 258 | |||||
| 259 | $classprefix = '\\Aimeos\\Admin\\JsonAdm\\Common\\Decorator\\'; |
||||
| 260 | $client = self::addDecorators( $context, $client, $path, $decorators, $classprefix ); |
||||
| 261 | |||||
| 262 | return $client; |
||||
| 263 | } |
||||
| 264 | |||||
| 265 | |||||
| 266 | /** |
||||
| 267 | * Adds the decorators to the client object |
||||
| 268 | * |
||||
| 269 | * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects |
||||
| 270 | * @param \Aimeos\Admin\JsonAdm\Iface $client Client object |
||||
| 271 | * @param array $decorators List of decorator names |
||||
| 272 | * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Admin\JsonAdm\Product\Decorator\" |
||||
| 273 | * @param string $path Name of the client separated by slashes, e.g "product/stock" |
||||
| 274 | * @return \Aimeos\Admin\JsonAdm\Iface Client object |
||||
| 275 | * @throws \LogicException If class can't be instantiated |
||||
| 276 | */ |
||||
| 277 | protected static function addDecorators( \Aimeos\MShop\ContextIface $context, \Aimeos\Admin\JsonAdm\Iface $client, |
||||
| 278 | string $path, array $decorators, string $classprefix ) : \Aimeos\Admin\JsonAdm\Iface |
||||
| 279 | { |
||||
| 280 | $interface = \Aimeos\Admin\JsonAdm\Common\Decorator\Iface::class; |
||||
| 281 | |||||
| 282 | foreach( $decorators as $name ) |
||||
| 283 | { |
||||
| 284 | if( ctype_alnum( $name ) === false ) { |
||||
| 285 | throw new \LogicException( sprintf( 'Invalid class name "%1$s"', $name ), 400 ); |
||||
| 286 | } |
||||
| 287 | |||||
| 288 | $client = \Aimeos\Utils::create( $classprefix . $name, [$client, $context, $path], $interface ); |
||||
| 289 | } |
||||
| 290 | |||||
| 291 | return $client; |
||||
| 292 | } |
||||
| 293 | |||||
| 294 | |||||
| 295 | /** |
||||
| 296 | * Creates a new client object |
||||
| 297 | * |
||||
| 298 | * @param \Aimeos\MShop\ContextIface $context Context object |
||||
| 299 | * @param string $classname Name of the client class |
||||
| 300 | * @param string $interface Name of the client interface |
||||
| 301 | * @param string $path Name of the client separated by slashes, e.g "product/property" |
||||
| 302 | * @return \Aimeos\Admin\JsonAdm\Iface Client object |
||||
| 303 | */ |
||||
| 304 | protected static function createComponent( \Aimeos\MShop\ContextIface $context, |
||||
| 305 | string $classname, string $interface, string $path ) : \Aimeos\Admin\JsonAdm\Iface |
||||
| 306 | { |
||||
| 307 | if( isset( self::$objects[$classname] ) ) { |
||||
| 308 | return self::$objects[$classname]; |
||||
| 309 | } |
||||
| 310 | |||||
| 311 | $client = \Aimeos\Utils::create( $classname, [$context, trim( $path, '/' )], $interface ); |
||||
| 312 | |||||
| 313 | return self::addComponentDecorators( $context, $client, $path ); |
||||
| 314 | } |
||||
| 315 | } |
||||
| 316 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths