goaop / goaop-symfony-bundle Goto Github PK
View Code? Open in Web Editor NEW[Outdated!] Integration bridge for Go! AOP framework and Symfony
[Outdated!] Integration bridge for Go! AOP framework and Symfony
I'm using Symfony 4, but I would like to use in a stable version to avoid problems for composer and dependencies!
There is a plan to tag this version?
phpunit vendor/goaop/goaop-symfony-bundle/Tests/GoAopBundleTest.php
PHPUnit 6.5.13 by Sebastian Bergmann and contributors.
.E.. 4 / 4 (100%)
Time: 1.22 seconds, Memory: 24.00MB
There was 1 error:
1) Go\Symfony\GoAopBundle\Tests\GoAopBundleTest::itRegistersAspectCollectorPassPass
Undefined property: PHPUnit\Framework\MockObject\Invocation\ObjectInvocation::$parameters
/var/www/app/current/vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php:112
/var/www/app/current/vendor/goaop/goaop-symfony-bundle/Tests/GoAopBundleTest.php:69
ERRORS!
Tests: 4, Assertions: 8, Errors: 1.
composer info | grep aop
goaop/framework 2.3.0 Framework for aspect-oriented programming in PHP.
goaop/goaop-symfony-bundle 2.1.2 Integration bridge for Go! AOP framework
goaop/parser-reflection 2.0.0 Provides reflection information, based on raw source
composer info | grep symfony
goaop/goaop-symfony-bundle 2.1.2 Integration bridge for Go! AOP framework
symfony/monolog-bundle v3.3.1 Symfony MonologBundle
symfony/phpunit-bridge v4.2.3 Symfony PHPUnit Bridge
symfony/polyfill-apcu v1.10.0 Symfony polyfill backporting apcu_* functions to lower ...
symfony/polyfill-ctype v1.10.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-icu v1.10.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.10.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php56 v1.10.0 Symfony polyfill backporting some PHP 5.6+ features to ...
symfony/polyfill-php70 v1.10.0 Symfony polyfill backporting some PHP 7.0+ features to ...
symfony/polyfill-util v1.10.0 Symfony utilities for portability of PHP codes
symfony/swiftmailer-bundle v2.6.7 Symfony SwiftmailerBundle
symfony/symfony v3.4.22 The Symfony PHP framework
php -v
PHP 7.2.14 (cli) (built: Jan 8 2019 14:05:15) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.14, Copyright (c) 1999-2018, by Zend Technologies
with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans
I conducted an experiment with a clean project and nothing works.
curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
chmod a+x /usr/local/bin/symfony
symfony new aop 3.4
cd aop
composer require goaop/goaop-symfony-bundle
sed -i '/$bundles = \[/ a \ \ new Go\\Symfony\\GoAopBundle\\GoAopBundle(),' app/AppKernel.php
cat >> app/config/config.yml << 'END'
go_aop:
# This setting enables or disables an automatic AOP cache warming in the application.
# By default, cache_warmer is enabled (true), disable it only if you have serious issues with
# cache warming process.
cache_warmer: true
# This setting enables or disables workaround for weaving of Doctrine ORM entities. By default,
# it is disabled. If you are using Doctrine ORM and you are using AOP to weave Doctrine entities,
# enable this feature. For details about this known issue, see https://github.com/goaop/framework/issues/327
doctrine_support: false
# Additional settings for the Go! AOP kernel initialization
options:
# Debug mode for the AOP, enable it for debugging and switch off for production mode to have a
# better runtime performance for your application
debug: %kernel.debug%
# Application root directory, AOP will be applied ONLY to the files in this directory, by default it's
# src/ directory of your application.
app_dir: "%kernel.root_dir%/../src"
# AOP cache directory where all transformed files will be stored.
cache_dir: %kernel.cache_dir%/aspect
# Whitelist is array of directories where AOP should be enabled, leave it empty to process all files
include_paths: []
# Exclude list is array of directories where AOP should NOT be enabled, leave it empty to process all files
exclude_paths: []
# AOP container class name can be used for extending AOP engine or services adjustment
container_class: ~
# List of enabled features for AOP kernel, this allows to enable function interception, support for
# read-only file systems, etc. Each item should be a name of constant from the `Go\Aop\Features` class.
features: []
END
cat >> src/AppBundle/LoggingAspect.php << 'END'
<?php
namespace AppBundle;
use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Before;
use Psr\Log\LoggerInterface;
/**
* Application logging aspect
*/
class LoggingAspect implements Aspect
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Writes a log info before method execution
*
* @param MethodInvocation $invocation
* @Before("execution(public **->*(*))")
*/
public function beforeMethod(MethodInvocation $invocation)
{
$this->logger->info($invocation, $invocation->getArguments());
}
}
END
cat >> app/config/services.yml << 'END'
logging.aspect:
class: AppBundle\LoggingAspect
arguments: ["@logger"]
tags:
- { name: goaop.aspect }
END
composer dumpautoload
After request to app:
Fatal error: Uncaught Error: Class name must be a valid object or a string in /var/www/app/aop/vendor/goaop/framework/src/Core/AspectKernel.php on line 108
Make crutch bugfix:
sed -i 's/container_class: ~/container_class: Go\\Core\\GoAspectContainer/' app/config/config.yml
php bin/console cache:clear --env=prod
Opps:
PHP Fatal error: Uncaught Error: Class name must be a valid object or a string in /var/www/app/aop/vendor/goaop/framework/src/Core/AspectKernel.php:108
Hard lifehack:
rm -rf var/cache/prod/
New oops:
Fatal error: Cannot declare class AppBundle\Controller\DefaultController, because the name is already in use in /var/www/app/aop/src/AppBundle/Controller/DefaultController.php on line 0
php bin/console cache:warmup:aop --env=prod
Total 3 files to process.
[OK]: /var/www/app/aop/src/AppBundle/AppBundle.php
[OK]: /var/www/app/aop/src/AppBundle/Controller/DefaultController.php
[OK]: /var/www/app/aop/src/AppBundle/LoggingAspect.php
[DONE]: Total processed 3, 0 errors.
Any ideas? Any tips? Start guide?
Hi!
I'm having some problems with the syntax if I use a very simple regex:
@Before("execution(public **->addDeal(*))")
It works, but I would like to narrow it down a little bit more, so addDeal is a method of the class
AbstractDealGroupingModel but if i write this down
@Before("execution(public AbstractDealGroupingModel->addDeal(*))")
it never get executed. Is there something wrong with the syntax that I'm using?
I make https://github.com/goaop/goaop-symfony-bundle#installation
And copy config from https://github.com/goaop/goaop-symfony-bundle#configuration
After any request:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Class name must be a valid object or a string in /var/www/app/current/vendor/goaop/framework/src/Core/AspectKernel.php:108
Stack trace:
#0 /var/www/app/current/vendor/goaop/goaop-symfony-bundle/Kernel/AspectSymfonyKernel.php(45): Go\Core\AspectKernel->init(Array)
#1 /var/www/app/current/var/cache/dev/ContainerD5ym4a7/getGoaop_Aspect_KernelService.php(13): Go\Symfony\GoAopBundle\Kernel\AspectSymfonyKernel->init(Array)
#2 /var/www/app/current/var/cache/dev/ContainerD5ym4a7/appDevDebugProjectContainer.php(987): require('/var/www/app/cu...')
#3 /var/www/app/current/var/cache/dev/ContainerD5ym4a7/getGoaop_Aspect_ContainerService.php(12): ContainerD5ym4a7\appDevDebugProjectContainer->load('getGoaop_Aspect...')
#4 /var/www/app/current/var/cache/dev/ContainerD5ym4a7/appDevDebugProjectContainer.php(987): require('/var/www/app/cu...')
#5 /var/www/app/current/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(304): ContainerD5ym4 in /var/www/app/current/vendor/goaop/framework/src/Core/AspectKernel.php on line 108
composer info | grep aop
goaop/framework 2.3.0 Framework for aspect-oriented programming in PHP.
goaop/goaop-symfony-bundle 2.1.2 Integration bridge for Go! AOP framework
goaop/parser-reflection 2.0.0 Provides reflection information, based on raw source
composer info | grep symfony
goaop/goaop-symfony-bundle 2.1.2 Integration bridge for Go! AOP framework
symfony/monolog-bundle v3.3.1 Symfony MonologBundle
symfony/phpunit-bridge v4.2.3 Symfony PHPUnit Bridge
symfony/polyfill-apcu v1.10.0 Symfony polyfill backporting apcu_* functions to lower ...
symfony/polyfill-ctype v1.10.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-icu v1.10.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.10.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php56 v1.10.0 Symfony polyfill backporting some PHP 5.6+ features to ...
symfony/polyfill-php70 v1.10.0 Symfony polyfill backporting some PHP 7.0+ features to ...
symfony/polyfill-util v1.10.0 Symfony utilities for portability of PHP codes
symfony/swiftmailer-bundle v2.6.7 Symfony SwiftmailerBundle
symfony/symfony v3.4.22 The Symfony PHP framework
php -v
PHP 7.2.14 (cli) (built: Jan 8 2019 14:05:15) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.14, Copyright (c) 1999-2018, by Zend Technologies
with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans
When I added this bundle into my project, everything works fine in dev environment, but when I try to run in production I hit this ServiceNotFoundException
. When I try to clear the cache, it also throws the same exception.
I try to dig around the problem and found that the exception was trigger by GoAopBundle:50.
This is because Symfony tries to boot existing bundles found in the configuration before clearing it caches. But when it tries to boot GoAopBundle it couldn't find goaop.aspect.containter
service because it wasn't there in previous cache.
My work around is to clear the cache manually, by removing it folder. Then executes cache:warmup
using Symfony console.
When using GoAop with https://github.com/symfony2admingenerator/GeneratorBundle exception gets thrown by GoAop complaining that it is impossible to find parent classes of autogenerated classes.
This is normal and expected. Can be managed with directories exclusion, or, we can handle that on same way as we handle classes that inherits other classes from, per example, PHARs.
Either way - known issue, ought to be documented.
Thank you for the great bundle. Currently, the usage of "roave/security-advisories" prevents us from using the bundle as the minimum-stability
needs to be set to "dev".
Can you please move the dependency to require-dev
so that we don't need to tinker our minimum-stability
? Thank you very much! :)
Hello! I have problems with editing source files. Aspects stop working after any change in the source file that works under the aspect. After running the cache:clear command, all aspects continue to work until a new change is made to the source file.
I'm using symfony 4.0.5 with autowiring.
The aspects that I use:
/**
* @Before("execution(public **\Application\**\*Service->*(*)) && !execution(public **\Application\**\*Service->__construct(*))")
*/
public function beginTransaction()
{
$this->entityManager->getConnection()->beginTransaction();
$this->entityManager->getConnection()->setAutoCommit(false);
}
/**
* @After("execution(public **\Application\**\*Service->*(*)) && !execution(public **\Application\**\*Service->__construct(*))")
*/
public function commitTransaction()
{
$this->entityManager->flush();
$this->entityManager->getConnection()->commit();
}
/**
* @AfterThrowing("execution(public **\Application\**\*Service->*(*)) && !execution(public **\Application\**\*Service->__construct(*))")
*/
public function rollbackTransaction()
{
if ($this->entityManager->getConnection()->isTransactionActive()) {
$this->entityManager->rollback();
}
}
In a 3.4.8 symfony project we are facing an issue related to the debug directive in config.file.
In a first try we've setted debug property to %kernel.debug% and in dev after doing cache:warmup the first time and changhing something in one of the classes implementing "\Go\Aop\Aspect" this change causes an error in "\Symfony\Component\Debug\DebugClassLoader:146" when doing another cache:clear/warmup.
The error from the DebugClassLoader complains about a costructor of a class in our app, but totally inconsistent (it says that the constructor is not compatible with the interface is implementing, but it's right).
After a lot of debugging we've tried to set the debug parameter to false and now all works correctly.
Need to have a documentation for bundle with config description and several examples of realization of logging, etc.
If you install the app with composer and optimize autoloader, the interceptors are not loaded (it loads the normal class).
Hi there!
I'm encountering a weird issue where the aop doenst work if the application is started in non-debug mode:
doesnt work: $kernel = new AppKernel('prod', false)
it works: $kernel = new AppKernel('prod', true);
Any ideas or tips on what is going on in here?
Should I check something specifically in my configs or is this a bug?
And there are no errors, the proxy classes are all created ok, everything seems to be in place, it's just that the AOP doesnt trigger.
Symfony version: 2.8.16
PHP version: 5.6.27
I have spent 2 days trying to figure out an issue of Go Aop not being able to weave around some classes in project. It happened that I had a circular reference issue that involved aspects, so that broke everything, and issue was not so obvious as it is with, per example, Symfony service container.
We had a external service providers (4 of them) with OAuth protected external api. In order to handle them, for each, a Provider class is created, and each Provider is injected into Manager.
Each provider could expire a token. So, we have RefreshTokenAspect, which will, in general, try to re-issue a token on some method call if that method fails (per example, Provider->fetchData()).
This weaving was possible.
However, there was a third Entity, which has method getData(). For that method, aspect is used on which Manager is injected to lazy-load data from some of the Providers.
And that failed Aspect Container without any obvious error.
As I have figure out, first, a Symfony service container is created. Then AOP kernel, then aspects, and then other services. However, if aspect requires some service, then that service will be initialized prior to aspect. And if that service is weaved, or its some sub-dependency, then you get a circular reference.
This complex situation can be simply explained as a rule: "There can not be an aspect defined which uses service that is weaved, or depends on any other service that is weaved".
It would be very convenient to build some kind of introspection that would detect this situation and warn about circular reference.
Possible workarounds:
Hi,
I have a problem in production, it check for write permission on "cache/aspect" folder. And it doesn't have the right... it fails (event if the cache:warmup was already done).
This shouldn't happen as the entire "cache" should be written by "cache:warmup".
Steps to reproduce:
I will try to explain this unusual issue that occurs when scanning advices. Unfortunately, this project is not setup according to good practice, so I guess that is why this issue appeared.
It is a Symfony (v.3.3) project, consist of several bundles in src directory, something like this:
So, in general, you can see that there are 3 bundles in Project directory that are not in accordance with standard recommended SF bundle/directory structure.
Here is what happens:
Weaving occurs when cache is cleared, and warmed up via console, or, cache is cleared and then page is loaded.
So, I started to investigate this, and stumbled upon commands that are in AOP/framework. Managed to make them work in Symfony project (btw I have opened some issue about that goaop/framework#330).
And strange thing happened: all debug commands showed correct matching.
So I have executed bin/console cache:warmup:aop web/app_dev.php
and every class regardless of it source was weaved flawlessly!
When I refreshed page, it all worked correctly.
I have no idea what is going on and why that happens, but I am hoping that you @lisachenko would have some kind of idea how to deal with this.
Do ask if you need any additional info.
First of all, awesome bundle, thanks a lot! "Go! AOP PHP" itself is working great, but we got some problems with cache clear and warmup in symfony.
app/console cache:clear --no-warmup
works fine.
But, when running app/console cache:clear
(with implicit warmup), i get:
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Constant AOP_ROOT_DIR already defined
When wrapping those with !defined('AOP_ROOT_DIR')
, SourceTransformingLoader::register()
fails with:
[RuntimeException]
Stream filter already registered
As a quick'n'dirty hack, i wrapped the full AspectKernel->init()
method with a check, if the constant is already defined. Which works for now.
But the most important bug currently is in the warmup command. I get these errors (simplified some pathes):
[Symfony\Component\Config\Exception\FileLoaderLoadException]
File "/myproject/src/.../Doctrine/Orm/IdTrait.php" was not processed yet in my_project.authentication.controller
(which is being imported from "/myproject/src/.../Resources/config/routing.yml").
[TokenReflection\Exception\BrokerException] File "/myproject/src/.../Doctrine/Orm/IdTrait.php" was not processed yet.
On each warmup, more and more files end up in the cache, and it (currently) works on the 3rd try.
# ./app/config/config.yml
...
go_aop:
options:
cache_dir: %kernel.cache_dir%/../%kernel.environment%-goaop
container_class: Go\Core\GoAspectContainer
# ./composer.json
...
"require": {
"php": ">=5.5",
"symfony/symfony": "2.7.1",
"doctrine/orm": "~2.5,>=2.5.0",
"doctrine/doctrine-bundle": "~1.5",
...
"goaop/framework": "dev-master",
"goaop/goaop-symfony-bundle": "dev-master",
"knplabs/doctrine-behaviors": "~1.1"
}
Need to give an ability to install goaop/framework
version 2.x too.
Am running symfony 4.0.5, and trying to get go-aop working.
Although I see that my test aspect and advisor are loaded, tried several ways to fire up through @before, @around, the advise never fires up...
$ composer create-project symfony/skeleton:^4.0 sf4
$ cd sf4
$ composer require roave/security-advisories
$ composer require goaop/goaop-symfony-bundle
# moved GoAppBundle to the top in config/bundles.php
$ composer require logger
FILE CONTENTS src/Command/ShineCommand.php:
<?php
namespace App\Command;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ShineCommand extends Command
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
parent::__construct(); // you *must* call the parent constructor
}
protected function configure()
{
$this->setName('app:shine');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->logger->info( $string = 'Waking up the sun' );
// ...
}
}
FILE CONTENTS Aspect/LoggingAspect.php:
<?php
namespace App\Aspect;
use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Before;
use Psr\Log\LoggerInterface;
/**
* Application logging aspect
*/
class LoggingAspect implements Aspect
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(LoggerInterface $logger)
{
print "ASPECT INIT\n";
$this->logger = $logger;
}
/**
* Writes a log info before method execution
*
* @param MethodInvocation $invocation
* @Before("execution(public **->*(*))")
*/
public function beforeMethod(MethodInvocation $invocation)
{
print "ASPECT FIRED in ".get_class($this)."\n";
$this->logger->info($invocation, $invocation->getArguments());
}
}
FILE CONTENTS (Appended) config/services.yaml:
parameters:
container.dumper.inline_class_loader: false
services:
logging.aspect:
class: App\Aspect\LoggingAspect
public: true
arguments: ["@logger"]
tags:
- { name: goaop.aspect }
go_aop:
options:
debug: true
app_dir: "%kernel.root_dir%/../src"
cache_dir: "%kernel.cache_dir%/aspect"
features: # framework/src/Aop/Features.php
- INTERCEPT_FUNCTIONS
- INTERCEPT_INITIALIZATIONS
- INTERCEPT_INCLUDES
$ console debug:container goaop
Select one of the following services to display its information:
[0 ] goaop.aspect.kernel
[1 ] goaop.aspect.container
[2 ] goaop.cache.path.manager
[3 ] goaop.cache.warmer
[4 ] goaop.bridge.doctrine.metadata_load_interceptor
[5 ] goaop.command.warmup
[6 ] goaop.command.debug_advisor
[7 ] goaop.command.debug_aspect
[8 ] console.command.public_alias.goaop.command.warmup
[9 ] console.command.public_alias.goaop.command.debug_advisor
[10] console.command.public_alias.goaop.command.debug_aspect
$ bin/console debug:aspect
Aspect debug information
========================
Go\Symfony\GoAopBundle\Kernel\AspectSymfonyKernel has following enabled aspects:
App\Aspect\LoggingAspect
------------------------
Defined in: /home/holzmann/shared/pkg/sf4/src/Aspect/LoggingAspect.php
Application logging aspect
Pointcuts and advices
--------- ----------------------------------------
Type Identifier
--------- ----------------------------------------
Advisor App\Aspect\LoggingAspect->beforeMethod
--------- ----------------------------------------
$ bin/console debug:advisor
Advisor debug information
=========================
List of registered advisors in the container
---------------------------------------- ----------------------------
Id Expression
---------------------------------------- ----------------------------
App\Aspect\LoggingAspect->beforeMethod execution(public **->*(*))
---------------------------------------- ----------------------------
$ console debug:container goaop.aspect.container
Information for Service "goaop.aspect.container"
Option Value
Service ID goaop.aspect.container
Class Go\Core\GoAspectContainer
Tags -
Calls registerAspect, registerAspect
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
Factory Service goaop.aspect.kernel
Factory Method getContainer
$ console debug:container goaop.aspect.kernel
Information for Service "goaop.aspect.kernel"
Option Value
Service ID goaop.aspect.kernel
Class Go\Symfony\GoAopBundle\Kernel\AspectSymfonyKernel
Tags -
Calls init
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
Factory Class Go\Symfony\GoAopBundle\Kernel\AspectSymfonyKernel
Factory Method getInstance
$ console app:shine -vv
[2018-02-16 14:19:48] app.INFO: Waking up the sun [] []
How I can remove SelfValueTransformer?
Actualy we can't use AOP's proxies classe if parents has private constanst used inside generated class via:
ClassName::CONST constuction.
for what ? :)
Proxied class also have copy of all constans equal parent class.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.