{"id":20338258,"url":"https://github.com/openclassrooms/serviceproxy","last_synced_at":"2025-10-26T06:36:32.954Z","repository":{"id":1770915,"uuid":"41264660","full_name":"OpenClassrooms/ServiceProxy","owner":"OpenClassrooms","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-12T13:48:38.000Z","size":477,"stargazers_count":0,"open_issues_count":4,"forks_count":2,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-11T23:11:30.069Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenClassrooms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-23T19:52:21.000Z","updated_at":"2025-03-12T13:47:30.000Z","dependencies_parsed_at":"2023-07-06T07:47:56.341Z","dependency_job_id":"fe829a58-41be-4613-bd55-0770d7e0a9b7","html_url":"https://github.com/OpenClassrooms/ServiceProxy","commit_stats":{"total_commits":69,"total_committers":9,"mean_commits":7.666666666666667,"dds":0.536231884057971,"last_synced_commit":"87118c3d592510829b4bcfc4d32b19be09592f8b"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FServiceProxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FServiceProxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FServiceProxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FServiceProxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenClassrooms","download_url":"https://codeload.github.com/OpenClassrooms/ServiceProxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248492877,"owners_count":21113163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T21:12:11.937Z","updated_at":"2025-10-26T06:36:27.936Z","avatar_url":"https://github.com/OpenClassrooms.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Service Proxy\n[![Build Status](https://travis-ci.org/OpenClassrooms/ServiceProxy.svg?branch=master)](https://travis-ci.org/OpenClassrooms/ServiceProxy)\n[![SensioLabsInsight](https://insight.sensiolabs.com/projects/e0840e44-8f14-4620-96cf-76300727e808/mini.png)](https://insight.sensiolabs.com/projects/e0840e44-8f14-4620-96cf-76300727e808)\n![PHPStan](https://img.shields.io/badge/PHPStan-level%207-brightgreen.svg?style=flat)\n![PHP](https://img.shields.io/badge/PHP-%3E=%207.4-brightgreen.svg?style=flat)\n![Coverage](../coverage/coverage.svg?raw=true)\n\nService Proxy is a library that provides functionality to manage technical code over a class:\n- Transactional context\n- Security access\n- Cache management\n- Events\n- Logs (not implemented yet)\n\n## Installation\nThe easiest way to install ServiceProxy is via [composer](http://getcomposer.org/).\n\nCreate the following `composer.json` file and run the `php composer.phar install` command to install it.\n\n```json\n{\n    \"require\": {\n        \"openclassrooms/service-proxy\": \"*\"\n    }\n}\n```\n```php\n\u003c?php\nrequire 'vendor/autoload.php';\n\nuse OpenClassrooms\\ServiceProxy\\ServiceProxy;\n\n//do things\n```\n\n## Concepts\n\n### Interceptors\n\nInterceptors are used as decorators to react to the method execution. \nfor example using `@Cache` annotation, is a condition to enable the cache interceptor.\n\nThere is two types of interceptors:\n#### Prefix interceptors :\nInterceptors that are called before the method execution, they must implement `OpenClassrooms\\ServiceProxy\\Interceptor\\Contract\\PrefixInterceptor`\nThree methods are called:\n- `prefix` : called before the method execution. Should return instance of `OpenClassrooms\\ServiceProxy\\Interceptor\\Response\\Response`.\n- `supportsPrefix` : called to know if the interceptor should be called, for example in the case of the cache interceptor, it will check that the method has the `@Cache` annotation.\n- `getPrefixPriority` : called to know the priority of the interceptor, the higher the priority, the earlier the interceptor will be called.\n\n#### Suffix interceptors :\nInterceptors that are called after the method execution, even if an exception is thrown, they must implement `OpenClassrooms\\ServiceProxy\\Interceptor\\Contract\\SuffixInterceptor`\nThree methods are called:\n- `suffix` : called after the method execution even if an exception is thrown. should return instance of `OpenClassrooms\\ServiceProxy\\Interceptor\\Response\\Response`.\n- `supportsSuffix` : called to know if the interceptor should be called, for example in the case of the cache\n  interceptor, it will check that the method has the `@Cache` annotation.\n- `getSuffixPriority` : called to know the priority of the interceptor, the higher the priority, the earlier the interceptor will be called.\n\n#### Handling exceptions\nIf you want to react to an exception thrown by the method, you can check for the exception in the suffix interceptor.\n- To check `$instance-\u003emethod()-\u003ethrewException()`\n- To get the exception (null if no exception was thrown) `$instance-\u003emethod()-\u003egetException()`\n- To get the return value (null in case of an exception) `$instance-\u003emethod()-\u003egetReturnValue()`\n\n#### Early return\n- If a prefix interceptor returns a response with early return parameter set to `true` ex: `Response($data, true)`, the method won't be executed and the suffix interceptors won't be called.\n- If a suffix interceptor returns a response with early return parameter set to `true`, the exception won't be thrown, in the case of a method that throws an exception.\n\nYou can create your own interceptors, or use the built-in ones:\n\n### Handlers\n\nHandlers are used by interceptors to manage the infrastructure code.\nTo be able to use built-in interceptors, you need to implement the built-in handlers contracts.\n\n- All handles need to implement `OpenClassrooms\\ServiceProxy\\Handler\\Contract\\AnnotationHandler`.\n- Each handler must have a unique name, you can use the `getName` method to return it.\n- Each handler must return true if it's the default handler or false if not, you can use the `isDefault` method to return it.\n- You can't have two handlers with the same name by annotation.\n- You can have only one default handler, by annotation.\n- If you have only one handler by annotation, it will be the default one.\n\n**example:**\n\n```php\nuse OpenClassrooms\\ServiceProxy\\Annotation\\Cache;\n\n/**\n * @Cache(handler=\"in_memory\")\n * to select the in_memory handler\n */\n\n ```\n\n## Usage\n### Instantiation\n\n#### Symfony\nCheck out the [ServiceProxyBundle](http://github.com/openclassrooms/ServiceProxyBundle).\nThe bundle provides an easy configuration option for this library.\n\n#### Manual\n##### Example\nFirst implement the handlers\n\n```php\nuse OpenClassrooms\\ServiceProxy\\Handler\\Contract\\CacheHandler;\n\nclass InMemoryCacheHandler implements CacheHandler\n{\n    public function getName(): string\n    {\n        return 'in_memory';\n    }\n    ...\n}\n\nclass RedisCacheHandler implements CacheHandler\n{\n    public function getName(): string\n    {\n        return 'redis';\n    }\n    ...\n}\n```\n\nThen you can inject the handlers into the interceptors:\n\n```php\n$cacheInterceptor = new CacheInterceptor([new ArrayCacheHandler(), new RedisCacheHandler()]);\n$prefixInterceptors = [\n    $cacheInterceptor,\n    new EventInterceptor([/* event handlers */]),\n    new TransactionInterceptor([/* transaction handlers */]),\n    new SecurityInterceptor([/* security handlers */]),\n];\n\n$suffixInterceptors = [\n    $cacheInterceptor,\n    new EventInterceptor(),\n    new TransactionInterceptor(),\n];\n\n$serviceProxyFactory = new ProxyFactory(\n    new Configuration(), //if no proxies directory is provided, the system tmp dir is used\n    $prefixInterceptors,\n    $SecurityInterceptor,\n);\n$proxy = $serviceProxyFactory-\u003ecreateProxy(new Class());\n```\n\n#### Built-in interceptors\n\n- [Cache](docs/Interceptor/cache.md)\n- [Event](docs/Interceptor/event.md)\n- [Security](docs/Interceptor/security.md)\n- [Transaction](docs/Interceptor/transaction.md)\n\n## Acknowledgments  \nThis library is based on [Ocramius\\ProxyManager](https://github.com/Ocramius/ProxyManager).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclassrooms%2Fserviceproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenclassrooms%2Fserviceproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclassrooms%2Fserviceproxy/lists"}